/ CODING.org
CODING.org
  1  #+TITLE: Coding Nomenclature and Style
  2  #+OPTIONS: author:nil date:nil
  3  
  4  * Nomenclature: Topics
  5  
  6  In a discussion on Le'Sec code, a topic is a set of types, functions and
  7  macros that belong together as unit.
  8  
  9  A recognisable topic would be a specific Le'Sec type, plus all the
 10  sub-types, functions and macros that surround it.
 11  
 12  Another way to recognise a topic is that there is a design story related to
 13  it.
 14  
 15  ** Discussion
 16  
 17  In other projects, this is often called "API" or "feature", but those terms
 18  have come to mean a variety of things on who you ask, and have thereby
 19  become a source of confusion.
 20  
 21  Yet other words to describe the same thing could be "unit" or "component".
 22  
 23  * Style: Coding in C
 24  
 25  This project uses a coding style that is derived from [[https://www.gnu.org/prep/standards/standards.html#Writing-C][the GNU Coding
 26  Standards, Chapter 5 - Making The Best Use of C]], only making a few
 27  exceptions:
 28  
 29  ** Please don't have the starting curly braces on separate lines
 30  
 31  In other words, this:
 32  
 33  #+BEGIN_SRC C
 34    if (cond) {
 35      body();
 36    }
 37  #+END_SRC
 38  
 39  is preferable to this:
 40  
 41  #+BEGIN_SRC C
 42    if (cond)
 43      {
 44        body();
 45      }
 46  #+END_SRC
 47  
 48  ** Please don't separate function names from its argument list
 49  
 50  In other words, this:
 51  
 52  #+BEGIN_SRC C
 53    fn(a, b, c);
 54  #+END_SRC
 55  
 56  is preferable to this:
 57  
 58  #+BEGIN_SRC C
 59    fn (a, b, c);
 60  #+END_SRC
 61  
 62  However, there are some statements that include a parenthesised condition,
 63  and that may look like a function call.  Please continue to separate their
 64  keyword from the condition, i.e.:
 65  
 66  #+begin_src C
 67    if (cond) ...;
 68    while (cond) ...;
 69    switch (num) { ...; }
 70    for (init; cond; increment) ...;
 71    /* ... etc ... */
 72  #+end_src
 73  
 74  ** Having the function return type and the function name on different lines is optional
 75  
 76  Go with what's practical in terms of line length and some modicum of
 77  elegance.  Having them on the same line or on separate lines is all the
 78  same, some tools non-withstanding.
 79  
 80  * Style: Symbols (function names, variables names, macro names)
 81  
 82  ** Prefix
 83  
 84  All public symbols must have an upper case prefix that corresponds to the
 85  library, and is usually an acronym for its longer name (for example, Le'Sec
 86  Core gives the prefix =LSC_=).
 87  
 88  Non-static internal symbols (which are still externalised in static
 89  libraries) must have the same prefix, but in lower case.
 90  
 91  Internal static symbols do not need a prefix.
 92  
 93  ** The rest of the symbol
 94  
 95  /NOTE/: In this section, "object" is primarly the grammatical term, not an
 96  Object in programming terms.
 97  
 98  The rest of the symbol should try to be close to normal english, so roughly
 99  speaking follow these patterns:
