doc improvements.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 28 Feb 2010 21:29:30 +0000 (21:29 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 28 Feb 2010 21:29:30 +0000 (21:29 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@46670 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

doc/Doxyfile
src/include/Eina.h
src/include/eina_module.h
src/include/eina_rbtree.h
src/include/eina_rectangle.h
src/lib/eina_log.c
src/lib/eina_magic.c

index f10a270..dbc1c8c 100644 (file)
@@ -177,7 +177,7 @@ SEPARATE_MEMBER_PAGES  = NO
 # The TAB_SIZE tag can be used to set the number of spaces in a tab. 
 # Doxygen uses this value to replace tabs by spaces in code fragments.
 
-TAB_SIZE               = 2
+TAB_SIZE               = 8
 
 # This tag can be used to specify a number of aliases that acts 
 # as commands in the documentation. An alias has the form "name=value". 
@@ -773,7 +773,7 @@ DOCSET_FEEDNAME        = "Doxygen generated docs"
 # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
 # will append .docset to the name.
 
-DOCSET_BUNDLE_ID       = org.doxygen.Project
+DOCSET_BUNDLE_ID       = org.enlightenment.Eina
 
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
 # documentation will contain sections that can be hidden and shown after the 
index addaf24..68f1d05 100644 (file)
@@ -1,4 +1,4 @@
-/* EINA - EFL data type library
+b/* EINA - EFL data type library
  * Copyright (C) 2008-2010 Enlightenment Developers:
  *           Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com>
  *           Alexandre "diaxen" Becoulet <diaxen@free.fr>
 /**
  * @mainpage Eina
  *
- * @author Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com>
- * @author Alexandre "diaxen" Becoulet <diaxen@free.fr>
- * @author Andre Dieb <andre.dieb@gmail.com>
- * @author Arnaud de Turckheim "quarium" <quarium@gmail.com>
- * @author Carsten Haitzler <raster@rasterman.com>
- * @author Cedric Bail <cedric.bail@free.fr>
- * @author Corey "atmos" Donohoe <atmos@atmos.org>
- * @author Fabiano FidĂȘncio <fidencio@profusion.mobi>
- * @author Gustavo Chaves <glima@profusion.mobi>
- * @author Gustavo Sverzut Barbieri <barbieri@gmail.com>
- * @author Jorge Luis "turran" Zapata <jorgeluis.zapata@gmail.com>
- * @author Peter "pfritz" Wehrfritz <peter.wehrfritz@web.de>
- * @author Raphael Kubo da Costa <kubo@profusion.mobi>
- * @author Tilman Sauerbeck <tilman@code-monkey.de>
+ * @author Albin "Lutin" Tonnerre <albin.tonnerre@@gmail.com>
+ * @author Alexandre "diaxen" Becoulet <diaxen@@free.fr>
+ * @author Andre Dieb <andre.dieb@@gmail.com>
+ * @author Arnaud de Turckheim "quarium" <quarium@@gmail.com>
+ * @author Carsten Haitzler <raster@@rasterman.com>
+ * @author Cedric Bail <cedric.bail@@free.fr>
+ * @author Corey "atmos" Donohoe <atmos@@atmos.org>
+ * @author Fabiano FidĂȘncio <fidencio@@profusion.mobi>
+ * @author Gustavo Chaves <glima@@profusion.mobi>
+ * @author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi>
+ * @author Jorge Luis "turran" Zapata <jorgeluis.zapata@@gmail.com>
+ * @author Peter "pfritz" Wehrfritz <peter.wehrfritz@@web.de>
+ * @author Raphael Kubo da Costa <kubo@@profusion.mobi>
+ * @author Tilman Sauerbeck <tilman@@code-monkey.de>
  * @author Vincent "caro" Torri  <vtorri at univ-evry dot fr>
  * @date 2008-2010
  *
- * @section eina_toc_sec Table of contents
- *
- * <ul>
- *   <li> @ref eina_intro_sec
- *   <li> @ref eina_data_types_sec
- *   <ul>
- *     <li> @ref eina_container_subsec
- *     <ul>
- *       <li> @ref eina_array_subsubsec
- *       <li> @ref eina_hash_subsubsec
- *       <li> @ref eina_inlist_subsubsec
- *       <li> @ref eina_rbtree_subsubsec
- *       <li> @ref eina_trash_subsubsec
- *       <li> @ref eina_list_subsubsec
- *     </ul>
- *     <li> @ref eina_stringshare_subsec
- *   </ul>
- *   <li> @ref eina_access_contents_sec
- *   <ul>
- *     <li> @ref eina_iterators_subsec
- *     <li> @ref eina_accessors_subsec
- *   </ul>
- *   <li> @ref eina_tools_sec
- *   <ul>
- *     <li> @ref eina_convert_subsec
- *     <li> @ref eina_counter_subsec
- *     <li> @ref eina_error_subsec
- *   </ul>
- *   <li> @ref thread_safety_sec
- *   <li> @ref debugging_sec
- * </ul>
- *
  * @section eina_intro_sec Introduction
  *
- * The Eina library is a library that implemente an API for data types
+ * The Eina library is a library that implements an API for data types
  * in an efficient way. It also provides some useful tools like
  * openin shared libraries, errors management, type conversion,
  * time accounting and memory pool.
  * This library is cross-platform and can be compiled and used on
  * Linux and Windows (XP and CE).
  *
- * The data types that are available are
- * @li array
- * @li hash table
- * @li inlined list
- * @li inlined red black tree
- * @li list
- * @li shared string
- *
- * This document describes each data type by providing the algorithms
- * used in the implementation, the performance, a short tutorial and
- * the API.
- *
- * @section eina_data_types_sec Eina Data Types
- *
- * @subsection eina_container_subsec Containers
+ * The data types that are available are (see @ref Eina_Data_Types_Group):
+ * @li @ref Eina_Array_Group standard array of @c void* data.
+ * @li @ref Eina_Hash_Group standard hash of @c void* data.
+ * @li @ref Eina_Inline_List_Group list with nodes inlined into user type.
+ * @li @ref Eina_List_Group standard list of @c void* data.
+ * @li @ref Eina_Matrixsparse_Group sparse matrix of @c void* data.
+ * @li @ref Eina_Rbtree_Group red-black tree with nodes inlined into user type.
+ * @li @ref Eina_Stringshare_Group saves memory by sharing read-only string references.
+ * @li @ref Eina_Tiler_Group split, merge and navigates into 2D tiled regions.
+ * @li @ref Eina_Trash_Group container of unused but allocated data.
+ *
+ * The tools that are available are (see @ref Eina_Tools_Group):
+ * @li @ref Eina_Benchmark_Group helper to write benchmarks.
+ * @li @ref Eina_Convert_Group faster conversion from strings to integers, double, etc.
+ * @li @ref Eina_Counter_Group measures number of calls and their time.
+ * @li @ref Eina_Error_Group error identifiers.
+ * @li @ref Eina_File_Group simple file list and path split.
+ * @li @ref Eina_Lalloc_Group simple lazy allocator.
+ * @li @ref Eina_Log_Group full-featured logging system.
+ * @li @ref Eina_Magic_Group provides runtime type checking.
+ * @li @ref Eina_Memory_Pool_Group abstraction for various memory allocators.
+ * @li @ref Eina_Module_Group lists, loads and share modules using Eina_Module standard.
+ * @li @ref Eina_Rectangle_Group rectangle structure and standard manipulation methods.
+ * @li @ref Eina_Safety_Checks_Group extra checks that will report unexpected conditions and can be disabled at compile time.
+ *
+ * @defgroup Eina_Data_Types_Group
+ *
+ * Eina provide easy to use and optimized data types and structures.
+ *
+ *
+ * @defgroup Eina_Containers_Group Containers
  *
  * Containers are data types that hold data and allow iteration over
- * their elements with an @ref eina_iterators_subsec, or eventually an
- * @ref eina_accessors_subsec. The only data type that is not a container (in
- * that sense) is the @ref eina_stringshare_subsec.
- *
- * @subsubsection eina_array_subsubsec Array
- *
- * @subsubsection eina_hash_subsubsec Hash Table
- *
- * @subsubsection eina_inlist_subsubsec Inlined List
- *
- * @subsubsection eina_rbtree_subsubsec Inlined Red Black Tree
- *
- * @subsubsection eina_trash_subsubsec Trash
- *
- * @subsubsection eina_trash_subsubsec Trash
- *
- * @subsubsection eina_list_subsubsec List
- *
- * @subsection eina_stringshare_subsec Shared String
- *
- * @section eina_access_contents_sec Accessing Data Struct Contents
- *
- * For the container data types, you can access to the elements
- * sequentially with iterators, or randomly with accessors. They are
- * created from the data types themselves and allow a generic way to
- * traverse these data types.
- *
- * @subsection eina_iterators_subsec Iterator
- *
- * Iterators allow a sequential access of the data of a
- * container. They can only access the next element. To look at the
- * API, go to @ref Eina_Iterator_Group.
- *
- * @subsection eina_accessors_subsec Accessor
- *
- * Accessors allow a random access of the data of a container. They
- * can access an element at any position. To look at the API, go to
+ * their elements with an @ref Eina_Iterator_Group, or eventually an
  * @ref Eina_Accessor_Group.
  *
- * @section eina_tools_sec Eina Tools
- *
- * @subsection eina_convert_subsec Convert Functions
- *
- * @subsection eina_counter_subsec Timing Functions
- *
- * @subsection eina_error_subsec Error Functions
- *
- * Take a look at the API of @ref Eina_Error_Group.
- *
- * Take a look at the @ref tutorial_error_page.
- *
- * @section thread_safety_sec Thread safety
- *
- * Add some stuff for thread safety doc
- *
- * @section debugging_sec Debugging
  *
- * Add some stuff for the debug doc
+ * @defgroup Eina_Tools_Group Tools
  *
- * @todo add debug function
- * @todo add magic function
- * @todo add other todo items :)
+ * Eina tools aims to help application development, providing ways to
+ * make it safer, log errors, manage memory more efficiently and more.
  */
 
 #ifdef __cplusplus
index a585100..c45bedf 100644 (file)
 /**
  * @defgroup Eina_Module_Group Module
  *
+ * Eina module provides some helpers over POSIX dlopen(). It is not
+ * meant to replace, abstract or make a "portable" version of the
+ * POSIX, but enhance its usage by defining some good practices.
+ *
+ * Modules are created with eina_module_new() and later loaded with
+ * eina_module_load(). Loads are reference counted and there must be
+ * the same number of eina_module_unload() in order to have it to call
+ * dlclose(). This makes simple to have different users for the same
+ * module.
+ *
+ * The loaded shared objects may have two visible functions that will
+ * be called and might provide initialization and shutdown
+ * proceedures. The symbols are @c __eina_module_init and
+ * @c __eina_module_shutdown and will be defined by the macros
+ * EINA_MODULE_INIT() and EINA_MODULE_SHUTDOWN().
+ *
+ * There are some helpers to automatically create modules based on
+ * directory listing. See eina_module_arch_list_get(),
+ * eina_module_list_get() and eina_module_find().
+ *
  * @{
  */
 
+/**
+ * @typedef Eina_Module
+ * Dynamic module loader handle.
+ */
 typedef struct _Eina_Module Eina_Module;
 
 typedef Eina_Bool (*Eina_Module_Cb)(Eina_Module *m, void *data);
+
+/**
+ * @typedef Eina_Module_Init
+ * If a function with such signature is exported by module as
+ * __eina_module_init, it will be called on the first load after
+ * dlopen() and if #EINA_FALSE is returned, load will fail, #EINA_TRUE
+ * means the module was successfully initialized.
+ * @see Eina_Module_Shutdown
+ */
 typedef Eina_Bool (*Eina_Module_Init)(void);
+
+/**
+ * @typedef Eina_Module_Shutdown
+ * If a function with such signature is exported by module as
+ * __eina_module_shutdown, it will be called before calling dlclose()
+ * @see Eina_Module_Init
+ */
 typedef void (*Eina_Module_Shutdown)(void);
 
+/**
+ * @def EINA_MODULE_INIT
+ * declares the given function as the module initializer (__eina_module_init).
+ * It must be of signature #Eina_Module_Init
+ */
 #define EINA_MODULE_INIT(f) EAPI Eina_Module_Init __eina_module_init = &f
+
+/**
+ * @def EINA_MODULE_SHUTDOWN
+ * declares the given function as the module shutdownializer
+ * (__eina_module_shutdown).  It must be of signature
+ * #Eina_Module_Shutdown
+ */
 #define EINA_MODULE_SHUTDOWN(f) EAPI Eina_Module_Shutdown __eina_module_shutdown = &f
 
 /**
index 88eac6d..5a6a124 100644 (file)
 #include "eina_error.h"
 #include "eina_iterator.h"
 
+/**
+ * @addtogroup Eina_Data_Types_Group Data Types
+ *
+ * @{
+ */
+
+/**
+ * @addtogroup Eina_Containers_Group Containers
+ *
+ * @{
+ */
+
+/**
+ * @defgroup Eina_Rbtree_Group Red-Black tree
+ *
+ * @{
+ */
+
+/**
+ * @typedef Eina_Rbtree_Color
+ * node color.
+ */
 typedef enum {
   EINA_RBTREE_RED,
   EINA_RBTREE_BLACK
 } Eina_Rbtree_Color;
 
+/**
+ * @typedef Eina_Rbtree_Direction
+ * walk direction.
+ */
 typedef enum {
   EINA_RBTREE_LEFT = 0,
   EINA_RBTREE_RIGHT = 1
 } Eina_Rbtree_Direction;
 
+/**
+ * @typedef Eina_Rbtree
+ * Type for a Red-Black tree node. It should be inlined into user's type.
+ */
 typedef struct _Eina_Rbtree Eina_Rbtree;
 struct _Eina_Rbtree
 {
@@ -43,16 +73,60 @@ struct _Eina_Rbtree
    Eina_Rbtree_Color  color : 1;
 };
 
+/**
+ * @def EINA_RBTREE
+ * recommended way to declare the inlined Eina_Rbtree in your type.
+ *
+ * @code
+ * struct my_type {
+ *    EINA_RBTREE;
+ *    int my_value;
+ *    char *my_name;
+ * };
+ * @endcode
+ *
+ * @see EINA_RBTREE_GET()
+ */
 #define EINA_RBTREE Eina_Rbtree __rbtree
+
+/**
+ * @def EINA_RBTREE_GET
+ * access the inlined node if it was created with #EINA_RBTREE.
+ */
 #define EINA_RBTREE_GET(Rbtree) &((Rbtree)->__rbtree)
 
+/**
+ * @typedef Eina_Rbtree_Cmp_Node_Cb
+ * Function used compare two nodes and see which direction to navigate.
+ */
 typedef Eina_Rbtree_Direction (*Eina_Rbtree_Cmp_Node_Cb)(const Eina_Rbtree *left, const Eina_Rbtree *right, void *data);
+
+/**
+ * @def EINA_RBTREE_CMP_NODE_CB
+ * Cast using #Eina_Rbtree_Cmp_Node_Cb
+ */
 #define EINA_RBTREE_CMP_NODE_CB(Function) ((Eina_Rbtree_Cmp_Node_Cb) Function)
 
+/**
+ * @typedef Eina_Rbtree_Cmp_Key_Cb
+ * Function used compare node with a given key of specified length.
+ */
 typedef int (*Eina_Rbtree_Cmp_Key_Cb)(const Eina_Rbtree *node, const void *key, int length, void *data);
+/**
+ * @def EINA_RBTREE_CMP_KEY_CB
+ * Cast using #Eina_Rbtree_Cmp_Key_Cb
+ */
 #define EINA_RBTREE_CMP_KEY_CB(Function) ((Eina_Rbtree_Cmp_Key_Cb) Function)
 
+/**
+ * @typedef Eina_Rbtree_Free_Cb
+ * Function used free a node.
+ */
 typedef void (*Eina_Rbtree_Free_Cb)(Eina_Rbtree *node, void *data);
+/**
+ * @def EINA_RBTREE_FREE_CB
+ * Cast using #Eina_Rbtree_Free_Cb
+ */
 #define EINA_RBTREE_FREE_CB(Function) ((Eina_Rbtree_Free_Cb) Function)
 
 EAPI Eina_Rbtree *eina_rbtree_inline_insert(Eina_Rbtree *root, Eina_Rbtree *node, Eina_Rbtree_Cmp_Node_Cb cmp, const void *data) EINA_ARG_NONNULL(2, 3) EINA_WARN_UNUSED_RESULT;
@@ -67,4 +141,17 @@ EAPI Eina_Iterator *eina_rbtree_iterator_postfix(const Eina_Rbtree *root) EINA_M
 
 #include "eina_inline_rbtree.x"
 
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
 #endif
index 386cc85..16d4c79 100644 (file)
@@ -34,8 +34,7 @@
  */
 
 /**
- * To be documented
- * FIXME: To be fixed
+ * Simple rectangle structure.
  */
 typedef struct _Eina_Rectangle
 {
index 3ac5a0f..e4d8dce 100644 (file)
  * }
  * @endcode
  *
- * @addtogroup Eina_Log_Group Log
- *
- * @{
- *
- * The default log level value is set by default to
- * #EINA_LOG_LEVEL_DBG if Eina is compiled with debug mode, or to
- * #EINA_LOG_LEVEL_ERR otherwise. That value can be overwritten by
- * setting the environment variable EINA_LOG_LEVEL. This function
- * checks the value of that environment variable in the first
- * call. Its value must be a number between 0 and 4, to match the log
- * levels #EINA_LOG_LEVEL_CRITICAL, #EINA_LOG_LEVEL_ERR,
- * #EINA_LOG_LEVEL_WARN, #EINA_LOG_LEVEL_INFO and
- * #EINA_LOG_LEVEL_DBG. That value can also be set later with
- * eina_log_log_level_set(). When logging domains are created, they
- * will get either this value or specific value given with
- * EINA_LOG_LEVELS that takes the format
- * 'domain_name:level,another_name:other_level'.
- *
- * Format and verbosity of messages depend on the logging method, see
- * eina_log_print_cb_set(). The default logging method is
- * eina_log_print_cb_stderr(), which will output fancy colored
- * messages to standard error stream. See its documentation on how to
- * disable coloring, function or file/line print.
- *
- * This module will optionally abort program execution if message
- * level is below or equal to @c EINA_LOG_LEVEL_CRITICAL and
- * @c EINA_LOG_ABORT=1.
- *
- * @}
  */
 
 #ifdef HAVE_CONFIG_H
@@ -1172,15 +1143,45 @@ eina_log_threads_shutdown(void)
 /**
  * @addtogroup Eina_Log_Group Log
  *
- * @brief These functions provide log management for projects.
+ * @brief Full-featured logging system.
+ *
+ * Eina provides eina_log_print(), a standard function to manage all
+ * logging messages. This function may be called directly or using the
+ * helper macros such as EINA_LOG_DBG(), EINA_LOG_ERR() or those that
+ * take a specific domain as argument EINA_LOG_DOM_DBG(),
+ * EINA_LOG_DOM_ERR().  Internally, eina_log_print() will call the
+ * function defined with eina_log_print_cb_set(), that defaults to
+ * eina_log_print_cb_stderr(), but may be changed to do whatever you
+ * need, such as networking or syslog logging.
+ *
+ * The logging system is thread safe once initialized with
+ * eina_log_threads_enable(). The thread that calls this function
+ * first is considered "main thread" and other threads will have their
+ * thread id (pthread_self()) printed in the log message so it is easy
+ * to detect from where it is coming.
+ *
+ * Log domains is the Eina way to differentiate messages. There might
+ * be different domains to represent different modules, different
+ * feature-set, different categories and so on. Filtering can be
+ * applied to domain names by means of @c EINA_LOG_LEVELS environment
+ * variable or eina_log_domain_level_set().
+ *
+ * The different logging levels serve to customize the amount of
+ * debugging one want to take and may be used to automatically call
+ * abort() once some given level message is printed. This is
+ * controlled by environment variable @c EINA_LOG_ABORT and the level
+ * to be considered critical with @c EINA_LOG_ABORT_LEVEL. These can
+ * be changed with eina_log_abort_on_critical_set() and
+ * eina_log_abort_on_critical_level_set().
+ *
+ * The default maximum level to print is defined by environment
+ * variable @c EINA_LOG_LEVEL, but may be set per-domain with @c
+ * EINA_LOG_LEVELS. It will default to #EINA_LOG_ERR. This can be
+ * changed with eina_log_level_set().
  *
  * To use the log system Eina must be initialized with eina_init() and
- * later shut down with eina_shutdown(). The most generic way to print
- * logs is to use eina_log_print() but the helper macros
- * EINA_LOG_ERR(), EINA_LOG_INFO(), EINA_LOG_WARN() and EINA_LOG_DBG()
- * should be used instead.
- *
- * Here is a straightforward example:
+ * later shut down with eina_shutdown(). Here is a straightforward
+ * example:
  *
  * @code
  * #include <stdlib.h>
@@ -1215,12 +1216,7 @@ eina_log_threads_shutdown(void)
  * gcc -Wall -o test_Eina_Log test_eina.c `pkg-config --cflags --libs eina`
  * @endcode
  *
- * If Eina is compiled without debug mode, then executing the
- * resulting program displays nothing because the default log level
- * is #EINA_LOG_LEVEL_ERR and we want to display a warning
- * message, which level is strictly greater than the log level (see
- * eina_log_print() for more informations). Now execute the program
- * with:
+ * Now execute the program with:
  *
  * @code
  * EINA_LOG_LEVEL=2 ./test_eina_log
index 942d5c8..28dee38 100644 (file)
@@ -189,7 +189,88 @@ eina_magic_string_shutdown(void)
 /**
  * @addtogroup Eina_Magic_Group Magic
  *
- * @brief These functions provide magic checks management for projects.
+ * @brief These functions provide runtime type-checking (magic checks)
+ * management for projects.
+ *
+ * C is a weak statically typed language, in other words, it will just
+ * check for types during compile time and any cast will make the
+ * compiler believe the type is correct.
+ *
+ * In real world projects we often need to deal with casts, either
+ * explicit or implicit by means of @c void*. We also need to resort
+ * to casts when doing inheritance in C, as seen in the example below:
+ *
+ * @code
+ * struct base {
+ *    int id;
+ *    char *name;
+ * };
+ * int base_id_get(struct base *ptr) {
+ *    return ptr->id;
+ * }
+ *
+ * struct subtype {
+ *    struct base base;
+ *    time_t date;
+ * };
+ * @endcode
+ *
+ * It is perfectly valid to use @c{struct subtype} blobs for functions
+ * that expect @c{struct base}, since the fields will have the same
+ * offset (as base member is the first, at offset 0). We could give
+ * the functions the @c{&subtype->base} and avoid the cast, but often
+ * we just cast.
+ *
+ * In any case, we might be safe and check if the given pointer is
+ * actually of the expected type. We can do so by using eina_magic,
+ * that is nothing more than attaching an unique type identifier to
+ * the members and check for it elsewhere.
+ *
+ * @code
+ * #define BASE_MAGIC 0x12345
+ * #define SUBTYPE_MAGIC 0x3333
+ * struct base {
+ *    int id;
+ *    char *name;
+ *    EINA_MAGIC;
+ * };
+ * int base_id_get(struct base *ptr) {
+ *    if (!EINA_MAGIC_CHECK(ptr, BASE_MAGIC)) {
+ *       EINA_MAGIC_FAIL(ptr, BASE_MAGIC);
+ *       return -1;
+ *    }
+ *    return ptr->id;
+ * }
+ * void base_free(struct base *ptr) {
+ *    if (!EINA_MAGIC_CHECK(ptr, BASE_MAGIC)) {
+ *       EINA_MAGIC_FAIL(ptr, BASE_MAGIC);
+ *       return;
+ *    }
+ *    EINA_MAGIC_SET(ptr, EINA_MAGIC_NONE);
+ *    free(ptr->name);
+ *    free(ptr);
+ * }
+ *
+ * struct subtype {
+ *    struct base base;
+ *    EINA_MAGIC;
+ *    time_t date;
+ * };
+ *
+ * int my_init(void) {
+ *    eina_init();
+ *    eina_magic_string_set(BASE_MAGIC, "base type");
+ *    eina_magic_string_set(SUBTYPE_MAGIC, "subtype");
+ * }
+ * @endcode
+ *
+ * This code also shows that it is a good practice to set magic to
+ * #EINA_MAGIC_NONE before freeing pointer. Sometimes the pointers are
+ * in pages that are still live in memory, so kernel will not send
+ * SEGV signal to the process and it may go unnoticed that you're
+ * using already freed pointers. By setting them to #EINA_MAGIC_NONE
+ * you avoid using the bogus pointer any further and gets a nice error
+ * message.
  *
  * @{
  */