Magic Lantern Firmware Wiki
Advertisement

Common sense: try to stay close to the coding style from the existing repository.

Whitespace[]

ML indents are four spaces. Tabs are never used, except in Makefiles where they have been irreversibly coded into the syntax.

Do not leave whitespace dangling off the ends of lines.


Line width[]

Lines are 80 characters; not longer.

[g3gg0 proposed 160; a lot of ML code lines longer than 80 chars]

Line ending Style[]

Use Unix line ending style (LF).

Setup your text editor to use Unix line endings or use dos2unix-like software.

Comments[]

Prefer /* C90-style comments */

(take a look at g3gg0's code, he uses them very well)

Naming[]

Variables are lower_case_with_underscores.

Public functions should be prefixed, e.g. flexinfo_setup, raw_set_geometry, raw_get_pixel, menu_add. Same for global variables (use long descriptive names).

Use static for things that are not meant to be called from other source files or modules. Static stuff can have shorter names, as they are local to that source file.

If, for some reason, you can't make some private stuff static (e.g. calls between 2 source files), prefix these functions with _underscore. This way, they will not be included in the *.SYM files, so you can't call them by mistake from modules.

Block structure[]

a1ex following the Allman indent style (see http://en.wikipedia.org/wiki/Indent_style#Allman_style).

Here is an example:

   if (i < 4)
   {
       /* here we go again... */
       auto_ettr_wait_lv_frames(15);
   }
   else
   {
       /* or... not? */
       beep();
       NotifyBox(2000, "Whoops");
       goto end;
   }

You can use the Artistic Style software (http://astyle.sourceforge.net) to beautify your code according to the Allman style:

astyle --style=allman <file_name.c>

Breaking long lines[]

Preferred way to break long function calls:

   bmp_printf(
       FONT_MED,
       x, y,
       "PROP %8x: %d: %8x %8x %8x %8x\n"
       "'%s' ",
       prop,
       len,
       len > 0x00 ? data[0] : 0,
       len > 0x04 ? data[1] : 0,
       len > 0x08 ? data[2] : 0,
       len > 0x0c ? data[3] : 0,
       strlen((const char *) data) < 100 ? (const char *) data : ""
   );

or

       bmp_printf(
           FONT_MED,
           20, 450, "EDMAC state: "
       );
       bmp_printf(
           FONT(FONT_MED, COLOR_GRAY(50), COLOR_BLACK),
           20+200, 450, "inactive"
       );
       bmp_printf(
           FONT(FONT_MED, COLOR_GREEN1, COLOR_BLACK),
           20+350, 450, "running"
       );

but not aligned like this:

   bmp_printf(
              selected ? MENU_FONT_SEL : MENU_FONT,
              x, y,
              "Dump Live View Buffers"
              );

Also, multiline strings should be broken:

           bmp_printf(FONT_MED, 50, 50, 
               "Trying write channel [%d]...\n"
               "Press PLAY if not working", 
               i
           );

Structs[]

Preferred style: e.g. struct raw_info * info, struct tm tm. Don't use typedefs.

From Linux kernel coding style: It's a _mistake_ to use typedef for structures and pointers. [1]

Breaking code into features[]

Most ML code can be split into features (e.g. zebras, cropmarks, intervalometer), with the FEATURE_* macros, and you should be able to choose a subset of features (look in features.h files). This is necessary because not all features are working on all cameras, so you have an easy way to enable only what's working.

Be careful what you tag with FEATURE_*, as these things will end up here: http://nanomad.magiclantern.fm/nightly/features.html

All feature macros should appear in all_features.h (maybe commented out), so the HTML script will know where to place them in the table (in what menus).

If it's rather something related to backend (not a user-level feature that appears in menu), use CONFIG_* instead and place it in internals.h.

Consider implementing new features as loadable modules. In the long run, modules will probably replace the FEATURE tags completely, but right now we are not there yet.

Further reading[]

Advertisement