100  
101  - verb followed by object (such as ~LSC_add_environment_bag()~)
102  
103    This only makes sense for functions and macros with arguments, as they
104    perform actions.
105  
106  - adjective followed by object (such as ~LSC_new_environment()~)
107  
108    NOTE: that's seen as bad form; the verb followed by object form is
109    preferred.  However, the form with ~new~ followed by the object is such a
110    common occurance that it can be treated as an acceptable exception.
111  
112    This only makes sense for functions and macros with arguments, as they
113    perform actions.
114  
115  - just the object (such as the internal ~lsc_env_dispatch()~).
116  
117  *** Shared [[*Nomenclature: Topics][topic]]
118  
119  For symbols belonging in a [[*Nomenclature: Topics][topic]], it's preferable that they include a
120  word that demonstrate this.  This would usually be the name of the topic
121  itself.  This word would normally be a verb or an object.
122  
123  /As an example, all public types and functions that are related to the
124  environment have the word =environment= or =env= in their symbols./
125  
126  The shared word doesn't have to be exactly the same, inflections are
127  allowed; they are even encouraged.
128  
129  /As an example, all public types and functions that are related to key
130  derivation have one of the words =derivator=, =derive= or =derivation= in
131  their symbols./
132  
133  *** Types and structures
134  
135  Le'Sec C types (typically defined with ~typedef~) should always have one of
136  the suffixes:
137  
138  - For a function signature type, ~_fn~
139  - Otherwise, ~_t~
140  
141  Le'Sec ~struct~ names should always have the suffix ~_st~.
142  
143  *** Macros
144  
145  Generally speaking, this follows the rules and recommendations above, except
146  that they are generally in all upper case.
147  
148  Macros that are simple constants may sometimes follow slightly different
149  rules, which will crystalize over time.  For example, all dispatch command
150  numbers in Le'Sec Core have macros with the prefix ~LSC_NR~.
151  
152  * Style: Argument lists
153  
154  The arguments for functions and macros with arguments should roughly be
155  these, in order:
156  
157  1. For functions and macros with arguments that are part of a topic, the
158     type they are associated with should generally come as the first
159     argument.  There may be arguable exceptions, see [[On the subject of the topical type coming first][discussion]] below.
160  2. All the mandatory and/or common input variables, except for an instance
161     of ~LSC_env_t~ (see [[On the subject of ~LSC_env_t~][discussion]] below).
162  3. Any output / result variable(s), if they are needed (in other word, there
163     is or may be more than merely the returned status code).
164  4. Optional arguments, primarly a [[On Parameter Sets][parameter set]].
165  5. A pointer to an instance of ~LSC_env_t~, unless that's the first argument
166     or expected to be embedded in the first argument.
167  
168  If variadic arguments are used, they should be treated in such a way that
169  this argument order is maintained.
170  
171  In all cases, any of the above are optional if there are no arguments that
172  fit the criteria for that location in the argument list.
173  
174  ** Discussion
175  
176  *** On the subject of ~LSC_env_t~
177  
178  ~LSC_env_t~ is a fairly special type, as it's the root of everything and
179  should be ever present, "magically".
180  
181  There is a different language where that's almost litererally the case:
182  Common Lisp.  That language has a special option for macros that take an
183  environment, =&environment=, which must /always/ come last in the macro
184  argument list, and which is never given explicitly in a macro call.
185  
186  C being the language it is, that level of magic isn't possible.  However, we
187  can still let ourselves be inspired by its location relative to other
188  arguments, to the extent that it's possible.
189  
190  *** On the subject of the topical type coming first
191  
192  One notable (and arguable) exception to this are the plugin invocation and
193  revocation functions, which take the plugin start an stop functions as first
194  argument.
195  
196  #+BEGIN_SRC C
197    LE_STATUS LSC_invoke_plugin(LSC_plugin_start_fn *start, LSC_PLUGIN **plugin,
198                                LSC_env_t *env);
199    LE_STATUS LSC_revoke_plugin(LSC_plugin_stop_fn *stop, LSC_PLUGIN *plugin);
200  #+END_SRC
201  
202  With ~LSC_invoke_plugin()~, it's not very difficult to argue for this
203  ordering, as ~plugin~ is an obvious output argument.
204  
205  With ~LSC_revoke_plugin()~, it could be argued that ~plugin~ should come
206  first, as it is of the topical type.  However, it can also be argued that it
207  makes for an ugly interface in relation with ~LSC_invoke_plugin()~, /and/
208  that it's mainly an input argument that's simply passed along to the ~stop~
209  function.
210