From 0786fc0d3d0a8f6af7bf8be7a04975d13498975b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Tarot?= Date: Thu, 6 Oct 2022 10:00:43 +0200 Subject: [PATCH] docs: split and include languages style guides --- docs/po4a.cfg | 4 + docs/src/code/style-asciidoc.adoc | 297 ++++++++++++++ docs/src/code/style-c-cpp.adoc | 321 +++++++++++++++ docs/src/code/style-comp.adoc | 16 + docs/src/code/style-guide.adoc | 649 ++---------------------------- docs/src/code/style-python.adoc | 12 + 6 files changed, 679 insertions(+), 620 deletions(-) create mode 100644 docs/src/code/style-asciidoc.adoc create mode 100644 docs/src/code/style-c-cpp.adoc create mode 100644 docs/src/code/style-comp.adoc create mode 100644 docs/src/code/style-python.adoc diff --git a/docs/po4a.cfg b/docs/po4a.cfg index f7f96e56074..687176b6060 100644 --- a/docs/po4a.cfg +++ b/docs/po4a.cfg @@ -27,6 +27,10 @@ [type: AsciiDoc_def] src/code/nml-messages.adoc $lang:src/$lang/code/nml-messages.adoc [type: AsciiDoc_def] src/code/rs274.adoc $lang:src/$lang/code/rs274.adoc [type: AsciiDoc_def] src/code/style-guide.adoc $lang:src/$lang/code/style-guide.adoc +[type: AsciiDoc_def] src/code/style-c-cpp.adoc $lang:src/$lang/code/style-c-cpp.adoc +[type: AsciiDoc_def] src/code/style-comp.adoc $lang:src/$lang/code/style-comp.adoc +[type: AsciiDoc_def] src/code/style-python.adoc $lang:src/$lang/code/style-python.adoc +[type: AsciiDoc_def] src/code/style-asciidoc.adoc $lang:src/$lang/code/style-asciidoc.adoc [type: AsciiDoc_def] src/code/translation.adoc $lang:src/$lang/code/translation.adoc [type: AsciiDoc_def] src/common/emc-history.adoc $lang:src/$lang/common/emc-history.adoc [type: AsciiDoc_def] src/common/glossary.adoc $lang:src/$lang/common/glossary.adoc diff --git a/docs/src/code/style-asciidoc.adoc b/docs/src/code/style-asciidoc.adoc new file mode 100644 index 00000000000..50e092a3811 --- /dev/null +++ b/docs/src/code/style-asciidoc.adoc @@ -0,0 +1,297 @@ +:lang: en +:toc: + += AsciiDoc Coding Standards + +This is a very recent (09/2022) part of this document. Please help shaping +it if you are familiar with asciidoc. + +// After looking at the website, and maybe watching the one or other YouTube Video, the +// LinuxCNC documentation is likely the first point of contact for any new +// user. The talent to get the documentation right is mostly disjunct from +// computationally orchestrating all the moving parts of a mill or lathe, +// though. Still, we need this to shine if we want LinuxCNC to shine and +// for a transfer of our knowledge for the next generation - this seems +// fair to say for a project that was started in the last millennium and few +// individuals buying their own mills/lathes before their hair turns gray. + +// not really related to the style guide IMHO +// == Overall structure of documentation + +// There are two basic documents, i.e. the +// * Users' Guide and the +// * Developers' Guide + +// All documents created belong to either of these "parental documents" +// and are included from the respective document, either directly or that +// included file includes it. + + +== Preamble, TOC, Anchors etc. + +Every file should start with a header. This is typically + +---- +:lang: en +---- + +and longer documents may also chose to set + +---- +:toc: +---- + +This should be followed by an anchor for that section or chapter that is +represented in that file like + +---- +[[cha:]] +---- + +// For a better consistency, and maintainability, the anchors need to be the same for all langages. +// If the page needs extras, e.g. for the syntax-highlighting, then such lines may then follow. + +//.Anchors for titles and other blocks + +If a chapter/section header shall be granted the option to be +referenced from another part of the documentation then it needs an anchor. +The anchor shall be a combination of an indicator of the kind +of block that is referenced (cha, sec, fig ,tab, ...) together with a +short name identifying the object. + + +// * index entries for titles and other blocks + +// ? + +== Heading/Title Capitalization + +The documentation prefers the "Title Case Capitalization". It is defined by several associations. Here the definition by the APA: + +.Title Case Capitalization +[quote, APA, 'link:https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case[]'] +____ + +In title case, major words are capitalized, and most minor words are lowercase. [...] + +- *major words*: Nouns, verbs (including linking verbs), adjectives, adverbs, pronouns, and all words of four letters or more are considered major words. +- *minor words*: Short (i.e., three letters or fewer) conjunctions, short prepositions, and all articles are considered minor words. + +____ + +// === Lists + +// I think we should not define whether we should have a dot at the end of list items or not + +== Sections and Subsections + +The depth of sections shall not exceed 3 levels. If more structure is needed, +subheadings can be inserted like this: +---- += Chapter +== Section +=== Subsection +.Subheading +---- +While "Chapter" corresponds to the document's title. + + + +== Usage of Italic and Monospace Font + +Highlighting of special elements like component names, pin names etc. shall be italic. +Short code snippets shall be in monospaecd font. +Headings shall not be formatted either itlaic nor monospaced. + +.Example +==== +---- +If you are using _component_a_ you have to set the use `parameter_x = 500.0`. +---- + +If you are using _component_a_ you have to set the use `parameter_x = 500.0`. + +If you have direction control of your spindle, then the HAL pins _spindle.N.forward_ and _spindle.N.reverse_ are controlled by the G-codes _M3_ and _M4_. +==== + + +== Values and Units + +Between a value and its unit shall be always a space, preferably a thin space (U+2009). + +To enter Unicode characters in most graphical editors, + +1. press and hold the Left Ctrl and Shift keys and hit the u key and then +2. type the Unicode code with Ctrl + Shift still pressed. + +In VIM, press Ctrl + v and then enter the Unicode code with prefixed "u". + + +== Code Blocks + +Asciidoc supports syntax highlighting for several languages. +The most common used in LinuxCNC are: _c, python, sh, tcl, xml_. + +They are used like this: +---- + [source,c] + ---- + // some code + ---- +---- +It also exists some LinuxCNC-specific syntax highlighting +for _hal, ini, ngc_. + +To use those, following lines need to be inserted: +---- +// these attributes must come after the document title, to work around a bug in asciidoc 8.6.6 +:ini: {basebackend@docbook:'':ini} +:hal: {basebackend@docbook:'':hal} +:ngc: {basebackend@docbook:'':ngc} +---- + +The keywords for those need to be surrounded by curly braces: +---- + [source,{ini}] + ---- + // some code + ---- +---- + + +== Pin Listings + +.Compact Form + +---- +* **comp.group.**_N_**.pin** '(type, direction)' - Functional description +---- + +Example: +==== +* **halui.joint.**_N_**.select** '(bit, in)' - Pin for selecting joint N +* **halui.joint.**_N_**.is-selected** '(bit, out)' - Status pin that joint N is selected +* **halui.joint.**_N_**.has-fault** '(bit, out)' - Status pin telling that joint N has a fault +==== +Where _N_ is the instance number of the component. If it's a component/module that can only be loaded once, a zero could/should replace _N_. + +.Indented Form with Line Break +---- +* **comp.group.**_N_**.pin** '(type, direction)':: Functional description +---- + +Example: +==== +**pid.**_N_**.Pgain** '(float, in)':: Proportional gain. Results in a contribution to the output that is the error multiplied by Pgain. + +**pid.**_N_**.Igain** '(float, in)':: Integral gain. Results in a contribution to the output that is the integral of the error multiplied by Igain. For example an error of 0.02 that lasted 10 seconds would result in an integrated error (`errorI`) of 0.2, and if Igain is 20, the integral term would add 4.0 to the output. + +**pid.**_N_**.Dgain** '(float, in)':: Derivative gain. Results in a contribution to the output that is the rate of change (derivative) of the error multiplied by Dgain. For example an error that changed from 0.02 to 0.03 over 0.2 seconds would result in an error derivative (errorD) of of 0.05, and if Dgain is 5, the derivative term would add 0.25 to the output. +==== + +== Listings of Commands/Messages + +.Panelui +==== +.*home_selected* +* required argument: axis number (int) + +.*unhome_selected* +* required argument: axis number (int) + +.*override_limits* + +.*spindle_forward_adjust* +* optional argument: starting RPM (int) - default 100 +* Description: If the spindle is stopped it will start in the forward direction. + If it is already running it will increase or decrease the rpm depending on + what direction the spindle is running in. + +.*spindle_forward* +* optional argument: starting RPM (int) - default 100 + +==== + + +.GStat +==== +*motion-mode-changed* :: '(returns integer)' - +Sent when motion's mode has changed + +*spindle-control-changed* :: '(returns integer, bool, integer, bool)' - +(spindle num, spindle on state, requested spindle direction & rate, at-speed state) + +Sent when spindle direction or running status changes or at-speed changes. + +*current-feed-rate* :: '(returns float)' - +Sent when the current feed rate changes. + +*current-x-rel-position* :: '(returns float)' - +Sent every 100ms. + +*current-position* :: '(returns pyobject, pyobject, pyobject, pyobject)' - +Sent every 100ms. + +returns tuples of position, relative position, distance-to-go and + +the joint actual position. Before homing, on multi-joint axes, only joint + +position is valid. +==== + +// === ?? +// * usage of lists vs titles + +// ? + +// * use of bold and italic +// * structure/page splitting guidance +// - avoid 2k+ char long lines + + +== Images + +- Shall be centered +- Shall have a caption if not embedded in the text +---- +.Caption +image::image.png["Description",align="center"] +---- + + +== Table Formatting (to be filled by smoe 😉) +Tables can be presented with a series of options. + +- header + +With the header-option set, the fist line will be interpreted accordingly. + +- column width + +in ideal column, the column is constituted only by its data. No +vertical separators should be required. The horizontal alignment will +also not be required since the writing itself is horizontal enough. ++ +If individual fields have too much text then a line-break within that +field should be provoked. + +- what lines are visible + +As motivated above, there should be no grid lines. +The top and bottom lines should separate the table from the surrounding text. +Another line could be motivated between the header and the main body. + +- captions + +Asciidoc makes it difficult to nicely prepare captions. At the same time, +captions are the only bit of the whole document that even with the first flick +through the document will not escape the reader's attention. + +- spaces between ? for po4a + +---- +Instruction needs to be added +---- + + +== ? +- reference +* figure formatting (captions) + - reference + - caption + ---- + Instruction needs to be added + ---- +* footnotes +* comments +* interaction with other media like videos + +// vim: set syntax=asciidoc: diff --git a/docs/src/code/style-c-cpp.adoc b/docs/src/code/style-c-cpp.adoc new file mode 100644 index 00000000000..e00b796214b --- /dev/null +++ b/docs/src/code/style-c-cpp.adoc @@ -0,0 +1,321 @@ +:lang: en +:toc: + += C/C++ Coding Standards + +Most of this style guide has been copied wholesale from the Linux kernel +documents - See linux/Documentation/CodingStyle for the full text. +The C++ recommendations have been drawn from various sources such as the +GTK headers, "C++ The Complete Reference" by Schildt, and IRC discussions. + +== Tab Stops + +A tab stop always corresponds to 8 spaces. Do not write code that +displays correctly only with a differing tab stop setting. + +== Indentation + +Use 4 spaces per level of indentation. Combining 8 spaces into one tab +is acceptable but not required. + +Rationale: The whole idea behind indentation is to clearly define where +a block of control starts and ends. Especially when you've been looking +at your screen for 20 straight hours, you'll find it a lot easier to see +how the indentation works if you have large indentations. + +Now, some people will claim that having 8-character indentations makes +the code move too far to the right, and makes it hard to read on a +80-character terminal screen. Whilst the GNU style of 2-character +indentations reduces the clarity. For EMC2, a compromise of 4-character +indentation has been chosen. This still spreads the code out and causes +lines to wrap round leading to difficulties in reading the sources. The +answer to that is that if you need more than 3 levels of indentation, you're +screwed anyway, and should fix your program. + +== Placing Braces + +The other issue that always comes up in C styling is the placement of +braces. Unlike the indent size, there are few technical reasons to +choose one placement strategy over the other, but the preferred way, as +shown to us by the prophets Kernighan and Ritchie, is to put the opening +brace last on the line, and put the closing brace first, thusly: + +[source,c] +---- +if (x is true) { + we do y +} +---- + +However, there is one special case, namely functions: they have the +opening brace at the beginning of the next line, thus: + +[source,c] +---- +int function(int x) +{ + body of function +} +---- + +Note that the closing brace is empty on a line of its own, _except_ in +the cases where it is followed by a continuation of the same statement, +i.e. a "while" in a do-statement or an "else" in an if-statement, like +this: + +[source,c] +---- +do { + body of do-loop +} while (condition); +---- + +and + +[source,c] +---- +if (x == y) { + .. +} else if (x > y) { + ... +} else { + .... +} +---- +Also, note that this brace-placement also minimizes the number of empty +(or almost empty) lines, without any loss of readability. Thus, as the +supply of new-lines on your screen is not a renewable resource (think +25-line terminal screens here), you have more empty lines to put +comments on. + +== Naming + +C is a Spartan language, and so should your naming be. Unlike Modula-2 +and Pascal programmers, C programmers do not use cute names like +ThisVariableIsATemporaryCounter. A C programmer would call that +variable 'tmp', which is much easier to write, and not the least more +difficult to understand. + +However, descriptive names for global variables are a must. To call a +global function 'foo' is a shooting offense. + +GLOBAL variables (to be used only if you *really* need them) need to +have descriptive names, as do global functions. If +you have a function that counts the number of active users, you should + call that 'count_active_users()' or similar, you should *not* call it +'cntusr()'. + +Encoding the type of a function into the name (so-called Hungarian +notation) is brain damaged - the compiler knows the types anyway and +can check those, and it only confuses the programmer. No wonder +Microsoft makes buggy programs. + +LOCAL variable names should be short, and to the point. If you have +some random integer loop counter, it should probably be called 'i'. +Calling it 'loop_counter' is non-productive, if there is no chance of +it being misunderstood. Similarly, 'tmp' can be just about any type of +variable that is used to hold a temporary value. + +If you are afraid to mix up your local variable names, you have +another problem, which is called the function-growth-hormone-imbalance +syndrome. See next chapter. + +== Functions + +Functions should be short and sweet, and do just one thing. They +should fit on one or two screenfuls of text (the ISO/ANSI screen size +is 80x24, as we all know), and do one thing and do that well. + +The maximum length of a function is inversely proportional to the +complexity and indentation level of that function. So, if you have a +conceptually simple function that is just one long (but simple) +case-statement, where you have to do lots of small things for a lot of +different cases, it's OK to have a longer function. + +However, if you have a complex function, and you suspect that a +less-than-gifted first-year high-school student might not even +understand what the function is all about, you should adhere to the +maximum limits all the more closely. Use helper functions with +descriptive names (you can ask the compiler to in-line them if you +think it's performance-critical, and it will probably do a better job +of it that you would have done). + +Another measure of the function is the number of local variables. They +shouldn't exceed 5-10, or you're doing something wrong. Re-think the +function, and split it into smaller pieces. A human brain can generally +easily keep track of about 7 different things, anything more and it +gets confused. You know you're brilliant, but maybe you'd like to +understand what you did 2 weeks from now. + +== Commenting + +Comments are good, but there is also a danger of over-commenting. +NEVER try to explain HOW your code works in a comment: it's much better +to write the code so that the *working* is obvious, and it's a waste of +time to explain badly written code. + +Generally, you want your comments to tell WHAT your code does, not +HOW. A boxed comment describing the function, return value, and who +calls it placed above the body is good. Also, try to avoid putting +comments inside a function body: if the function is so complex that you +need to separately comment parts of it, you should probably re-read the +Functions section again. You can make small comments to note or warn +about something particularly clever (or ugly), but try to avoid excess. +Instead, put the comments at the head of the function, telling people +what it does, and possibly WHY it does it. + +If comments along the lines of /* Fix me */ are used, please, please, +say why something needs fixing. When a change has been made to the +affected portion of code, either remove the comment, or amend it to +indicate a change has been made and needs testing. + +== Shell Scripts & Makefiles + +Not everyone has the same tools and packages installed. Some people +use vi, others emacs - A few even avoid having either package +installed, preferring a lightweight text editor such as nano or the one +built in to Midnight Commander. + +gawk versus mawk - Again, not everyone will have gawk installed, mawk +is nearly a tenth of the size and yet conforms to the POSIX AWK +standard. If some obscure gawk specific command is needed that mawk +does not provide, than the script will break for some users. The same +would apply to mawk. In short, use the generic awk invocation in +preference to gawk or mawk. + +== C++ Conventions + +C++ coding styles are always likely to end up in heated debates (a bit +like the emacs versus vi arguments). One thing is certain however, a +common style used by everyone working on a project leads to uniform and +readable code. + +Naming conventions: Constants either from #defines or enumerations +should be in upper case through out. Rationale: Makes it easier to spot +compile time constants in the source code, e.g., EMC_MESSAGE_TYPE. + +Classes and Namespaces should capitalize the first letter of each word +and avoid underscores. Rationale: Identifies classes, constructors and +destructors, e.g., GtkWidget. + +Methods (or function names) should follow the C recommendations above +and should not include the class name. Rationale: Maintains a common +style across C and C++ sources, e.g., get_foo_bar(). + +However, boolean methods are easier to read if they avoid underscores +and use an 'is' prefix (not to be confused with methods that manipulate +a boolean). Rationale: Identifies the return value as TRUE or FALSE and +nothing else, e.g., isOpen, isHomed. + +Do NOT use 'Not' in a boolean name, it leads only leads to confusion +when doing logical tests, e.g., isNotOnLimit or is_not_on_limit are BAD. + +Variable names should avoid the use of upper case and underscores +except for local or private names. The use of global variables should +be avoided as much as possible. Rationale: Clarifies which are +variables and which are methods. Public: e.g., axislimit Private: e.g., +maxvelocity_ . + +.Specific method naming conventions + +The terms get and set should be used where an attribute is accessed +directly. Rationale: Indicates the purpose of the function or method, +e.g., get_foo set_bar. + +For methods involving boolean attributes, set & reset is preferred. +Rationale: As above. e.g. set_amp_enable reset_amp_fault + +Math intensive methods should use compute as a prefix. Rationale: +Shows that it is computationally intensive and will hog the CPU. e.g. +compute_PID + +Abbreviations in names should be avoided where possible - The +exception is for local variable names. Rationale: Clarity of code. e.g. +pointer is preferred over ptr compute is preferred over cmp compare is +again preferred over cmp. + +Enumerates and other constants can be prefixed by a common type name, +e.g., `enum COLOR { COLOR_RED, COLOR_BLUE };` . + +Excessive use of macros and defines should be avoided - Using simple +methods or functions is preferred. Rationale: Improves the debugging +process. + +Include Statements Header files must be included at the top of a +source file and not scattered throughout the body. They should be +sorted and grouped by their hierarchical position within the system +with the low level files included first. Include file paths should +NEVER be absolute - Use the compiler -I flag instead to extend the search +path. Rationale: Headers may not be in the same place on all systems. + +Pointers and references should have their reference symbol next to the +variable name rather than the type name. Rationale: Reduces confusion, +e.g., `float *x` or `int &i`. + +Implicit tests for zero should not be used except for boolean +variables, e.g., `if (spindle_speed != 0)` NOT `if (spindle_speed)`. + +Only loop control statements must be included in a for() construct, +e.g. + +[source,c] +---- +sum = 0; +for (i = 0; i < 10; i++) { + sum += value[i]; +} +---- + +NOT: + +[source,c] +---- +for (i = 0, sum = 0; i < 10; i++) { + sum += value[i]; +} +---- + +Likewise, executable statements in conditionals must be avoided, e.g., +`if (fd = open(file_name))` is bad. + +Complex conditional statements should be avoided - Introduce temporary +boolean variables instead. + +The form `while(true)`` should be used for infinite loops. +e.g. + +[source,c] +---- +while (true) { + ...; +} +---- + +NOT + +[source,c] +---- +for (;;) { + ...; +} +---- + +or + +[source,c] +---- +while (1) { + ...; +} +---- + +Parentheses should be used in plenty in mathematical expressions - Do +not rely on operator precedence when an extra parentheses would clarify +things. + +File names: C++ sources and headers use .cc and .hh extension. The use +of .c and .h are reserved for plain C. Headers are for class, method, +and structure declarations, not code (unless the functions are declared +inline). + +// vim: set syntax=asciidoc: diff --git a/docs/src/code/style-comp.adoc b/docs/src/code/style-comp.adoc new file mode 100644 index 00000000000..d5d8055044a --- /dev/null +++ b/docs/src/code/style-comp.adoc @@ -0,0 +1,16 @@ +:lang: en +:toc: + += Comp Coding Standards + +// FIXME "Comp" "HAL Comp" "Component" "HAL Component" ? + +In the declaration portion of a .comp file, begin each declaration at +the first column. Insert extra blank lines when they help group related +items. + +In the code portion of a .comp file, follow normal C coding style. + +// TODO Complete at least with commented example ! + +// vim: set syntax=asciidoc: diff --git a/docs/src/code/style-guide.adoc b/docs/src/code/style-guide.adoc index 096c90e32ee..cb45b9203f0 100644 --- a/docs/src/code/style-guide.adoc +++ b/docs/src/code/style-guide.adoc @@ -5,639 +5,48 @@ == General comments -LinuxCNC is developed in C/C++, Python, BASH and Tcl/Tk. -Documentation is written in asciidoc, which includes the -UNIX man pages written in Groff. +LinuxCNC _components and applications_ developed in *C/C++*, *Python*, *BASH* +and *Tcl/Tk*. -These programming languages are not completely independent from each other. -So do the scripting languages extend the LinuxCNC core written in C/C++ for easier adaption of user interfaces. +_Documentation_ is written in *AsciiDoc*, and the UNIX _man pages_ are written +in *Groff*. -Every programming language has its very own syntax and customs to be structured, -and many flavours with every developer being very opinionated about -their very own being the best. And while the exact style does not matter -too much, it is important for the eye to see the source code formatted -consistently. +These programming languages are not completely independent from each other: +the scripting languages extend the LinuxCNC C/C++ core for easier adaption +of user interfaces. -This chapter hence describes the source code style preferred by the -LinuxCNC team. This shall improve the readability of source code and documentation and shall avoid -intensive discussions (aka bike-shedding) about how to style it best. +Every programming language has its very own syntax and structure standards +and customs, and as many flavours as opinionated developers about their +very own being the best. And while the exact style does not matter too much, +it is important for the eye to see the source code formatted consistently. +These chapters hence describe the source code style preferred by the LinuxCNC +team. This shall improve the readability of source code and documentation +and shall avoid intensive discussions (aka bike-shedding) about how to style +it best. -=== Do no Harm -When making small edits to code in a style different than the one -described below, observe the local coding style. Rapid changes from one -coding style to another decrease code readability. +=== Do No Harm -Never check in code after running "indent" on it. The whitespace -changes introduced by indent make it more difficult to follow the -revision history of the file. +When making small edits to code in a style different than the one described +below, _observe the local coding style_. Rapid changes from one coding style +to another decrease code readability. -Do not use an editor that makes unneeded changes to whitespace (e.g., -which replaces 8 spaces with a tabstop on a line not otherwise -modified, or word-wraps lines not otherwise modified). +Never check in code after running "indent" on it. The whitespace changes +introduced by indent make it more difficult to follow the revision history +of the file. +Do not use an editor that makes unneeded changes to whitespace (e.g., which +replaces 8 spaces with a tabstop on a line not otherwise modified, or word-wraps +lines not otherwise modified). -== C/C++ coding standards -Most of this style guide has been copied wholesale from the Linux kernel -documents - See linux/Documentation/CodingStyle for the full text. -The C++ recommendations have been drawn from various sources such as the -GTK headers, "C++ The Complete Reference" by Schildt, and IRC discussions. +include::style-c-cpp.adoc[leveloffset=+1] -=== Tab Stops +include::style-comp.adoc[leveloffset=+1] -A tab stop always corresponds to 8 spaces. Do not write code that -displays correctly only with a differing tab stop setting. +include::style-python.adoc[leveloffset=+1] -=== Indentation - -Use 4 spaces per level of indentation. Combining 8 spaces into one tab -is acceptable but not required. - -Rationale: The whole idea behind indentation is to clearly define where -a block of control starts and ends. Especially when you've been looking -at your screen for 20 straight hours, you'll find it a lot easier to see -how the indentation works if you have large indentations. - -Now, some people will claim that having 8-character indentations makes -the code move too far to the right, and makes it hard to read on a -80-character terminal screen. Whilst the GNU style of 2-character -indentations reduces the clarity. For EMC2, a compromise of 4-character -indentation has been chosen. This still spreads the code out and causes -lines to wrap round leading to difficulties in reading the sources. The -answer to that is that if you need more than 3 levels of indentation, you're -screwed anyway, and should fix your program. - -=== Placing Braces - -The other issue that always comes up in C styling is the placement of -braces. Unlike the indent size, there are few technical reasons to -choose one placement strategy over the other, but the preferred way, as -shown to us by the prophets Kernighan and Ritchie, is to put the opening -brace last on the line, and put the closing brace first, thusly: -[source,c] ----- -if (x is true) { - we do y -} ----- -However, there is one special case, namely functions: they have the -opening brace at the beginning of the next line, thus: -[source,c] ----- -int function(int x) -{ - body of function -} ----- -Note that the closing brace is empty on a line of its own, _except_ in -the cases where it is followed by a continuation of the same statement, -i.e. a "while" in a do-statement or an "else" in an if-statement, like -this: -[source,c] ----- -do { - body of do-loop -} while (condition); ----- -and -[source,c] ----- -if (x == y) { - .. -} else if (x > y) { - ... -} else { - .... -} ----- -Also, note that this brace-placement also minimizes the number of empty -(or almost empty) lines, without any loss of readability. Thus, as the -supply of new-lines on your screen is not a renewable resource (think -25-line terminal screens here), you have more empty lines to put -comments on. - -=== Naming - -C is a Spartan language, and so should your naming be. Unlike Modula-2 -and Pascal programmers, C programmers do not use cute names like -ThisVariableIsATemporaryCounter. A C programmer would call that -variable 'tmp', which is much easier to write, and not the least more -difficult to understand. - -However, descriptive names for global variables are a must. To call a -global function 'foo' is a shooting offense. - -GLOBAL variables (to be used only if you *really* need them) need to -have descriptive names, as do global functions. If -you have a function that counts the number of active users, you should - call that 'count_active_users()' or similar, you should *not* call it -'cntusr()'. - -Encoding the type of a function into the name (so-called Hungarian -notation) is brain damaged - the compiler knows the types anyway and -can check those, and it only confuses the programmer. No wonder -Microsoft makes buggy programs. - -LOCAL variable names should be short, and to the point. If you have -some random integer loop counter, it should probably be called 'i'. -Calling it 'loop_counter' is non-productive, if there is no chance of -it being misunderstood. Similarly, 'tmp' can be just about any type of -variable that is used to hold a temporary value. - -If you are afraid to mix up your local variable names, you have -another problem, which is called the function-growth-hormone-imbalance -syndrome. See next chapter. - -=== Functions - -Functions should be short and sweet, and do just one thing. They -should fit on one or two screenfuls of text (the ISO/ANSI screen size -is 80x24, as we all know), and do one thing and do that well. - -The maximum length of a function is inversely proportional to the -complexity and indentation level of that function. So, if you have a -conceptually simple function that is just one long (but simple) -case-statement, where you have to do lots of small things for a lot of -different cases, it's OK to have a longer function. - -However, if you have a complex function, and you suspect that a -less-than-gifted first-year high-school student might not even -understand what the function is all about, you should adhere to the -maximum limits all the more closely. Use helper functions with -descriptive names (you can ask the compiler to in-line them if you -think it's performance-critical, and it will probably do a better job -of it that you would have done). - -Another measure of the function is the number of local variables. They -shouldn't exceed 5-10, or you're doing something wrong. Re-think the -function, and split it into smaller pieces. A human brain can generally -easily keep track of about 7 different things, anything more and it -gets confused. You know you're brilliant, but maybe you'd like to -understand what you did 2 weeks from now. - -=== Commenting - -Comments are good, but there is also a danger of over-commenting. -NEVER try to explain HOW your code works in a comment: it's much better -to write the code so that the *working* is obvious, and it's a waste of -time to explain badly written code. - -Generally, you want your comments to tell WHAT your code does, not -HOW. A boxed comment describing the function, return value, and who -calls it placed above the body is good. Also, try to avoid putting -comments inside a function body: if the function is so complex that you -need to separately comment parts of it, you should probably re-read the -Functions section again. You can make small comments to note or warn -about something particularly clever (or ugly), but try to avoid excess. -Instead, put the comments at the head of the function, telling people -what it does, and possibly WHY it does it. - -If comments along the lines of /* Fix me */ are used, please, please, -say why something needs fixing. When a change has been made to the -affected portion of code, either remove the comment, or amend it to -indicate a change has been made and needs testing. - -=== Shell Scripts & Makefiles - -Not everyone has the same tools and packages installed. Some people -use vi, others emacs - A few even avoid having either package -installed, preferring a lightweight text editor such as nano or the one -built in to Midnight Commander. - -gawk versus mawk - Again, not everyone will have gawk installed, mawk -is nearly a tenth of the size and yet conforms to the POSIX AWK -standard. If some obscure gawk specific command is needed that mawk -does not provide, than the script will break for some users. The same -would apply to mawk. In short, use the generic awk invocation in -preference to gawk or mawk. - -=== C++ Conventions - -C++ coding styles are always likely to end up in heated debates (a bit -like the emacs versus vi arguments). One thing is certain however, a -common style used by everyone working on a project leads to uniform and -readable code. - -Naming conventions: Constants either from #defines or enumerations -should be in upper case through out. Rationale: Makes it easier to spot -compile time constants in the source code, e.g., EMC_MESSAGE_TYPE. - -Classes and Namespaces should capitalize the first letter of each word -and avoid underscores. Rationale: Identifies classes, constructors and -destructors, e.g., GtkWidget. - -Methods (or function names) should follow the C recommendations above -and should not include the class name. Rationale: Maintains a common -style across C and C++ sources, e.g., get_foo_bar(). - -However, boolean methods are easier to read if they avoid underscores -and use an 'is' prefix (not to be confused with methods that manipulate -a boolean). Rationale: Identifies the return value as TRUE or FALSE and -nothing else, e.g., isOpen, isHomed. - -Do NOT use 'Not' in a boolean name, it leads only leads to confusion -when doing logical tests, e.g., isNotOnLimit or is_not_on_limit are BAD. - -Variable names should avoid the use of upper case and underscores -except for local or private names. The use of global variables should -be avoided as much as possible. Rationale: Clarifies which are -variables and which are methods. Public: e.g., axislimit Private: e.g., -maxvelocity_ . - -.Specific method naming conventions - -The terms get and set should be used where an attribute is accessed -directly. Rationale: Indicates the purpose of the function or method, -e.g., get_foo set_bar. - -For methods involving boolean attributes, set & reset is preferred. -Rationale: As above. e.g. set_amp_enable reset_amp_fault - -Math intensive methods should use compute as a prefix. Rationale: -Shows that it is computationally intensive and will hog the CPU. e.g. -compute_PID - -Abbreviations in names should be avoided where possible - The -exception is for local variable names. Rationale: Clarity of code. e.g. -pointer is preferred over ptr compute is preferred over cmp compare is -again preferred over cmp. - -Enumerates and other constants can be prefixed by a common type name, -e.g., `enum COLOR { COLOR_RED, COLOR_BLUE };` . - -Excessive use of macros and defines should be avoided - Using simple -methods or functions is preferred. Rationale: Improves the debugging -process. - -Include Statements Header files must be included at the top of a -source file and not scattered throughout the body. They should be -sorted and grouped by their hierarchical position within the system -with the low level files included first. Include file paths should -NEVER be absolute - Use the compiler -I flag instead to extend the search -path. Rationale: Headers may not be in the same place on all systems. - -Pointers and references should have their reference symbol next to the -variable name rather than the type name. Rationale: Reduces confusion, -e.g., `float *x` or `int &i`. - -Implicit tests for zero should not be used except for boolean -variables, e.g., `if (spindle_speed != 0)` NOT `if (spindle_speed)`. - -Only loop control statements must be included in a for() construct, -e.g. -[source,c] ----- -sum = 0; -for (i = 0; i < 10; i++) { - sum += value[i]; -} ----- -NOT: -[source,c] ----- -for (i = 0, sum = 0; i < 10; i++) { - sum += value[i]; -} ----- - -Likewise, executable statements in conditionals must be avoided, e.g., -`if (fd = open(file_name))` is bad. - -Complex conditional statements should be avoided - Introduce temporary -boolean variables instead. - -The form `while(true)`` should be used for infinite loops. - e.g. -[source,c] ----- -while (true) { - ...; -} ----- -NOT -[source,c] ----- -for (;;) { - ...; -} ----- -or -[source,c] ----- -while (1) { - ...; -} ----- - -Parentheses should be used in plenty in mathematical expressions - Do -not rely on operator precedence when an extra parentheses would clarify -things. - -File names: C++ sources and headers use .cc and .hh extension. The use -of .c and .h are reserved for plain C. Headers are for class, method, -and structure declarations, not code (unless the functions are declared -inline). - - -== Python Coding standards - -Use the http://www.python.org/dev/peps/pep-0008/[PEP 8] style for -Python code. - -== Comp Coding standards - -In the declaration portion of a .comp file, begin each declaration at -the first column. Insert extra blank lines when they help group related -items. - -In the code portion of a .comp file, follow normal C coding style. - -== Documentation Style - -This is a very recent (09/2022) part of this document. Please help shaping it if you are familiar with asciidoc. - -// After looking at the website, and maybe watching the one or other YouTube Video, the -// LinuxCNC documentation is likely the first point of contact for any new -// user. The talent to get the documentation right is mostly disjunct from -// computationally orchestrating all the moving parts of a mill or lathe, -// though. Still, we need this to shine if we want LinuxCNC to shine and -// for a transfer of our knowledge for the next generation - this seems -// fair to say for a project that was started in the last millenium and few -// individuals buying their own mills/lathes before their hair turns gray. - -// not really related to the style guide IMHO -// == Overall structure of documentation - -// There are two basic documents, i.e. the -// * Users' Guide and the -// * Developers' Guide - -// All documents created belong to either of these "parental documents" -// and are included from the respective document, either directly or that -// included file includes it. - - -=== Preamble, TOC, Anchors etc. - -Every file should start with a header. This is typically ----- -:lang: en ----- -and longer documents may also chose to set ----- -:toc: ----- -This should be followed by an anchor for that section or chapter that is -represented in that file like ----- -[[cha:]] ----- -// For a better consistency, and maintainability, the anchors need to be the same for all langages. -// If the page needs extras, e.g. for the syntax-highlighting, then such lines may then follow. - -// .Anchors for titles and other blocks - -If a chapter/section header shall be granted the option to be -referenced from another part of the documentation then it needs an anchor. -The anchor shall be a combination of an indicator of the kind -of block that is referenced (cha, sec, fig ,tab, ...) together with a -short name identifying the object. - - -// * index entries for titles and other blocks - -// ? - -=== Heading/Title Capitalization - -The documentation prefers the "Title Case Capitalization". It is defined by several associations. Here the definition by the APA: - -.Title Case Capitalization -[quote, APA, 'link:https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case[]'] -____ - -In title case, major words are capitalized, and most minor words are lowercase. [...] - -- *major words*: Nouns, verbs (including linking verbs), adjectives, adverbs, pronouns, and all words of four letters or more are considered major words. -- *minor words*: Short (i.e., three letters or fewer) conjunctions, short prepositions, and all articles are considered minor words. - -____ - -// === Lists - -// I think we should not define whether we should have a dot at the end of list items or not - -=== Sections and Subsections - -The depth of sections shall not exceed 3 levels. If more structure is needed, -subheadings can be inserted like this: ----- -= Chapter -== Section -=== Subsection -.Subheading ----- -While "Chapter" corresponds to the document's title. - - - -=== Usage of Italic and Monospace Font - -Highlighting of special elements like component names, pin names etc. shall be italic. -Short code snippets shall be in monospaecd font. -Headings shall not be formatted either itlaic nor monospaced. - -.Example -==== ----- -If you are using _component_a_ you have to set the use `parameter_x = 500.0`. ----- - -If you are using _component_a_ you have to set the use `parameter_x = 500.0`. - -If you have direction control of your spindle, then the HAL pins _spindle.N.forward_ and _spindle.N.reverse_ are controlled by the G-codes _M3_ and _M4_. -==== - - -=== Values and Units - -Between a value and its unit shall be always a space, preferably a thin space (U+2009). + -To enter Unicode characters in most graphical editors, - -1. press and hold the Left Ctrl and Shift keys and hit the u key and then -2. type the Unicode code with Ctrl + Shift still pressed. - -In VIM, press Ctrl + v and then enter the Unicode code with prefixed "u". - - -=== Code Blocks - -Asciidoc supports syntax highlighting for several languages. -The most common used in LinuxCNC are: _c, python, sh, tcl, xml_. + -They are used like this: ----- - [source,c] - ---- - // some code - ---- ----- -It also exists some LinuxCNC-specific syntax highlighting -for _hal, ini, ngc_. + -To use those, following lines need to be inserted: ----- -// these attributes must come after the document title, to work around a bug in asciidoc 8.6.6 -:ini: {basebackend@docbook:'':ini} -:hal: {basebackend@docbook:'':hal} -:ngc: {basebackend@docbook:'':ngc} ----- - -The keywords for those need to be surrounded by curly braces: ----- - [source,{ini}] - ---- - // some code - ---- ----- - - - -=== Pin Listings - -.Compact Form - ----- -* **comp.group.**_N_**.pin** '(type, direction)' - Functional description ----- - -Example: -==== -* **halui.joint.**_N_**.select** '(bit, in)' - Pin for selecting joint N -* **halui.joint.**_N_**.is-selected** '(bit, out)' - Status pin that joint N is selected -* **halui.joint.**_N_**.has-fault** '(bit, out)' - Status pin telling that joint N has a fault -==== -Where _N_ is the instance number of the component. If it's a component/module that can only be loaded once, a zero could/should replace _N_. - -.Indented Form with Line Break ----- -* **comp.group.**_N_**.pin** '(type, direction)':: Functional description ----- - -Example: -==== -**pid.**_N_**.Pgain** '(float, in)':: Proportional gain. Results in a contribution to the output that is the error multiplied by Pgain. - -**pid.**_N_**.Igain** '(float, in)':: Integral gain. Results in a contribution to the output that is the integral of the error multiplied by Igain. For example an error of 0.02 that lasted 10 seconds would result in an integrated error (`errorI`) of 0.2, and if Igain is 20, the integral term would add 4.0 to the output. - -**pid.**_N_**.Dgain** '(float, in)':: Derivative gain. Results in a contribution to the output that is the rate of change (derivative) of the error multiplied by Dgain. For example an error that changed from 0.02 to 0.03 over 0.2 seconds would result in an error derivative (errorD) of of 0.05, and if Dgain is 5, the derivative term would add 0.25 to the output. -==== - -=== Listings of Commands/Messages - -.Panelui -==== -.*home_selected* -* required argument: axis number (int) - -.*unhome_selected* -* required argument: axis number (int) - -.*override_limits* - -.*spindle_forward_adjust* -* optional argument: starting RPM (int) - default 100 -* Description: If the spindle is stopped it will start in the forward direction. - If it is already running it will increase or decrease the rpm depending on - what direction the spindle is running in. - -.*spindle_forward* -* optional argument: starting RPM (int) - default 100 - -==== - - -.GStat -==== -*motion-mode-changed* :: '(returns integer)' - -Sent when motion's mode has changed - -*spindle-control-changed* :: '(returns integer, bool, integer, bool)' - -(spindle num, spindle on state, requested spindle direction & rate, at-speed state) + -Sent when spindle direction or running status changes or at-speed changes. - -*current-feed-rate* :: '(returns float)' - -Sent when the current feed rate changes. - -*current-x-rel-position* :: '(returns float)' - -Sent every 100ms. - -*current-position* :: '(returns pyobject, pyobject, pyobject, pyobject)' - -Sent every 100ms. + -returns tuples of position, relative position, distance-to-go and + -the joint actual position. Before homing, on multi-joint axes, only joint + -position is valid. -==== - - - -// === ?? -// * usage of lists vs titles + -// ? - -// * use of bold and italic -// * structure/page splitting guidance -// - avoid 2k+ char long lines - -=== Images - -- Shall be centered -- Shall have a caption if not embedded in the text ----- -.Caption -image::image.png["Description",align="center"] ----- - -=== Table Formatting (to be filled by smoe 😉) -Tables can be presented with a series of options. - -- header + -With the header-option set, the fist line will be interpreted accordingly. - -- column width + -in ideal column, the column is constituted only by its data. No -vertical separators should be required. The horizontal alignment will -also not be required since the writing itself is horizontal enough. -+ -If individual fields have too much text then a line-break within that -field should be provoked. - -- what lines are visible + -As motivated above, there should be no grid lines. -The top and bottom lines should separate the table from the surrounding text. -Another line could be motivated between the header and the main body. - -- captions + -Asciidoc makes it difficult to nicely prepare captions. At the same time, -captions are the only bit of the whole document that even with the first flick -through the document will not escape the reader's attention. - -- spaces between ? for po4a - ----- -Instruction needs to be added ----- - -=== ? -- reference -* figure formatting (captions) - - reference - - caption - ---- - Instruction needs to be added - ---- -* footnotes -* comments -* interaction with other media like videos +include::style-asciidoc.adoc[leveloffset=+1] // vim: set syntax=asciidoc: diff --git a/docs/src/code/style-python.adoc b/docs/src/code/style-python.adoc new file mode 100644 index 00000000000..0dd0e90add8 --- /dev/null +++ b/docs/src/code/style-python.adoc @@ -0,0 +1,12 @@ +:lang: en +:toc: + += Python Coding Standards + +Use the http://www.python.org/dev/peps/pep-0008/[PEP 8] style for +Python code. + +[NOTE] +To be done, experience and help very welcome ! + +// vim: set syntax=asciidoc: