Fixed also some outdated informations in doc/HACKING
[midnight-commander.git] / doc / HACKING
blobf6aa70794421cb93c8d8e56e16512eeaff03e676
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.x and above
24 It is recommended that all those tools are installed with the same
25 prefix.  Make sure that the tools with the right version are first in
26 PATH.
28 Once you have the right tools, run `autogen.sh' - it will generate
29 everything necessary for the build and run `configure'.  Arguments given
30 to `autogen.sh' are passed to `configure'.  Then run `make' as usually.
32 The distribution tarball is created by the command `make distcheck'. 
33 This command can take a while.
35 Currently snapshots are made on Debian unstable and use the versions of
36 the tools from the unstable repository.  Yes, the rpm packages are made
37 on Debian too.
39 Note that the version of gettext doesn't affect the snapshot because the
40 distributed files are installed by gettext from archives for the version
41 used in the AM_GNU_GETTEXT_VERSION macro, which is 0.11.5.
45 Working with GNU Midnight Commander
46 ===================================
48 Please use the GIT version.  It may be quite different from the released
49 versions.  A lot of cleanup is going on.  The GIT version may be easier
50 to understand, in addition to the obvious fact that the merging is
51 easier with the GIT version.
53 There are some tools in the maint directory on GIT.  They are not
54 included with releases or snapshots.  You may be interested to look at
55 them if you are going to work on the project for an extended period of
56 time.  In particular, the release procedure is described there.
58 In order to compile GNU Midnight Commander from a clean GIT checkout you
59 should use autogen.sh instead of configure.  Arguments passed to
60 autogen.sh are passed to configure after it's generated.
62 GNU Midnight Commander uses Autoconf and Automake, with make it fairly
63 portable.  However, GNU Make is strongly recommended for development
64 because other versions of make may not track dependencies properly. 
65 This is very important for correct compilation, especially if you change
66 any header files.
68 If you add or remove any files, please change Makefile.am in the same
69 directory accordingly.  When doing significant changes in the tree
70 structure, "make distcheck" is strongly recommended.
72 If you have etags installed, you can run "make tags" and use tags in
73 emacs to find functions or variables.  But you can also use the internal
74 editor and the "Find File" command to find any text in the source tree.
76 GNU Autoconf allows you to test several different configurations are
77 once.  To do so, use the so called out-of-tree (or VPATH) compilation. 
78 Create separate empty directories and run configure with full path from
79 those directories, like this:
81 cd /usr/local/src
82 mkdir mc-slang
83 mkdir mc-ncurses
84 cd mc-slang
85 /usr/local/src/mc/configure && make all
86 cd ../mc-ncurses
87 /usr/local/src/mc/configure --with-screen=ncurses && make all
89 Please use the same indentation as other developers.  To indent a block,
90 select in the internal editor and use Shift-F9 to call the external
91 indent.  For historic reasons, GNU Midnight Commander used formatting
92 that is not default for GNU Indent.  Please put following text to your
93 ~/.indent.pro file to make GNU Indent follow the style used in GNU
94 Midnight Commander:
96 -kr -i4 -pcs -psl --ignore-newlines
98 It's OK to indent the whole function if you edit it.  However, please
99 refrain from it if you are posting your patch for review.  In this case
100 you would save time of other developers if you only include significant
101 changes.  The developer applying your patch can format the code for you.
103 Please keep in mind that the VFS subsystem is licensed under LGPL, while
104 the rest of the code uses GPL.
107 Code structure - outline
108 ========================
110 The code is located in following directories.
112 vfs - Virtual File System.
114 This library provides filesystem-like access to various data, such are
115 archives and remote filesystems.  To use VFS, you should use wrappers
116 around POSIX calls.  The wrappers have names composed from "mc_" and the
117 standard name of the function.  For example, to open a file on VFS, use
118 mc_open() instead.
120 edit - the internal editor.
122 This code has been contributed by Paul Sheer, the author of Cooledit. 
123 The internal editor shares some code with Cooledit, but now it's
124 developed as part of GNU Midnight Commander.
126 src - the main part of the code.
128 This code includes the dialog manager written by Radek Doulik and source
129 code of the main application.
131 Code structure - details
132 ========================
134 GNU Midnight Commander uses extensively the dialog manager written by
135 Radek Doulik.  To understand how the dialog manager works, please read
136 the dialog.c.  You will find the basic widgets in the files widget.c. 
137 Some more high-level functions, e.g. to display a message box, are
138 located in wtools.c.  This file also contains the Quick Dialog code,
139 which makes it easier to create complex dialogs.
141 Files findme.c, popt.c, poptconfig.c, popthelp.c and poptparse.c come
142 from the popt library used to parse the command line.  They should not
143 be modified unless absolutely necessary.
145 The files util.c and utilunix.c have a lot of utility functions.  Get
146 familiar with them, they are very simple. 
148 glib is used for memory allocation and for some utility functions, such
149 as manipulation with lists and trees.  gmodule (part of the glib
150 distribution) is used to load some libraries dynamically at the run
151 time.
153 Thanks to glib, the code has almost no hardcoded limits, since there are
154 many ways to avoid them.  For example, when you want to concatenate
155 strings, use the g_strconcat() function:
157         new_text = g_strconcat (username, " ", password, (char *)0);
159 This allocates new memory for the string, so you should use g_free() on
160 the result.
162 The parent of all dialogs is called midnight_dlg.  Both panels are
163 widgets in that dialog.  Other widgets include the menu, the command
164 line and the button bar.
167 Input handling
168 ==============
170 The routines for input handling on the Midnight Commander are:
171 getch, get_key_code, mi_getch and get_event.
173 getch is an interface to the low level system input mechanism.  It
174 does not deal with the mouse.  
176     In the case of ncurses, this is a function implemented in the
177     ncurses library that translates key sequences to key codes (\E[A to
178     something like KEY_UP and so on).
180     In the case of S-Lang there is no such conversion, that's why we
181     load a set of extra definitions.
183 The get_key_code routine converts the data from getch to the
184 constants the Midnight Commander uses.
186     In the case of S-Lang, it will actually do all the jobs that getch
187     does for curses.  In the case of curses it patches a couple of
188     sequences that are not available on some terminal databases.  This
189     routine is the one you want to use if you want a character without
190     the mouse support.
192 get_event is the routine you want to use if you want to handle mouse
193 events, it will return 0 on a mouse event, -1 if no input is available
194 or a key code if there is some input available.  This routine in turn
195 uses get_key_code to decode the input stream and convert it to useful
196 constants.
198 mi_getch is just a wrapper around get_event that ignores all the mouse
199 events.  It's used only in a couple of places, this routine may return
200 -1 if no input is available (if you have set the nodelay option of
201 ncurses or S-Lang with nodelay) or a character code if no such option is
202 available. 
205 Mouse support
206 =============
208 The mouse support in the Midnight Commander is based on the get_event
209 routine.  The core of the mouse event dispatching is in the
210 dlg.c:run_dlg routine.
213 ncurses
214 =======
216 Although S-Lang is now used by default, we still support ncurses.  We
217 basically are using a small subset of ncurses because we want to be
218 compatible with Slang.
221 The Dialog manager and the Widgets
222 ==================================
224 The Dialog manager and the Widget structure are implemented in
225 src/dialog.c.  Everything shown on screen is a dialog.  Dialogs contain
226 widgets, but not everything on screen is a widget.  Dialogs can draw
227 themselves.
229 Dialogs are connected into a singly linked list using "parent" field. 
230 Currently active dialog is saved in current_dlg variable.  The toplevel
231 dialog has parent NULL.  Usually it's midnight_dlg.
233             parent                  parent
234 current_dlg ------->another dialog-- ... -->midnight_dlg
236 When the screen needs to be refreshed, every dialog asks its parent to
237 refresh first, and then refreshes itself.
239 A dialog is created by create_dlg().  Then it's populated by widgets
240 using add_widget().  Then the dialog is run by calling run_dlg(), which
241 returns the id of the button selected by the user.  Finally, the dialog
242 is destroyed by calling destroy_dlg().
244 Widgets are placed to a doubly linked circular list.  Each widget has
245 previous and next widget.
247         prev   next         prev   next
248 widget1 <---------> widget2 <---------> widget3
249    ^                                       ^
250    -----------------------------------------
251    next                                 prev
253 Pressing Tab moves focus to the "next" widget, pressing Shift-Tab moves
254 focus to "prev".  The tab order is equal to the add order except some
255 old code that use the reverse order by setting DLG_REVERSE flag in
256 create_dlg() call.  Please don't use reverse order in the new code.
258 The initial widget to get focus can be selected by calling
259 dlg_select_widget().
261 When creating a dialog, you may want to use a callback that would
262 intercept some dialog events.  However, many widgets will do the right
263 thing by default, so some dialogs can work just fine without callbacks.
265 There are also widget events, which are sent by the dialog to individual
266 widgets.  Some widgets also have user callbacks.
268 To create your own widget, use init_widget().  In this case, you must
269 provide a callback function.  Please note that it's not the same as the
270 user callback in some widgets.
273 Where to Find Bug Reports and Patches
274 =====================================
276 The official place for bug reports is:
278     http://www.midnight-commander.org/
281 There are various unofficial sources where bug reports and patches can 
282 be found (NOT maintained by the MC team).
285 http://bugs.debian.org/mc
286         The bug tracking system for Debian, a package collection mainly
287         for GNU/Linux and the Hurd.
289 http://bugzilla.redhat.com/bugzilla/buglist.cgi?component=mc
290         Bugs reported in Redhat Linux.
292 http://www.openbsd.org/cgi-bin/cvsweb/ports/misc/mc/patches/
293         The patches that are applied for the OpenBSD version of MC.
295 http://www.freebsd.org/cgi/cvsweb.cgi/ports/misc/mc/files/
296         The patches that are applied for the FreeBSD version of MC.
298 http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/mc/patches/
299         The patches that are applied for the NetBSD version of MC.
301 http://www.gentoo.org/cgi-bin/viewcvs.cgi/app-misc/mc/files/?hideattic=1
302         The patches that are applied for the Gentoo Linux version of MC.
305 Programming Tips
306 ================
308 (This list should be sorted alphabetically.)
310 ?: This operator has a precedence that is easy to use the wrong way. You
311         might think that
313                 int right = 25 + have_frame() ? 1 : 0; /* WRONG */
315         results in either 25 or 26. This is not the case. The C compiler
316         sees this as:
318                 int right = (25 + have_frame()) ? 1 : 0; /* WRONG */
320         To avoid this, put the ?: in parentheses, like this
322                 int right = 25 + (have_frame() ? 1 : 0); /* RIGHT */
324         If the condition is more complicated, put it in additional
325         parentheses:
327                 int right = 25 + ((have_frame()) ? 1 : 0); /* RIGHT */
329 const: For every function taking a string argument, decide whether you
330         (as a user of the function) would expect that the string is modi-
331         fied by the function. If not, declare the string argument as
332         "const char *". If your implementation needs to modify the string,
333         use g_strdup to create a local copy.
335 const_cast: Has been replaced by str_unconst.
337 g_free: g_free handles NULL argument too, no need for the comparison.
338         Bad way:
339             if (old_dir) g_free (old_dir);
340         Right way:
341             g_free (old_dir);
343 g_strdup: When you use g_strdup to create a local copy of a string, use
344         the following pattern to keep the reference.
346         char * const pathref = g_strdup(argument);
347         /* ... */
348         g_free (pathref);
350         The "const" will make the pointer unmodifiable (pathref++
351         is not possible), but you can still modify the string contents.
352         
353 g_strlcpy: Whenever you use this function, be sure to add "glibcompat.h"
354         to the included headers. This is because in glib-1.2 there is
355         no such function.
357 NULL: When you pass NULL as an argument of a varargs function, cast the
358         0 to the appropriate data type. If a system #defines NULL to
359         be 0 (at least NetBSD and OpenBSD do), and the sizes of int and
360         a pointer are different, the argument will be passed as int 0,
361         not as a pointer.
363         This tip applies at least to catstrs (edit/edit.h), execl(3),
364         execle(3), execlp(3), g_strconcat (glib), parent_call
365         (src/background.h), parent_call_string (src/background.h),
366         rpc_get (vfs/mcfsutil.h), rpc_send (vfs/mcfsutil.h).
368         example:
369         char *path = g_strconcat("dir", "/", "file", (char *)0);
371 size_t: This data type is suitable for expressing sizes of memory or the
372         length of strings. This type is unsigned, so you need not check
373         if the value is >= 0.
375 strncpy: Don't use this function in newly created code. It is slow, insecure
376         and hard to use. A much better alternative is g_strlcpy (see there).
378 str_unconst: We use many libraries that do not know about "const char *"
379         and thus declare their functions to require "char *". If you
380         know for sure that an external function does not modify the
381         string, you can "unconst" a string using the function
382         str_unconst(). If you are not sure whether the function modifies
383         the string, you should use g_strdup() to pass a copy of a string
384         to the function. Don't forget to call g_free() after work is done.
386 unused: Unused arguments of a function can be marked like this:
388         void do_nothing(int data)
389         {
390             (void) &data;
391         }
393         This tells the GNU C Compiler not to emit a warning, and has no
394         side effects for other compilers.