Sphinx coding standard ======================= WARNING. This document is just an internal note. It might or might not be in sync with the actual code. Use it as an overview; refer to the source for precise details. General -------- This document describes C++ coding standard that MUST be used for Sphinx source code. It is not yet complete. Currently, we're not aiming for an exhaustive set of rules (that noone will read anyway). Rather, we're covering only those gray areas that are not immediately obvious from the source. However, you should also *first* refer to the source for general look and feel. Certain rules might change over time. However, the following rules are not going to be changed: - All source parts must look alike. - When in doubt, ask. If not answered, mimic. (And ask again.) 1. General formatting rules ---------------------------- - No duplicate spaces, use tabs. - Indent is 1 tab. - Tab size is 4. 2. Formatting C++ clauses -------------------------- 2.1. Enumeration ----------------- enum ESphExample { FIRST = mandatory_value, SECOND, THIRD, FOURTH }; 2.2. Switch statement ---------------------- switch ( tMyCondition ) { case FIRST: iShortStatement = 1; break; case SECOND: iAnotherShortStatement = 2; break; case THIRD: iLongerStatement = 3; DoSomething(); break; case FOURTH: { int iEvenLongerStatementWithLocals = 4; DoSomethingElse(); break; } } 2.3. Parentheses ----------------- - 1 space around opening '('. - 1 space before closing ')'. - Empty argument lists in function calls can omit spaces. - Short 1-argument lists can omit spaces too. TypicalCall ( iFirst, sSecond ); NullArglist(); ShortArglist(i); StillShortArglist(iIdx); LongEnoughArglist ( iFirst ); iVar = !( iCode & BOOLEAN_EXPRESSION ); if ( i==1 || ( j==2 && k==3 ) ) { ... } if ( i ) {... } 2.4. Class declaration layout ------------------------------ - Usually, variables go first, then functions. - Usually, public members go first, then protected, then private. - Repeat access specifier to highlight big blocks of members. - All the rules above are not mandatory, but generally suggested. class SampleClass { public: SampleClass (); ~SampleClass (); void DoThings (); protected: int m_iLocalState; bool m_bSomeFlag; protected: int m_iAnotherLogicalBlock; int m_iOfMemberVariables; protected: void Helper1(); void Helper2(); }; 3. Naming conventions ---------------------- - Camel case, and reasonable subset of Hungarian notation. - Identifiers are "MultiWordName", not "multi_word_name" (this is CamelCase). - "m_" prefix on data members is mandatory (this is Hungarian). - Single-char typeid prefix on variables is mandatory (this is Hungarian). - "i" means int - "u" means unsigned - "b" means boolean - "c" means char - "f" means float - "p" means pointer - "pp" means pointer to pointer - "s" means string (both CSphString and char *) - "e" means enum - "d" means array (no idea why "d", maybe "data"?) - "t" means any other (complex) type - No special rules for public/protected/private member names. - Special rules for entities exposed in sphinx.h to libsphinx callers: - Enum names MUST start with "ESph" - Interface names MUST start with "ISph" - Class/struct names MUST start with "CSph" - Function names MUST start with "sph" - Internal entities can either use or omit these prefixes. class SampleInternalClass { int m_iSomething; // right, got both "m_" prefix and "i" typeid char iAnotherthing; // WRONG, bad typeid char, bad capitalization long m_AnotherField; // WRONG, missing typeid char char * m_lpszWtf; // WRONG, typeid must be single char (or "pp") ... /// right void SampleCall ( RuleType_e eRule, char cKey, bool bFlag, char * sArg ); }; - constants, either typed or defined, must be all caps: const bool FAIL_ON_NULL_SOURCE = false; #define READ_NO_SIZE_HINT 0 --eof--