Ticket #1783: remove own declaration of bzero()
[free-mc.git] / doc / HACKING
blob0eaf195b2a2cbcf9897db062d833cb3ad0e19971
1 This document
2 =============
4 This document is a guide how to develop GNU Midnight Commander.  It's
5 quite incomplete, but may be worth reading anyway.
7 The document was written by Miguel de Icaza and reworked by Pavel
8 Roskin and later from Patrick Winnertz.
9  Some parts were taken from the messages posted in the mailing
10 lists.
13 Compiling from GIT
14 ==================
16 To compile GNU Midnight commander from GIT, the following software is
17 required:
19 Autoconf 2.52 and above (latest is recommended)
20 Automake 1.5 and above (latest is recommended)
21 Gettext 0.11.5 and above
22 Glib 2.6 and above (2.14 and higher is recommended)
24 Full list of requirements you can see at:
25 http://www.midnight-commander.org/wiki/doc/buildAndInstall/req
27 It is recommended that all those tools are installed with the same
28 prefix.  Make sure that the tools with the right version are first in
29 PATH.
31 Once you have the right tools, run `autogen.sh' - it will generate
32 everything necessary for the build `configure'. Then run 'configure'
33 and `make' as usually.
35 The distribution tarball is created by the command `make distcheck'. 
36 This command can take a while.
38 Currently snapshots are made on Debian unstable and use the versions of
39 the tools from the unstable repository.  Yes, the rpm packages are made
40 on Debian too.
42 Note that the version of gettext doesn't affect the snapshot because the
43 distributed files are installed by gettext from archives for the version
44 used in the AM_GNU_GETTEXT_VERSION macro, which is 0.11.5.
48 Working with GNU Midnight Commander
49 ===================================
51 Please use the GIT version.  It may be quite different from the released
52 versions.  A lot of cleanup is going on.  The GIT version may be easier
53 to understand, in addition to the obvious fact that the merging is
54 easier with the GIT version.
56 In order to compile GNU Midnight Commander from a clean GIT checkout you
57 should use 'autogen.sh && ./configure' instead of 'configure'.
59 GNU Midnight Commander uses Autoconf and Automake, with make it fairly
60 portable.  However, GNU Make is strongly recommended for development
61 because other versions of make may not track dependencies properly. 
62 This is very important for correct compilation, especially if you change
63 any header files.
65 If you add or remove any files, please change Makefile.am in the same
66 directory accordingly.  When doing significant changes in the tree
67 structure, "make distcheck" is strongly recommended.
69 GNU Autoconf allows you to test several different configurations are
70 once.  To do so, use the so called out-of-tree (or VPATH) compilation. 
71 Create separate empty directories and run configure with full path from
72 those directories, like this:
74 cd /usr/local/src
75 mkdir mc-slang
76 mkdir mc-ncurses
77 cd mc-slang
78 /usr/local/src/mc/configure && make all
79 cd ../mc-ncurses
80 /usr/local/src/mc/configure --with-screen=ncurses && make all
82 Please use the same indentation as other developers.  To indent a block,
83 select in the internal editor and use Shift-F9 to call the external
84 indent.  For historic reasons, GNU Midnight Commander used formatting
85 that is not default for GNU Indent.  Please put following text to your
86 ~/.indent.pro file to make GNU Indent follow the style used in GNU
87 Midnight Commander:
89 -kr -i4 -pcs -psl --ignore-newlines
91 It's OK to indent the whole function if you edit it.  However, please
92 refrain from it if you are posting your patch for review.  In this case
93 you would save time of other developers if you only include significant
94 changes.  The developer applying your patch can format the code for you.
96 Please keep in mind that the VFS subsystem is licensed under LGPL, while
97 the rest of the code uses GPL.
100 Code structure - outline
101 ========================
103 The code is located in following directories.
105 vfs - Virtual File System.
107 This library provides filesystem-like access to various data, such are
108 archives and remote filesystems.  To use VFS, you should use wrappers
109 around POSIX calls.  The wrappers have names composed from "mc_" and the
110 standard name of the function.  For example, to open a file on VFS, use
111 mc_open() instead.
113 edit - the internal editor.
115 This code has been contributed by Paul Sheer, the author of Cooledit.
116 The internal editor shares some code with Cooledit, but now it's
117 developed as part of GNU Midnight Commander.
119 src - the main part of the code.
121 This code includes the dialog manager written by Radek Doulik and source
122 code of the main application.
124 Code structure - details
125 ========================
127 GNU Midnight Commander uses extensively the dialog manager written by
128 Radek Doulik.  To understand how the dialog manager works, please read
129 the dialog.c.  You will find the basic widgets in the files widget.c.
130 Some more high-level functions, e.g. to display a message box, are
131 located in wtools.c.  This file also contains the Quick Dialog code,
132 which makes it easier to create complex dialogs.
134 Files findme.c, popt.c, poptconfig.c, popthelp.c and poptparse.c come
135 from the popt library used to parse the command line.  They should not
136 be modified unless absolutely necessary. At near time these stuff will
137 removed.
139 The files util.c and utilunix.c have a lot of utility functions.  Get
140 familiar with them, they are very simple.
142 glib is used for memory allocation and for some utility functions, such
143 as manipulation with lists and trees.  gmodule (part of the glib
144 distribution) is used to load some libraries dynamically at the run
145 time.
147 Thanks to glib, the code has almost no hardcoded limits, since there are
148 many ways to avoid them.  For example, when you want to concatenate
149 strings, use the g_strconcat() function:
151         new_text = g_strconcat (username, " ", password, (char *)0);
153 This allocates new memory for the string, so you should use g_free() on
154 the result.
156 The parent of all dialogs is called midnight_dlg.  Both panels are
157 widgets in that dialog.  Other widgets include the menu, the command
158 line and the button bar.
161 Input handling
162 ==============
164 The routines for input handling on the Midnight Commander are:
165 getch, get_key_code, mi_getch and get_event.
167 getch is an interface to the low level system input mechanism.  It
168 does not deal with the mouse.  
170     In the case of ncurses, this is a function implemented in the
171     ncurses library that translates key sequences to key codes (\E[A to
172     something like KEY_UP and so on).
174     In the case of S-Lang there is no such conversion, that's why we
175     load a set of extra definitions.
177 The get_key_code routine converts the data from getch to the
178 constants the Midnight Commander uses.
180     In the case of S-Lang, it will actually do all the jobs that getch
181     does for curses.  In the case of curses it patches a couple of
182     sequences that are not available on some terminal databases.  This
183     routine is the one you want to use if you want a character without
184     the mouse support.
186 get_event is the routine you want to use if you want to handle mouse
187 events, it will return 0 on a mouse event, -1 if no input is available
188 or a key code if there is some input available.  This routine in turn
189 uses get_key_code to decode the input stream and convert it to useful
190 constants.
192 mi_getch is just a wrapper around get_event that ignores all the mouse
193 events.  It's used only in a couple of places, this routine may return
194 -1 if no input is available (if you have set the nodelay option of
195 ncurses or S-Lang with nodelay) or a character code if no such option is
196 available. 
199 Mouse support
200 =============
202 The mouse support in the Midnight Commander is based on the get_event
203 routine.  The core of the mouse event dispatching is in the
204 dlg.c:run_dlg routine.
207 ncurses
208 =======
210 Although S-Lang is now used by default, we still support ncurses.  We
211 basically are using a small subset of ncurses because we want to be
212 compatible with Slang.
215 The Dialog manager and the Widgets
216 ==================================
218 The Dialog manager and the Widget structure are implemented in
219 src/dialog.c.  Everything shown on screen is a dialog.  Dialogs contain
220 widgets, but not everything on screen is a widget.  Dialogs can draw
221 themselves.
223 Dialogs are connected into a singly linked list using "parent" field. 
224 Currently active dialog is saved in current_dlg variable.  The toplevel
225 dialog has parent NULL.  Usually it's midnight_dlg.
227             parent                  parent
228 current_dlg ------->another dialog-- ... -->midnight_dlg
230 When the screen needs to be refreshed, every dialog asks its parent to
231 refresh first, and then refreshes itself.
233 A dialog is created by create_dlg().  Then it's populated by widgets
234 using add_widget().  Then the dialog is run by calling run_dlg(), which
235 returns the id of the button selected by the user.  Finally, the dialog
236 is destroyed by calling destroy_dlg().
238 Widgets are placed to a doubly linked circular list.  Each widget has
239 previous and next widget.
241         prev   next         prev   next
242 widget1 <---------> widget2 <---------> widget3
243    ^                                       ^
244    -----------------------------------------
245    next                                 prev
247 Pressing Tab moves focus to the "next" widget, pressing Shift-Tab moves
248 focus to "prev".  The tab order is equal to the add order except some
249 old code that use the reverse order by setting DLG_REVERSE flag in
250 create_dlg() call.  Please don't use reverse order in the new code.
252 The initial widget to get focus can be selected by calling
253 dlg_select_widget().
255 When creating a dialog, you may want to use a callback that would
256 intercept some dialog events.  However, many widgets will do the right
257 thing by default, so some dialogs can work just fine without callbacks.
259 There are also widget events, which are sent by the dialog to individual
260 widgets.  Some widgets also have user callbacks.
262 To create your own widget, use init_widget().  In this case, you must
263 provide a callback function.  Please note that it's not the same as the
264 user callback in some widgets.
267 Where to Find Bug Reports and Patches
268 =====================================
270 The official place for bug reports is:
272     http://www.midnight-commander.org/
275 There are various unofficial sources where bug reports and patches can
276 be found (NOT maintained by the MC team).
279 http://bugs.debian.org/mc
280         The bug tracking system for Debian, a package collection mainly
281         for GNU/Linux and the Hurd.
283 http://bugzilla.redhat.com/bugzilla/buglist.cgi?component=mc
284         Bugs reported in Redhat Linux.
286 http://www.openbsd.org/cgi-bin/cvsweb/ports/misc/mc/patches/
287         The patches that are applied for the OpenBSD version of MC.
289 http://www.freebsd.org/cgi/cvsweb.cgi/ports/misc/mc/files/
290         The patches that are applied for the FreeBSD version of MC.
292 http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/mc/patches/
293         The patches that are applied for the NetBSD version of MC.
295 http://www.gentoo.org/cgi-bin/viewcvs.cgi/app-misc/mc/files/?hideattic=1
296         The patches that are applied for the Gentoo Linux version of MC.
299 Programming Tips
300 ================
302 (This list should be sorted alphabetically.)
304 ?: This operator has a precedence that is easy to use the wrong way. You
305         might think that
307                 int right = 25 + have_frame() ? 1 : 0; /* WRONG */
309         results in either 25 or 26. This is not the case. The C compiler
310         sees this as:
312                 int right = (25 + have_frame()) ? 1 : 0; /* WRONG */
314         To avoid this, put the ?: in parentheses, like this
316                 int right = 25 + (have_frame() ? 1 : 0); /* RIGHT */
318         If the condition is more complicated, put it in additional
319         parentheses:
321                 int right = 25 + ((have_frame()) ? 1 : 0); /* RIGHT */
323 const: For every function taking a string argument, decide whether you
324         (as a user of the function) would expect that the string is modi-
325         fied by the function. If not, declare the string argument as
326         "const char *". If your implementation needs to modify the string,
327         use g_strdup to create a local copy.
329 const_cast: Has been replaced by str_unconst.
331 g_free: g_free handles NULL argument too, no need for the comparison.
332         Bad way:
333             if (old_dir) g_free (old_dir);
334         Right way:
335             g_free (old_dir);
337 g_strdup: When you use g_strdup to create a local copy of a string, use
338         the following pattern to keep the reference.
340         char * const pathref = g_strdup(argument);
341         /* ... */
342         g_free (pathref);
344         The "const" will make the pointer unmodifiable (pathref++
345         is not possible), but you can still modify the string contents.
346         
347 g_strlcpy: Whenever you use this function, be sure to add "glibcompat.h"
348         to the included headers. This is because in glib-1.2 there is
349         no such function.
351 NULL: When you pass NULL as an argument of a varargs function, cast the
352         0 to the appropriate data type. If a system #defines NULL to
353         be 0 (at least NetBSD and OpenBSD do), and the sizes of int and
354         a pointer are different, the argument will be passed as int 0,
355         not as a pointer.
357         This tip applies at least to catstrs (edit/edit.h), execl(3),
358         execle(3), execlp(3), g_strconcat (glib), parent_call
359         (src/background.h), parent_call_string (src/background.h),
360         rpc_get (vfs/mcfsutil.h), rpc_send (vfs/mcfsutil.h).
362         example:
363         char *path = g_strconcat("dir", "/", "file", (char *)0);
365 size_t: This data type is suitable for expressing sizes of memory or the
366         length of strings. This type is unsigned, so you need not check
367         if the value is >= 0.
369 strncpy: Don't use this function in newly created code. It is slow, insecure
370         and hard to use. A much better alternative is g_strlcpy (see there).
372 str_unconst: We use many libraries that do not know about "const char *"
373         and thus declare their functions to require "char *". If you
374         know for sure that an external function does not modify the
375         string, you can "unconst" a string using the function
376         str_unconst(). If you are not sure whether the function modifies
377         the string, you should use g_strdup() to pass a copy of a string
378         to the function. Don't forget to call g_free() after work is done.
380 unused: Unused arguments of a function can be marked like this:
382         void do_nothing(int data)
383         {
384             (void) &data;
385         }
387         This tells the GNU C Compiler not to emit a warning, and has no
388         side effects for other compilers.