Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix (C) dates; proper xbt_log function
[simgrid.git] / README.coding
1 **
2 ** Source tree organization
3 **
4 ******************************************************
5
6 There is 4 projects in the tree:
7
8  - GROS: no fancy name yet (low-level toolbox: logging, datatypes).
9  - GRAS: Grid Reality And Simulation (message passing API with two
10          implementations allowing to compile programs on top of the
11          simulator or for the real life without code modification)
12  - SURF: Server for the Use of Resource Fictions (the simulator used 
13          in GRAS and more)
14  - AMOK: Advanced Metacomputing Overlay Kit (high level toolbox; Grid
15          application elements such as distributed database, topology
16          discovery service, and so on)
17
18 They are all in the same tree because GRAS depends on SURF which depends on
19 GRAS (that's the only cycle here, we're not *that* vicious).
20
21 The tree is not splited on projects, but on file finality:
22  include/            -> all *public* headers
23  include/gros/*.h    -> one file per module
24  include/gros.h      -> file including all modules headers
25   (same for gras, surf and amok instead of gros)
26   
27  src/Makefile.am     -> main makefile. All projects should fit in only one
28                         library (I mean 2, RL+SG), which is compiled here.
29                         
30                         Since all object.o files are placed here, you should
31                         choose the name of c files carfully to avoid
32                         conflict. 
33                         
34  src/gras/DataDesc                      -> typical project module
35  src/gras/DataDesc/datadesc_interface.h -> visible to any GRAS modules;
36                                            masked to the user and GROS/AMOK/SURF
37  src/gras/DataDesc/datadesc_private.h   -> visible only from this module                                           
38   
39    So, the modules have 3 levels of publicity for their interface. 
40    Private, internal to GRAS, public. Of course, I try to keep as much stuff
41    private as possible.
42   
43  testsuite/ -> The more test the better. 
44                Same organization than src/ and include/
45                Tests are allowed to load some headers of the module they test.
46                All tests should be listed in run_test.in so that they get
47                   run on 'make check'. 
48                They are not listed directly in the check_PROGRAMS part of
49                   the makefile because run_test knows about the gras logging
50                   features and relaunch with full details the failed tests.
51                   
52  examples/ -> Supposed to be copy/pastable by the user, so keep it clear and
53                 avoid any kind of trick. In particular, do only include the
54                 public headers here.
55
56 **
57 ** Type naming standard
58 **
59 *****************************************************
60
61 It may sound strange, but the type naming convention was source of intense
62 discution between da GRAS posse members. The convention we came to may not
63 be the best solution, but it has the merit to exist and leave everyone work.
64 So please stick to it.
65
66   - ???_t is a valid type (builded with typedef)
67   - s_toto_t is a structure (access to fields with .)
68   - s_toto   is a structure needing 'struct' keyword to be used
69   - e_toto_t is an enum
70   - u_toto_t is an union
71   - u_toto   is an union needing 'union' keyword to be used
72   -   toto_t is an 'object' (struct*)
73   
74 Please to not call toto_t something else than an 'object' (ie, something you
75 have to call _new and _free on it).
76
77 Exemple:
78   typedef struct s_toto {} s_toto_t, *toto_t;
79   typedef enum {} e_toto_t;
80   
81 Moreover, only toto_t (and e_toto_t) are public. The rest (mainly s_toto_t)
82 is private.
83
84 If you see any part of the code not following this convention, this is a
85 bug. Please report it (or fix it yourself if you can).
86
87 **
88 ** Random bits about coding standards and portability
89 **
90 *****************************************************
91
92 MALLOC:
93  You must cast the result of malloc on AIX. 
94  It's even better to use gras_new when possible.
95
96 SIZE_T
97  If possible, avoid size_t and use unsigned long instead. If not,
98
99  #include <sys/types.h> in all files manipulating size_t
100  do cast it to unsigned long before printing (and use %lu)
101  
102 PRINTF pointer difference
103  printf ("diff = %ld\n", (long) (pointer2 - pointer1));
104   
105
106 **              
107 ** Commenting the source
108 **
109 ****************************************************
110
111 Le format pour cela est :
112
113 /**                              (très important, la deuxieme étoile)
114  * nomDeFonction:                (faut les deux points)
115  * @param1: blabla               (faut le @ et les deux points, et ca peut
116  *                                courir sur plusieurs lignes)
117  * @param2: blabla
118  *                               (fin des paramètres: ligne vide)
119  * blabla sur la fonction        (autant de lignes que tu veux)
120  */
121
122 Si tu met () apres un nom de fonction, il essaye d'ajouter un lien
123 automatiquement, il me semble.
124
125
126 Ensuite, quand tu fais "make -C doc", il ne se passe rien de particulier ;)
127 Avant que ca marche, il faut créer une nouvelle section dans
128 doc/gras-sections.txt Attention, on dirait du xml, mais le parseur est
129 stupide. Je me suis arraché les cheveux plusieurs heures pour un "<SECTION<"
130
131 Tout ce qui n'est pas dans une section se trouve listé dans gras-unused.txt
132 Pour éviter que ca ne soit le cas sans pour autant les documenter, place les
133 symboles après <SUBSECTION Standard> (regarde tbx_log dans le fichier pour
134 un exemple).
135
136 Une fois la section crée, un "make -C doc" crée un bout de doc, mais ne
137 l'inclue pas dans la documentation finale. Pour cela, il faut éditer le
138 fichier gras-docs.sgml (qui est un fichier xml de bon aloi, malgré son
139 nom). Il te faut ajouter une entité système dans le prologue (avant "]>")
140 style: <!ENTITY tbx-cfg SYSTEM "xml/tbx_cfg.xml">
141 Ensuite dans le corps du document, tu colles: &tbx-cfg; et t'es arrivé. Au
142 milleu du gras-docs.sgml, y'a un bout de code mort en commentaire. Autant le
143 laisser, je nettoyerais un jour, peut etre.
144
145
146 Il te faut maintenant mettre un titre long et une description de module.
147 Pour cela, édite le fichier "tmpl/<nom_de_section>.sgml". Juste en haut, les
148 parties "SECTION Title", "SECTION Short_Description", "SECTION
149 Long_Description" et "SECTION See_Also". Pr les deux premiers, faut mettre
150 une seule ligne et pas de tags. Pour les autres, il faut faire des
151 paragraphes. Donc, tout ce que t'as le droit de mettre dans un <para> passe.
152
153 Attention, les fichiers dans doc/xml sont les morceaux prêts à être intégrés
154 par gras-doc.sgml. Ils sont donc générés et écrasés à tout bout de champ.
155 Mais les fichiers de doc/tmpl (templates) sont aussi partiellement générés.
156 Les doc de fonction extraites du code y sont placées, et les modification
157 que t'y a fait (titre, desc_courte/longue, voir_aussi) sont préservées,
158 normalement.
159
160
161 Voila, une fois ceci fait, la doc devrait être bonne. Comme tu peux le voir,
162 gtk-doc est bien plus bordelique à utiliser que doxygen (j'utilise souvent
163 "make clean all" car il semble manquer des dépendances). Mais je préfere car
164 on peut faire exactement ce qu'on veut. Et pis rose bonbon, c'est plus joli
165 que bleu triste.
166
167 **              
168 ** Using the logs
169 **
170 ****************************************************
171
172 Dans gras, tu ne te contente pas d'écrire des choses à l'écran, mais tu
173 écris sur un sujet particulier (notion de canal) des choses d'une gravité
174 particulière. Il y a 7 niveaux de gravité.
175  trace: tracer les entrées dans une fonction, retour de fonction
176         (famille de macros XBT_IN/XBT_OUT)
177  debug: pour t'aider à mettre au point le module, potentiellement tres bavard
178  verbose: quelques infos succintes sur les internals du module
179  info: niveau normal, ton de la conversation
180  warning: problème potentiel, mais auquel on a su faire face
181  error: problème qui t'as empêché de faire ton job
182  critical: juste avant de mourir
183
184 Quand on compile avec -DNDEBUG (par défaut dans le paquet Debian), tout ce
185 qui est '>= verbose' est supprimé au moment de la compilation. Retiré du
186 binaire, killé.
187
188 Ensuite, tu écris dans un canal particulier. Tous les canaux sont rangés en
189 arbre. Il faudrait faire un ptit script qui fouille les sources à la
190 recherche des macros XBT_LOG_NEW_* utilisées pour créer des canaux. Le
191 dernier argument de ces macros est ignoré dans le source. Il est destiné à
192 être la documentation de la chose en une ligne. En gros, ca fait:
193 root
194  +--xbt
195  |   +--config
196  |   +--dict
197  |   |   +--dict_cursor
198  |   |   +--dict_elm
199  |   |   ...
200  |   +--dynar
201  |   +--set
202  |   +--log
203  |   +--module
204  +--gras
205      +--datadesc
206      |   +--ddt_cbps
207      |   +--ddt_convert
208      |   +--ddt_exchange
209      |   +--ddt_parse
210      |       +--lexer
211      +--msg
212      +--transport
213          +--raw_trp (Je devrais tuer ce module, un jour)
214          +--trp_buf
215          +--trp_sg
216          +--trp_file
217          +--trp_tcp
218          
219 Et ensuite les utilisateurs peuvent choisir le niveau de gravité qui les
220 interresse sur tel ou tel sujet.
221
222 Toute la mécanique de logging repose sur des variables statiques dont le nom
223 dépend du nom du canal.
224  => attention aux conflits de nom de canal
225  => il faut une macro XBT_LOG dans chaque fichier où tu fais des logs.
226  
227 XBT_LOG_NEW_CATEGORY: nouveau canal sous "root". Rare, donc.
228 XBT_LOG_NEW_SUBCATEGORY: nouveau canal dont on précise le père.
229 XBT_LOG_DEFAULT_CATEGORY: indique quel est le canal par défaut dans ce fichier
230 XBT_LOG_NEW_DEFAULT_CATEGORY: Crèe un canal et l'utilise par défaut
231 XBT_LOG_NEW_DEFAULT_SUBCATEGORY: devine
232 XBT_LOG_EXTERNAL_CATEGORY: quand tu veux utiliser par défaut un canal créé
233                            dans un autre fichier.
234                            
235 Une fois que ton canal est créé, tu l'utilise avec les macros LOG, DEBUG,
236 VERB, WARN, ERROR et CRITICAL. Il faut que tu donne le nombre d'arguments
237 après le nom de macro. Exemple: LOG2("My name is %s %s","Martin","Quinson")
238 Si tu veux préciser explicitement le canal où écrire, ajoute un C devant le
239 nom de la macro. Exemple: CCRITICAL0(module, "Cannot initialize GRAS")
240
241 Toutes ces macros (enfin, ce en quoi elles se réécrivent) vérifient leurs
242 arguments comme printf le fait lorsqu'on compile avec gcc. 
243 LOG1("name: %d","toto"); donne un warning, et donc une erreur en mode
244 mainteneur.
245
246 Enfin, tu peux tester si un canal est ouvert à une priorité donnée (pour
247 préparer plus de débug, par exemple. Dans le parseur, je fais du pretty
248 printing sur ce qu'il faut parser dans ce cas).
249 XBT_LOG_ISENABLED(catName, priority) Le second argument doit être une valeur
250 de e_xbt_log_priority_t (log.h). Par exemple: xbt_log_priority_verbose
251
252 Voila sur comment mettre des logs dans ton code. N'hesite pas à faire pleins
253 de canaux différents pour des aspects différents de ton code. En
254 particulier, dans les dict, j'ai un canal pour l'ajout, le retrait, le
255 netoyage du code après suppression et ainsi de suite. De cette façon, je
256 peux choisir qui m'interresse.
257
258
259 Pour utiliser les logs, tu déjà faire, non ? Tu colle sur la ligne de
260 commande un ou plusieurs arguments de la forme
261   --gras-log="<réglage> [<reglage>+]" (ou sans " si t'as pas d'espace)
262 chaque réglage étant de la forme:
263   <canal>.thres=<priorité>
264 Les différents réglages sont lus de gauche à droite.
265 "root.thres=debug root.thres=critical" ferme tout, normalement.