1=================
2STYLE OF THE CODE
3=================
4
5  Unfortunatly the style is not homogeneous throughout the program!!!
6  This problem is connected with the long life of this code and with my mind
7  which changes with experience.
8
9
10NAMING CONVENTIONS
11------------------
12
13  Names are choosen differently for different entities in the code (types,
14  instances, macros). In particular,
15
16  InThisWay   --> types
17  in_this_way --> instances
18  a, b, c, .. --> local instances (counters, and other instances which are
19                  defined and used within few lines of code)
20  In_This_Way --> functions
21  IN_THIS_WAY --> macros
22
23  Names for functions usually start with a prefix. Typically, if the function
24  is a method of the object ``TheObject``, then ``TheObject_`` should be the
25  prefix. For example, ``TheObject_Do_Something``. If the function is a
26  standalone function, then it should still have a prefix which suggests in
27  which file the function may be defined. For example: 'Cmp_Operator_New' may
28  be defined in the file 'cmp.c'. Whenever a symbol is supposed to be used from
29  outside the library, it should start with the prefix ``Box``. For example:
30  ``BoxType``, ``box_instance``, ``Box_Do_Something`` or ``BOX_DO_SOMETHING``
31  (for types, instances, functions and macros, respectively). Static functions
32  use the prefix My_ to denote they are defined in the same file. In principle,
33  one should do the same for static variables, but one should try to avoid
34  using static variables unless it is really necessary to use them, which means
35  one should never use them (even if, presently, this rule is not strictly
36  followed in the code. Mainly, for messages.c, msgbase.c and lex, yacc
37  files). For locally defined typedef the same applies: ``typedef xxx
38  MyType;``.
39
40  Here is a summary of  rules which may help to make the naming of library
41  entities more uniform and less arbitrary (having to go through the library to
42  rename things is not fun and may also require to change the library interface
43  too often):
44
45  * whatever goes into the standard library should be preceded by a ``Box``,
46    ``BOX`` or ``box`` prefix, to avoid clashes with names from other
47    libraries (C doesn't allow to pack things into namespaces!):
48
49    - for types: ``BoxOneType``, ``BoxAnotherType``, ...
50
51    - for methods which get ``BoxOneType`` as first argument:
52      ``BoxOneType_Do_Something``, ``BoxOneType_Do_Something_Else``.
53
54    - other functions should be named as ``Box_Do_Something``.
55
56  * In general, a function does something, right? Therefore it is advisable
57    to choose a name that contains the verb describing what it does:
58
59    - ``BoxWin_Draw_Text`` rather than ``BoxWin_Text``, ``BoxWin_Set_Font``
60      rather than ``BoxWin_Font``.
61
62    - functions that are querying for attributes should have again a verb in
63      their name: ``Is``, ``Has`` in order of precedence: ``BoxWin_Has_Font``
64      rather than ``BoxWin_Font``.
65
66    - a function retrieving a property or sub-object of a parent object should
67      use the verb ``Get``: ``BoxParent_Get_Size``, ``BoxParent_Get_Item``.
68
69
70TYPESETTING CONVENTIONS
71-----------------------
72
73  Use indentation length of 2 (and spaces instead of tabs), example:
74
75  while (1) {
76    printf("Nothing to print!\n");
77    printf("Really nothing!\n");
78  }
79
80  Lines should not exceed 79 characters.
81
82  Avoid use of C++ keywords as variable names, for example don't use
83  'bool' since it exists in C++ and will cause a clash if the code is
84  ever compiled as C++.
85
86
87LANGUAGE CONFORMANCE
88--------------------
89
90  Our aim is to produce code which complies with the C99 standard.
91  This allows us some freedom:
92
93  * we try to declare the variables at the beginning of each scope block,
94    just to make the code more readable (it is then clear where to look for
95    variable declarations), but don't take this role to be "God's Law".
96    If we find useful to put a statement before a declaration, then we do it!
97
98  * we can use variadic macros.
99
100
101HOW WE DEAL WITH ERRORS
102-----------------------
103
104  This typedef is defined inside 'types.h':
105
106    typedef enum {
107      BOXTASK_OK      = 0, /**< Function succeeded */
108      BOXTASK_FAILURE = 1, /**< Function failed: caller needs to report error */
109      BOXTASK_ERROR   = 2  /**< Function failed: error already reported */
110    } BoxTask;
111
112  This is how we define many functions:
113
114    /* This functions deals with a particular task and can exit with
115     * or without errors
116     */
117    BoxTask Do_Do_Do(...) {
118      ...
119      if (...)
120        return BOXTASK_FAILURE;   /* Exits in case of errors! */
121
122      if (...) {                  /* Exit, but report error first! */
123        MSG_ERROR("Error in Do_Do_Do!")
124        return BOXTASK_ERROR;
125
126      ...
127      return BOXTASK_OK;        /* Operation succesfully completed! */
128    }
129
130  Now we call this function, testing for errors:
131
132    /* Main function */
133    int main(void) {
134      if (Do_Do_Do(...) != BOXTASK_OK)
135        fprintf(stderr, "Error!\n");
136    }
137
138  Note that one shouldn't use such an infrastructure if it is not really
139  necessary. In other words, when an error compromises the whole execution of
140  the program, the error should not be handled in this way, but the program
141  should be halted. For example, if we cannot allocate 40 bytes to store - for
142  example - an AST node, then why should we continue at all?! If malloc fails to
143  give us 40 bytes, it is likely that the only thing we want to do is to abort
144  the execution as soon as we can. One should then use code like:
145
146    if (critical_error) {
147      MSG_FATAL("Critical error in Name_Of_Function.");
148      assert(0);
149      return; /* if needed to make the C compiler happy, even if these days
150                 gcc can cope well with such situation without complaining
151                 for execution reaching end of function without returning...
152               */
153    }
154
155  (Note that in the aforementioned example of allocation you may want to use
156  BoxMem_Safe_Alloc, which aborts automatically on failure).
157  You can use also ``abort();`` rather than ``assert(0)``, but do not use the
158  ``exit`` function (abort allows the debugger to do its job).
159  If - on the other hand - you are allowing the user to allocate a very big
160  array, then you may be interested in handling the NULL pointer returned by
161  BoxMem_Alloc.
162
163
164NULL AND CASTING
165----------------
166
167  Other than the obvious...
168  NB: remember casts are dangerous, annoying for maintenance and can cause
169      performance hits (esp. float <-> int)
170
171  * Always use NULL for pointers instead of 0.
172    For example,
173
174  While the standard says that 0 and NULL are interchangable, NULL is specific
175  to pointers and thus is more readable and allows implicit casts/errors to be
176  picked up
177
178  * You can rely on implicit (void *) casts, it's part of the standard
179    However feel free to use the void casts in areas where redundancy
180    improves the quality or readability.
181
182  * You shouldn't rely on cast from (void *) to (Object *).
183    The idea is that automatic casts should not allow an object to acquire
184    meaning. In other words, a pointer to Object is a pointer anyway, so it
185    is fine to pass it to a function requiring as argument (void *). On the
186    contrary, a pointer to void is not - in general - a pointer to Object,
187    therefore the cast should be explicit. For BoxMem_Alloc and friends, you
188    can feel free to omit the cast, to avoid redundancy (i.e. you can use
189    Object *obj = BoxMem_Alloc(sizeof(Object)) rather than
190    Object *obj = (Object *) BoxMem_Alloc(sizeof(Object)).
191
192  * Cast to (void) when you want to make it explicit on the code that you
193    want to discard the return value of a function.
194
195    Example:
196
197    int foo(void) {
198      return 5;
199    }
200
201    /* ... */
202
203    (void) foo();
204
205    The following is regular C:
206
207    foo();
208
209    But one may wonder whether it is an error: why is it not using the
210    returned value? One may argue that - in general - the return value is
211    typically the reason why you call a function.
212    A (void) cast makes it explicit that you are aware that you know that the
213    function returns something, and you *WANT* to discard it.
214    This also helps when using -Wunused-value to find out whether you discarded
215    some return values without being aware of it.
216
217
218NOTES
219-----
220
221  Some other random notes:
222
223  * Never access the elements of a structure type explicitly, except for the
224    files which provide the implementation of the corresponding type. You can
225    always define a macro in the header where the structure is defined.
226    This will make interface between sources clearer.
227
228  * We are not caring much about binary compatibility of the interface: i.e.
229    types are not opaque pointers, but are defined in full in the headers we
230    install on the system with a ``make install``. Inside them we define
231    macros which pretend to be functions and can access the structure members.
232    This means that we may break binary compatility of the Box core library
233    by just reordering the elements in the datastructure. We tolerate this
234    for now.
235
236  * we are currently not caring much about the ``const`` attribute.
237    We may want to change this.
238
239  * Note that the source directory is currently named ``box`` this is to make
240    it easy to include the core headers. The idea is that one can use
241    ``#include <box/types.h>`` in his C source, and give a
242    ``-I/path/to/include/box0.2`` to the C compiler. Typically one can give
243    something like::
244
245      cc -c -I`box -q C_INCLUDE_PATH` myext.c -o myext.o
246
247   (try ``box -q all`` to see what Box knows about itself).
248
249