=================
STYLE OF THE CODE
=================

  Unfortunatly the style is not homogeneous throughout the program!!!
  This problem is connected with the long life of this code and with my mind
  which changes with experience.
 

NAMING CONVENTIONS
------------------

  Names are choosen differently for different entities in the code (types,
  instances, macros). In particular,

  InThisWay   --> types
  in_this_way --> instances
  a, b, c, .. --> local instances (counters, and other instances which are
                  defined and used within few lines of code)
  In_This_Way --> functions
  IN_THIS_WAY --> macros

  Names for functions usually start with a prefix. Typically, if the function
  is a method of the object ``TheObject``, then ``TheObject_`` should be the
  prefix. For example, ``TheObject_Do_Something``. If the function is a
  standalone function, then it should still have a prefix which suggests in
  which file the function may be defined. For example: 'Cmp_Operator_New' may
  be defined in the file 'cmp.c'. Whenever a symbol is supposed to be used from
  outside the library, it should start with the prefix ``Box``. For example:
  ``BoxType``, ``box_instance``, ``Box_Do_Something`` or ``BOX_DO_SOMETHING``
  (for types, instances, functions and macros, respectively). Static functions
  use the prefix My_ to denote they are defined in the same file. In principle,
  one should do the same for static variables, but one should try to avoid
  using static variables unless it is really necessary to use them, which means
  one should never use them (even if, presently, this rule is not strictly
  followed in the code. Mainly, for messages.c, msgbase.c and lex, yacc
  files). For locally defined typedef the same applies: ``typedef xxx
  MyType;``.

  Here is a summary of  rules which may help to make the naming of library
  entities more uniform and less arbitrary (having to go through the library to
  rename things is not fun and may also require to change the library interface
  too often):

  * whatever goes into the standard library should be preceded by a ``Box``,
    ``BOX`` or ``box`` prefix, to avoid clashes with names from other
    libraries (C doesn't allow to pack things into namespaces!):

    - for types: ``BoxOneType``, ``BoxAnotherType``, ...

    - for methods which get ``BoxOneType`` as first argument:
      ``BoxOneType_Do_Something``, ``BoxOneType_Do_Something_Else``.

    - other functions should be named as ``Box_Do_Something``.

  * In general, a function does something, right? Therefore it is advisable
    to choose a name that contains the verb describing what it does:

    - ``BoxWin_Draw_Text`` rather than ``BoxWin_Text``, ``BoxWin_Set_Font``
      rather than ``BoxWin_Font``.

    - functions that are querying for attributes should have again a verb in
      their name: ``Is``, ``Has`` in order of precedence: ``BoxWin_Has_Font``
      rather than ``BoxWin_Font``.

    - a function retrieving a property or sub-object of a parent object should
      use the verb ``Get``: ``BoxParent_Get_Size``, ``BoxParent_Get_Item``.


TYPESETTING CONVENTIONS
-----------------------

  Use indentation length of 2 (and spaces instead of tabs), example:

  while (1) {
    printf("Nothing to print!\n");
    printf("Really nothing!\n");
  }

  Lines should not exceed 79 characters.

  Avoid use of C++ keywords as variable names, for example don't use
  'bool' since it exists in C++ and will cause a clash if the code is
  ever compiled as C++.


LANGUAGE CONFORMANCE
--------------------

  Our aim is to produce code which complies with the C99 standard.
  This allows us some freedom:

  * we try to declare the variables at the beginning of each scope block,
    just to make the code more readable (it is then clear where to look for
    variable declarations), but don't take this role to be "God's Law".
    If we find useful to put a statement before a declaration, then we do it!

  * we can use variadic macros.


HOW WE DEAL WITH ERRORS
-----------------------

  This typedef is defined inside 'types.h':

    typedef enum {
      BOXTASK_OK      = 0, /**< Function succeeded */
      BOXTASK_FAILURE = 1, /**< Function failed: caller needs to report error */
      BOXTASK_ERROR   = 2  /**< Function failed: error already reported */
    } BoxTask;

  This is how we define many functions:

    /* This functions deals with a particular task and can exit with
     * or without errors
     */
    BoxTask Do_Do_Do(...) {
      ...
      if (...)
        return BOXTASK_FAILURE;   /* Exits in case of errors! */

      if (...) {                  /* Exit, but report error first! */
        MSG_ERROR("Error in Do_Do_Do!")
        return BOXTASK_ERROR;

      ...
      return BOXTASK_OK;        /* Operation succesfully completed! */
    }

  Now we call this function, testing for errors:

    /* Main function */
    int main(void) {
      if (Do_Do_Do(...) != BOXTASK_OK)
        fprintf(stderr, "Error!\n");
    }

  Note that one shouldn't use such an infrastructure if it is not really
  necessary. In other words, when an error compromises the whole execution of
  the program, the error should not be handled in this way, but the program
  should be halted. For example, if we cannot allocate 40 bytes to store - for
  example - an AST node, then why should we continue at all?! If malloc fails to
  give us 40 bytes, it is likely that the only thing we want to do is to abort
  the execution as soon as we can. One should then use code like:

    if (critical_error) {
      MSG_FATAL("Critical error in Name_Of_Function.");
      assert(0);
      return; /* if needed to make the C compiler happy, even if these days
                 gcc can cope well with such situation without complaining
                 for execution reaching end of function without returning...
               */    
    }

  (Note that in the aforementioned example of allocation you may want to use
  BoxMem_Safe_Alloc, which aborts automatically on failure).
  You can use also ``abort();`` rather than ``assert(0)``, but do not use the
  ``exit`` function (abort allows the debugger to do its job).
  If - on the other hand - you are allowing the user to allocate a very big
  array, then you may be interested in handling the NULL pointer returned by
  BoxMem_Alloc.


NULL AND CASTING
----------------

  Other than the obvious...
  NB: remember casts are dangerous, annoying for maintenance and can cause
      performance hits (esp. float <-> int)

  * Always use NULL for pointers instead of 0.
    For example,

  While the standard says that 0 and NULL are interchangable, NULL is specific
  to pointers and thus is more readable and allows implicit casts/errors to be
  picked up

  * You can rely on implicit (void *) casts, it's part of the standard
    However feel free to use the void casts in areas where redundancy
    improves the quality or readability.

  * You shouldn't rely on cast from (void *) to (Object *).
    The idea is that automatic casts should not allow an object to acquire
    meaning. In other words, a pointer to Object is a pointer anyway, so it
    is fine to pass it to a function requiring as argument (void *). On the
    contrary, a pointer to void is not - in general - a pointer to Object,
    therefore the cast should be explicit. For BoxMem_Alloc and friends, you
    can feel free to omit the cast, to avoid redundancy (i.e. you can use
    Object *obj = BoxMem_Alloc(sizeof(Object)) rather than
    Object *obj = (Object *) BoxMem_Alloc(sizeof(Object)).

  * Cast to (void) when you want to make it explicit on the code that you
    want to discard the return value of a function.

    Example:

    int foo(void) {
      return 5;
    }

    /* ... */

    (void) foo();

    The following is regular C:

    foo();

    But one may wonder whether it is an error: why is it not using the
    returned value? One may argue that - in general - the return value is
    typically the reason why you call a function.
    A (void) cast makes it explicit that you are aware that you know that the
    function returns something, and you *WANT* to discard it.
    This also helps when using -Wunused-value to find out whether you discarded
    some return values without being aware of it.


NOTES
-----

  Some other random notes:

  * Never access the elements of a structure type explicitly, except for the
    files which provide the implementation of the corresponding type. You can
    always define a macro in the header where the structure is defined.
    This will make interface between sources clearer.

  * We are not caring much about binary compatibility of the interface: i.e.
    types are not opaque pointers, but are defined in full in the headers we
    install on the system with a ``make install``. Inside them we define
    macros which pretend to be functions and can access the structure members.
    This means that we may break binary compatility of the Box core library
    by just reordering the elements in the datastructure. We tolerate this
    for now.

  * we are currently not caring much about the ``const`` attribute.
    We may want to change this.

  * Note that the source directory is currently named ``box`` this is to make
    it easy to include the core headers. The idea is that one can use
    ``#include <box/types.h>`` in his C source, and give a
    ``-I/path/to/include/box0.2`` to the C compiler. Typically one can give
    something like::

      cc -c -I`box -q C_INCLUDE_PATH` myext.c -o myext.o

   (try ``box -q all`` to see what Box knows about itself).

