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