The eLua coding style
This section presents the eLua coding style that should be followed by every developer working on eLua. The following rules apply:
- Everything should be spaced out properly. Examples (please note the spacing rules, which is basically "space out everything for readability"):
i = 3 (not i=3) a = ( a + 5 ) / 3 for( i = 0; i < 10; i ++ ) ... if( ( i == 5 ) && ( a == 10 ) ) ... unsigned i = ( unsigned )p; void func( int arg1, const char* arg2 ) ...
- Indentation: indent everything at 2 SPACES. Again, SPACES. DO NOT USE TABS; this is important (and fortunately pretty easy to remember :) ).
There are too many examples where tabs completely destroyed the readability of source code. Most editors have an "insert tabs instead of spaces" option;
use it, and set your "tab size" to 2.
Also, indent "{" and "}" on their own lines:
Or:if( i == 2 ) { // some code here } else { // some other code here }
Do not enclose single statements in {} when given a choice. For example, do this:void f( int i ) { // function code }
instead of this:if( i == 2 ) return;
Also, follow the "one statement per line" rule. In other words, don't do this:if( i == 2 ) { return; }
Do this instead:if( i == 2 ) return;
Note that eLua code does not use a space between the function name and its parameter list when calling/defining it (like in the Lua code, for example). So do this:if( i == 2 ) return;
instead of this:void f( int i ) { // function code here } f( 2 ); // function call
void f ( int i ) { // function code here } f ( 2 ); // function call
- line terminators: THIS IS IMPORTANT! Use UNIX style (LF) line terminators, not DOS (CR/LF) or old Mac (CR) line terminators.
- identifier names: use a "GNU-style" here, with underlines and all lowercase:
As opposed to:int simple; double another_identifier; char yes_this_is_OK_although_quite_stupid;
int Simple1; double AnotherIdentifier; char DontEvenThinkAboutWritingSomethingLikeThis;
- DO NOT USE HUNGARIAN NOTATION (like iNumber, sString, fFloat ... if you don't know what that is, it's fine, as it means that we don't need to worry about it :) ). It has its advantages when used properly, it's just not for eLua.
- constants in code: don't ever write something like this:
Instead, define some constants with meaningful names (via enums or even #define) and write like this:if( key == 10 ) sys_ok(); else if( key == 5 ) phone_dial( "911" ); else if( key == 666 ) { while( user_is_evil() ) exorcize_user(); } else if( key == 0 ) sys_retry(); else sys_error();
You can see in this example an accepted violation of the "one statement per line" rule: it's OK to write "else if (newcondition)" on the same line.if( key == KEY_CODE_OK ) sys_ok(); else if( key == KEY_CODE_FATAL_ERROR ) phone_dial( "911" ); else if( key == KEY_CODE_COMPLETELY_EVIL ) { while( user_is_evil() ) exorcize_user(); } else if( key == KEY_CODE_NONE ) sys_retry(); else sys_error();
- use specific data types as much as possible. In this context, specific data types refers to generic types that have the same size on all
platforms. They are defined by each platform in turn and their meaning is given below:
- s8: signed 8-bit integer
- u8: unsigned 8-bit integer
- s16: signed 16-bit integer
- u16: unsigned 16-bit integer
- s32: signed 32-bit integer
- u32: unsigned 32-bit integer
- s64: signed 64-bit integer
- u64: unsigned 64-bit integer
- endianness: remember that eLua runs on both little endian and big endian architectures, and write your code accordingly.
- comments: we generally favor C++ style comments (//), but it's perfectly OK to use C style (/**/) comments. Automatic documentation generators like Doxygen aren't encouraged, since
they tend to make the programmer over-document the code to the point where it becomes hard to read because of the documentation alone. Ideally, you'd neither over-document, nor
under-document your code; just document it as much as you think it's needed, without getting into too much details, but also without omitting important information. In particular, DON'T do this:
When something is self-obvious from the context, documenting it more is pointless and decreases readability.// This function returns the sum of two numbers // Input: n1 - first number // Input: n2 - the second number // Output: the sum of n1 and n2 int sum( int n1, int n2 ) { return n1 + n2; }
- pseudo name-spaces: since we don't have namespaces in C, I like to "emulate" them by prefixing anything (constants, variables, functions) in a file with something that identifies that
file uniquely (most likely its name, but this is not a definite rule). For example, a file called "uart.c" would look like this:
int uart_tx_count, uart_rx_count; int uart_receive( unsigned limit )... unsigned uart_send( const char *buf, unsigned size )...
Also, if you're using 3rd party code (from a library/support package for example) making it follow the above rules is nice, but not mandatory. Focus on functionality and writing your own code properly, and come back to indent other people's code when you really don't have anything better to do with your time.