165 lines
4.7 KiB
ReStructuredText
165 lines
4.7 KiB
ReStructuredText
|
Development concepts for libcasio
|
||
|
=================================
|
||
|
|
||
|
As a follow-up for :ref:`user-concepts` in the user guide, here's a few
|
||
|
concepts and decisions that have been taken for the development.
|
||
|
|
||
|
File organization
|
||
|
-----------------
|
||
|
|
||
|
There are many, many files in libcasio, and that's because I try to keep the
|
||
|
project clean and organized. This file is an attempt at describing how
|
||
|
the files are organized and where you can find or should put anything here.
|
||
|
|
||
|
There are a few main files and folders:
|
||
|
|
||
|
``docs/``
|
||
|
The library documentation, written using Sphinx.
|
||
|
|
||
|
``include/``
|
||
|
The public headers to use with the library (not including
|
||
|
internal headers).
|
||
|
|
||
|
``src/``
|
||
|
The sources and internal headers.
|
||
|
|
||
|
``tools/``, ``configure``, ``Makefile``, ``Makefile.vars``, ``Makefile.msg``
|
||
|
Build utilities.
|
||
|
|
||
|
``README.md``, ``CONTRIBUTING.md``, ``LICENSE.md``
|
||
|
Basic to-read files.
|
||
|
|
||
|
In the ``include/`` folder, there is the main header the user is supposed to
|
||
|
include, ``libcasio.h``, and a subfolder, which contains all of the headers
|
||
|
specific to modules. It is organized as in ``src/``, in modules which represent
|
||
|
the abstraction the module defines. For example, ``src/stream/`` and
|
||
|
``include/libcasio/stream.h`` are related to the libcasio-specific stream which
|
||
|
defines platform-agnostic functions to the system-specific utilities.
|
||
|
|
||
|
In the source folder, the ``internals.h`` header is the general internal header
|
||
|
which is included in every source file in the project (sometimes using a
|
||
|
module or submodule specific header which defines some more specific things
|
||
|
afterwards). It contains general utilities such as reliable endian management
|
||
|
macros, reliable integer types, and so on.
|
||
|
|
||
|
Function declarations and definitions
|
||
|
-------------------------------------
|
||
|
|
||
|
For portability (e.g. call conventions and other compiler-specific mess),
|
||
|
libcasio uses a few macros for declaring and defining functions that you are
|
||
|
expected to use if you ought to add some stuff:
|
||
|
|
||
|
.. function:: OF(ARGS)
|
||
|
|
||
|
This is a macro originally from `Zlib <https://www.zlib.net/>`_. It is
|
||
|
used on function declarations for compatibility with K&R (pre-ANSI) C,
|
||
|
which didn't support arguments definition for them. Without the macro,
|
||
|
you might have done:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
#if defined(__STDC__) && __STDC__
|
||
|
int my_function(int arg, char const *carg);
|
||
|
#else
|
||
|
int my_function(); /* K&R */
|
||
|
#endif
|
||
|
|
||
|
Instead, with this macro, you can just do:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
int my_function
|
||
|
OF((int arg, char const *carg));
|
||
|
|
||
|
.. function:: CASIO_EXTERN(TYPE)
|
||
|
|
||
|
Declare or define a function exported or ought to be. For example, with
|
||
|
a declaration and a definition:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
CASIO_EXTERN(int) my_function
|
||
|
OF((int arg1, int arg2));
|
||
|
|
||
|
CASIO_EXTERN(int) my_function(int arg1, int arg2)
|
||
|
{
|
||
|
return (arg1 + arg2);
|
||
|
}
|
||
|
|
||
|
Which can be resolved as one of the following (not exhaustive):
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
/* Within normal circumstances. */
|
||
|
extern int my_function(int arg1, int arg2);
|
||
|
|
||
|
/* Oh, we're on good ol' Windows! Let's set a call convention
|
||
|
* explicitely so we don't run into problems. */
|
||
|
extern int WINAPI my_function(int arg1, int arg2);
|
||
|
|
||
|
.. function:: CASIO_NORETURN
|
||
|
|
||
|
Use instead of :c:func:`CASIO_EXTERN` for functions that are not supposed
|
||
|
to return, e.g. if they ``exit()`` or ``abort()``. For example:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
CASIO_NORETURN panic_and_set_fire_to_the_computer
|
||
|
OF((char const *msg));
|
||
|
|
||
|
.. function:: CASIO_LOCAL(TYPE)
|
||
|
|
||
|
Use for defining a function internal to the file. For example, with
|
||
|
a declaration and a definition:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
CASIO_LOCAL(int) my_function(int arg1, int arg2);
|
||
|
|
||
|
CASIO_LOCAL(int) my_function(int arg1, int arg2)
|
||
|
{
|
||
|
return (arg1 - arg2);
|
||
|
}
|
||
|
|
||
|
Which can be resolved as one of the following (not exhaustive):
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
/* Within normal circumstances. */
|
||
|
static int my_function(int arg1, int arg2);
|
||
|
|
||
|
.. function:: CASIO_HOOK(TYPE)
|
||
|
|
||
|
Equivalent of :c:func:`CASIO_LOCAL` for functions that ought to be used
|
||
|
as hooks, i.e. callbacks for libcasio.
|
||
|
|
||
|
.. function:: CASIO_HOOK_TYPE(TYPE)
|
||
|
|
||
|
Extern function as a type, for using hook functions as callbacks within
|
||
|
``typedef`` or other type definitions. For example:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
typedef CASIO_EXTERN_TYPE(int) my_function_t
|
||
|
OF((int arg1, int arg2));
|
||
|
|
||
|
.. function:: CASIO_EXTERN_TYPE(TYPE)
|
||
|
|
||
|
Equivalent of :c:func:`CASIO_HOOK_TYPE` for exported functions to be
|
||
|
used and stored as hooks.
|
||
|
|
||
|
.. function:: CASIO_DEPRECATED
|
||
|
|
||
|
Prefix for function declarations and definitions which will be marked as
|
||
|
deprecated for the compiler (if it supports it). For example:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
CASIO_DEPRECATED CASIO_EXTERN(char const *) do_not_use_this_function
|
||
|
OF((char const *s));
|
||
|
|
||
|
CASIO_DEPRECATED CASIO_EXTERN(char const *) do_not_use_this_function(char const *s)
|
||
|
{
|
||
|
return (s + strlen(s));
|
||
|
}
|