Coding Guidelines
From WinMerge Development Wiki
These are not strict rules we enforce. But following these guidelines keeps code consistent and easier for everybdy to work with.
Contents |
[edit] Prefer Clean Code
Avoid unnecessary tricks! Simple and easy to read code is usually best, tricks are rarely really needed. C++ allows all kinds of really ugly constructs, think twice if you really need them.
If you find a code that you think could be improved, please submit a patch.
[edit] Code Formatting
Some formatting guidelines:
- use tabs to indent the code
- try to limit lines to 80 chars (for printing etc)
- put braces in own lines, and don't indent them
- you can leave braces out if there would be only one instruction inside, and code is easy to understand
- surround operators with spaces
- function, class, struct names begin with capital letter
- variable name begins with small letter
- in MFC code (GUI code), class member names start with
m_, though other code should use this convention too
int ExampleFunction(int param1) { int retval = 0; for (int i = 0; i < 10; i++) { retval += 10; // Some other code... } if (retval < 100) printf("Didn't reach 100..."); return retval; }
[edit] Debug Code
Always put debug-only code inside _DEBUG ifdef!
// some code... #ifdef _DEBUG // code for debugging only #endif // _DEBUG
There are lots of ready macros and CRT (C-runtime) functions to use for debugging. Please don't re-invent the wheel, use the existing facilities. In (MFC) GUI code ASSERT() -macro is the most used debug macro. It is a good way to make simple verifications. Another useful MFC macro is VERIFY(). If you want to print to output window in Visual Studio, use MFC TRACE() macro.
In non-MFC code there are CRT macros like _ASSERT, _ASSERTE and _RPTFx.
Be careful to not add any functional code inside debug macros! Debug macros should only check for variable/class states, they must not alter variables or class state. Otherwise the code behaves differently in debug builds and in release builds, and makes finding bugs harder.
[edit] Comments
Please always comment your code. Even if the code is obvious when you write it, it may be hard to understand for others. And it may be hard to understand for you after few months.
Do:
- comment every function, class, struct etc with Doxygen comments
- answer the Why not What?. I.e. explain why something is done, not what you are doing (code tells it).
- keep the comments up-to-date. When you change the code, update also comments.
Don't:
- add comments with your name telling you changed something. We have a version control, so we see from version control who changed what. It is just unnecessary noise.
- leave old version of code in comments. Remove old code. We have a version control and we changes and earlier versions from it.
- be overly verbose.
[edit] Revision Keyword Comment
Although $Id: keyword was originally used with CVS, it also works with SVN.
So every source file should have following two lines in begin of them (you can use this as template):
// ID line follows -- this is updated by SVN // $Id: $
When file is checked out from SVN, lines look like:
// ID line follows -- this is updated by SVN // $Id: MainFrm.cpp 4375 2007-07-20 17:27:33Z kimmov $
There are lots of old-style comments mentioning CVS, please update them when modifying files.
[edit] License
WinMerge is GPL licensed. So all the pros and cons of the GPL apply to WinMerge.
Be careful that the code is properly licensed. After all, the proper licensing is the only way to protect our work from abusing it.
The basic rule is simple: if you modify sources, compile them and distribute binaries, you must make modified sources available also. Even if it was just for testing some new bugfix or feature.
Of course we'd prefer you to submit a patch for us at the first place. Eventually the patch will be included into next experimental release, which gets downloaded and tested by hundreds of users.
[edit] License Compatibility
When you are adding new code, please prefer licensing it under GPL. That is the easiest solution for all of us.
However, there are perfectly valid reasons for you to use some other license. And we can accept that. Just make sure that the other license you use is compatible with GPL! See License list for more information.
Even more importantly, when you are grabbing code elsewhere, be sure it is compatible with GPL before submitting it to us. E.g. Mozilla Org's MPL is not compatible and hence we cannot use MPL-licensed code in WinMerge.
[edit] License Block
Every source code file should have a GPL license block at the beginning of the file. That is best way to ensure people understand the code they look at and/or modify is GPL licensed.
If you are adding code that is not GPL-licensed, be sure to include proper license block to the beginning of the file. Otherwise the code gets converted to GPL license!
[edit] Unicode
Please remember always that WinMerge is an Unicode application. Mostly this is visible in code when handling strings:
- strings can be in UCS-2 (Windows native format) or UTF-8
- most of the time UCS-2 is recommended
- UTF-8 is used with XML handling, PCRE and when sending file data to diffutils
- use CString, String or TCHAR for strings.
- prefer String (from
Common/UnicodeString.h) for non-GUI code instead of CString. - don't use char type when using UCS-2 strings, it is always a bug. char can be only used with UTF-8.
- prefer String (from
- don't use strcpy(), itoa() etc. There are macros which use TCHAR: _tcscpy(), _itot() etc.
- when calculating string table size, remember to use sizeof(TCHAR) as multiplier (tells size of one character in bytes). Unicode strings take two bytes per character.
- when adding a string to the code, put the string inside _T() -macro (for example:
_T("Hello")). The macro converts the string to Unicode string.
[edit] MFC / STL / WinAPI
There are several frameworks / APIs used in WinMerge. What framework and API to use depends on the what part of the code you are working with.
[edit] GUI code
WinMerge's GUI is based on MFC. We use MFC view/document classes, containers etc. There is no way around this, you must know MFC to work with WinMerge GUI. With GUI it is best to use MFC classes instead of other libraries (like STL).
[edit] Other Code
Most of the backend code (file handling etc) do not need any of MFC. There pure WinAPI and STL are recommended.
The reason is MFC, while being a nice framework, seriously limits people's ability to work with WinMerge code. Compiling requires a commercial version of Visual Studio (free versions don't include MFC!).
[edit] Strings
There is a String class (defined in Common/UnicodeString.h) which is typedef of std::string for ANSI and std::wstring for Unicode targets. So using it is like using std::string except the name:
#include "UnicodeString.h" void myfunc() { String first(_T("Hello")); String second(_T(" world!")); String message = first + second; }
String should be used in non-GUI code instead of MFC CString!
[edit] Translated Application
Remember WinMerge is translated to several languages. For translation system to work, every user visible string and resource must be loaded from the resource file. This means strings, menus, dialogs etc.
Never add strings or menu/button labels directly into the code.
See Translation System for more information.

