]> git.lyx.org Git - lyx.git/blobdiff - development/Code_rules/Rules
update aastex documentation; remove Mike Ressler's address
[lyx.git] / development / Code_rules / Rules
index 7e2ed08ab3b6342c382d70625070e65568801c67..2212a6140b025464f648328a8aa073d6c61eee05 100644 (file)
@@ -1,64 +1,67 @@
 Rules for the code in LyX
 -------------------------
-[updated from the C++STYLE distrubuted with the GNU C++ Standard]
+[updated from the C++STYLE distributed with the GNU C++ Standard]
 
 The aim of this file is to serve as a guide for the developers, to aid us to
-get clean and uniform code. This document is still uncomplete.
+get clean and uniform code. This document is still incomplete.
 
-We really like to have new developers joining the LyX Project. However
-since we have had problems in the past with developers leaving the
+We really like to have new developers joining the LyX Project. However,
+we have had problems in the past with developers leaving the
 project and their contributed code in a far from perfect state. Most
-of this happened before that we really became aware of these issues,
+of this happened before we really became aware of these issues,
 but still, we don't want it to happen again. So we have put together
 some guidelines and rules for the developers.
 
 General
 -------
 
-These guidelines should save us a lot of work while cleaning up the code and 
-help us to have quality code. LyX has been haunted by problems coming from 
-unfinished projects by people who have left the team. Those problems will 
+These guidelines should save us a lot of work while cleaning up the code and
+help us to have quality code. LyX has been haunted by problems coming from
+unfinished projects by people who have left the team. Those problems will
 hopefully disappear if the code is easy to hand over to somebody else.
 
-In general, if you want to contribute to the main source, we expect at least 
+In general, if you want to contribute to the main source, we expect at least
 that you:
 
 - the most important rule first: kiss (keep it simple stupid), always
-  use a simple implementation in favour of a more complicated one.
-  This eases maintenence a lot.
-- write good C++ code: Readable, well commented and taking advantage of the 
+  use a simple implementation in favor of a more complicated one.
+  This eases maintenance a lot.
+- write good C++ code: Readable, well commented and taking advantage of the
   OO model. Follow the formatting guidelines. See Formatting.
-- adapt the code to the structures already existing in LyX, or in case that 
-  you have better ideas, discuss them on the developer's list before writing 
-  the code.
+- adapt the code to the structures already existing in LyX, or in the case
+  that you have better ideas, discuss them on the developer's list before
+  writing the code.
 - take advantage of the C++ standard library. especially don't use
-  custom containers when a standard container is usable, learn to use
+  custom containers when a standard container is usable; learn to use
   the algorithms and functors in the standard library.
 - be aware of exceptions and write exception safe code. See Exceptions.
 - document all variables, methods, functions, classes etc. We are
-  using the source documentation program doc++, a program that handles
-  javadoc syntax, to document sources. See Source Documentation.
+  using the source documentation program doxygen, a program that handles
+  javadoc syntax, to document sources. You can download doxygen from :
+
+  http://www.stack.nl/~dimitri/doxygen/
+
 - we have certain code constructs that we try to follow. See Code
   Constructs.
 
 
-Submiting Code
-------------------
+Submitting Code
+---------------
 
 It is implicitly understood that all patches contributed to The LyX
-Project is under the Gnu General Public Lisence, it you have a problem
-with that, don't contribute code.
+Project is under the Gnu General Public License, version 2 or later.
+If you have a problem with that, don't contribute code.
 
-Also please don't just pup up out of the blue with a huge patch (or
+Also please don't just pop up out of the blue with a huge patch (or
 small) that changes something substantial in LyX. Always discuss your
-ideas with the developers on the developers mailinglist.
+ideas with the developers on the developer's mailing list.
 
 When you create the patch, please use "diff -up" since we find that a
 lot easier to read than the other diff formats. Also please do not
-send patches that implements/fix several different things, several
+send patches that implements or fixes several different things; several
 patches is a much better option.
 
-We also expect you to provide a ChangeLog entry with every patch, this
+We also require you to provide a ChangeLog entry with every patch, this
 describes shortly what the patch is doing. The ChangeLog entry follows
 this syntax:
 
@@ -66,25 +69,33 @@ this syntax:
 
        * src/support/lyxstring.C (find): assert bug fixed.
 
+Note that there are specific ChangeLogs for most directories; use those
+rather than the top-level one.
 
 Code Constructs
 ---------------
 
-We have several guidelines on code constructs, some of these exists to
+We have several guidelines on code constructs, some of these exist to
 make the code faster, others to make the code clearer. Yet others
-exists to make us able to take advantage of the strong type checking
+exist to allow us to take advantage of the strong type checking
 in C++.
-  
+
 - Declaration of variables should wait as long as possible. The rule
   is: "Don't declare it until you need it." In C++ there are a lot of
   user defined types, and these can very often be expensive to
   initialize. This rule connects to the next rule too.
 
+- declare the variable as const if you don't need to change it. This
+  applies to POD types like int as well as classes.
+
 - Make the scope of a variable as small as possible.
 
-- Prefere preincrement to postincrement whenever possible.
-  Preincrement has potential of beeing faster than postincrement. Just
-  thing about the obvious implementations of pre/post-increment. This
+- Make good use of namespaces. Prefer anonymous namespaces to declaring
+  "static" for file scope.
+
+- Prefer preincrement to postincrement whenever possible.
+  Preincrement has potential of being faster than postincrement. Just
+  think about the obvious implementations of pre/post-increment. This
   rule applies to decrement too.
 
        ++T;
@@ -97,7 +108,7 @@ in C++.
   aimed especially at loops.
 
        Container::iterator end = large.end();
-       for (Container::iterator it = large.begin(), it != end; ++it) {
+       for (Container::iterator it = large.begin(); it != end; ++it) {
                ...;
        }
        -NOT-
@@ -106,7 +117,7 @@ in C++.
                ...;
        }
 
-- For functions and metods that returns a non-POD type T, return T
+- For functions and methods that return a non-POD type T, return T
   const instead. This gives better type checking, and will give a
   compiler warning when temporaries are used wrongly.
 
@@ -114,64 +125,79 @@ in C++.
        -NOT-
        T add(...);
 
+- Avoid using the default cases in switch statements unless you have
+  too. Use the correct type for the switch expression and let the
+  compiler ensure that all cases are exhausted.
+
+       enum Foo {
+               foo,
+               bar
+       };
+       Foo f = ...;
+       switch (f) {
+       case foo: ...; break;
+       case bar: ...; break;
+       default: ...; break; // not needed and would shadow a wrong use of Foo
+       }
 
 Exceptions
 ----------
 
 Even if LyX currently is not using exceptions we need to be aware of
 them. One important thing to realize is that you often do not have to
-use throw,try or catch to be exception safe. Let's look at the
+use throw, try or catch to be exception safe. Let's look at the
 different types of exceptions safety: (These are taken from Herb
-Sutters book[ExC++]
+Sutter's book[ExC++]
 
 "
-1. Basic guarantee: Even in te presence of exceptions thrown by T or
-other exceptions, Stack objects don't leak resources.
+1. Basic guarantee: Even in the presence of exceptions thrown by T or
+       other exceptions, Stack objects don't leak resources.
        Note that this also implies that the container will be
-       destructible and usable even if an exception is thrown wile
+       destructible and usable even if an exception is thrown while
        performing some container operation. However, if an exception
        is thrown, the container will be in a consistent, but not
        necessarily predictable, state. Containers that support the
        basic guarantee can work safely in some settings.
 
 2. Strong guarantee: If an operation terminates because of an
-exception, program state will remain uncanged.
-       This always implies commit-or-rollback samantics, including
+       exception, program state will remain unchanged.
+       This always implies commit-or-rollback semantics, including
        that no references or iterators into the container be
        invalidated if an operation fails. For example, if a Stack
        client calls Top and then attempts a Push that fails because
        of an exception, then the state of the Stack object must be
        unchanged and the reference returned from the prior call to
-       Top must still be valid. For more information on there
+       Top must still be valid. For more information on these
        guarantees, see Dave Abrahams's documentation of the SGI
        exception-safe standard library adaption at:
-       http://www.metabyte.com/~fbp/stl/eg_contract.html 
 
-       Probably te most interesting point here is tat wen you
+       http://www.stlport.org/doc/exception_safety.html
+
+       Probably the most interesting point here is that when you
        implement the basic guarantee, the strong guarantee often
        comes for free. For example, in our Stack implementation,
-       alost everything we did was needed to satisfy just the basic
-       guarantee -- and wath's presented above very nearly satisfires
+       almost everything we did was needed to satisfy just the basic
+       guarantee -- and what's presented above very nearly satisfies
        the strong guarantee, with little of no extra work. Not half
        bad, considering all the trouble we went to.
 
-       In addition to tese two guarantees, there is one more
+       In addition to these two guarantees, there is one more
        guarantee that certain functions must provide in order to make
-       overall exception safety possible: 
+       overall exception safety possible:
 
-3. Nothrow guarantee: Te function will not emit an exception under any
-   circumstances.
+3. Nothrow guarantee: The function will not emit an exception under any
+       circumstances.
        Overall exception safety isn't possible unless certain
-       functions are guaranteed not to throw. In particualr, we've
-       seen that this is true for destructors; later in tis
+       functions are guaranteed not to throw. In particular, we've
+       seen that this is true for destructors; later in this
        miniseries, we'll see that it's also needed in certain helper
-       functions, such as Swap(). 
+       functions, such as Swap().
 "
 
 For all cases where we might be able to write exception safe functions
-without using try,throw or catch we should do so. In particular we
+without using try, throw or catch we should do so. In particular we
 should look over all destructors to ensure that they are as exception
-safe at possible.
+safe as possible.
 
 Later when more compiler support exceptions sufficiently well we will
 begin using them too. One reason for this is that the C++ standard
@@ -182,7 +208,7 @@ bad_allocation if the requested memory is not available.
 Formatting
 ----------
 
-* Only one delaration on each line.
+* Only one declaration on each line.
        int a;
        int b;
        -NOT-
@@ -201,7 +227,7 @@ Formatting
        char *p = "flop"; // wrong
        char &c = *p;     // wrong
 
-  Some time ago we had a huge discusion on this subject and after
+  Some time ago we had a huge discussion on this subject and after
   convincing argumentation from Asger this is what we decided. Also note
   that we will have:
        char const * p;
@@ -229,6 +255,12 @@ Formatting
        };
        -NOT-
        enum { one = 1, two = 2, three 3 }; // wrong
+       -NOT-
+       enum {
+               ONE = 1,
+               TWO = 2,
+               THREE = 3
+       };
 
 * Naming rules for classes
 
@@ -238,24 +270,22 @@ Formatting
     [I am not so sure about the LyX prefix]
 
   - Class names are usually capitalized, and function names lowercased.
-    Enums are named like Classes, enum values in CAPS.
+    Enums are named like Classes, values are usually in lower-case.
 
   - Long variables are named like thisLongVariableName.
 
-  New types are capitalized, so this goes for typedefs,classes,structs
+  New types are capitalized, so this goes for typedefs, classes, structs
   and enums.
 
 * Formatting
 
-  - Please adapt the formatting of your code to the setting in LyX in that
-    particular file. Lars and Asger are slowly, but surely moving the source 
-    towards Linux kernel style formatting, aka K&R style. We suggest that you 
-    also do this, but this is NOT something that has been decided generally.
-
+  - Adapt the formatting of your code to the one used in the
+    other parts of LyX. In case there is different formatting for
+    the same construct, use the one used more often.
 
 * Use existing structures
 
-  - Use string whereever possible. LyX will someday move to Unicode, and
+  - Use string wherever possible. LyX will someday move to Unicode, and
     that will be easy if everybody uses string now.
 
   - Check out the filename and path tools in filetools.h
@@ -264,47 +294,57 @@ Formatting
     and the regex class.
 
   - Use the DebugStream class to report errors and messages using
-    the lyxerr instantation.
+    the lyxerr instantiation.
 
   [add description of other existing structures]
 
 
 * Declarations
-  
+
   - Use this order for the access sections of your class: public,
     protected, private. The public section is interesting for every
     user of the class. The private section is only of interest for the
-    implementors of the class (you). [Obvously not true since this is
+    implementors of the class (you). [Obviously not true since this is
     for developers, and we do not want one developer only to be able to
     read and understand the implementation of class internals. Lgb]
-  
-  - Avoid to declare global objects in the declaration file of the class. 
-    If the same variable is used for all object, use a static member.
 
-  - Avoid global or static variables. An exception to this rule is 
+  - Avoid declaring global objects in the declaration file of the class.
+    If the same variable is used for all objects, use a static member.
+
+  - Avoid global or static variables. An exception to this rule is
     very private stuff like the math stack.
 
-  - Use the const keyword like this: char const * instead of const char *
-    because this is more logical.
 
+* File headers
+
+  - If you create a new file, the top of the file should look something
+    like this :
+
+  /**
+   * \file NewFile.C
+   * This file is part of LyX, the document processor.
+   * Licence details can be found in the file COPYING.
+   *
+   * \author Kaiser Sose
+   *
+   * Full author contact details are available in file CREDITS
+   */
 
 * Documentation
 
   - The documentation is generated from the header files.
   - You document for the other developers, not for yourself.
-  - You should document what the funtion do, not the implementation.
+  - You should document what the function does, not the implementation.
   - in the .C files you document the implementation.
   - Single line description (///), multiple lines description (/** ... */)
-  - You make the documentation by doing "make srcdoc" in the root,
-    and then you'll find HTML in the srcdoc/ directory. Read with
-    Netscape for best results.
+  - see the doxygen webpage referenced above
 
 
 * NAMING RULES FOR USER-COMMANDS
-   
+
   Here's the set of rules to apply when a new command name is introduced:
-  1) Use the object.event order. That is, use `word-forward' instead of 
+
+  1) Use the object.event order. That is, use `word-forward' instead of
      `forward-word'.
   2) Don't introduce an alias for an already named object. Same for events.
   3) Forward movement or focus is called `forward' (not `right').
@@ -315,24 +355,15 @@ Formatting
   8) The end of an object is called `end'.
 
 
-* Using external GUI constructors (XForms fdesign)
-
-  - Fdesign generated files should not be changed at all. The only changes
-    needed are gettext, compability with 0.81 or when you have made your own
-    xforms objects and have just a dummy in the .fd file in place of your
-    own. In case you have to change the generated files for any of the
-    reasons above, you should provide a patch against the clean generated
-    file. Your callbacks must be in a separate file.
-
  *************************************************************
 
  How to create class interfaces.
  (a.k.a How Non-Member Functions Improve Encapsulation)
  ======================================================
 
-       I recently read an article by Scott Meyers in C/C++ Users
+       I recently read an article by Scott Meyers in C/C++ User's
 Journal (Vol.18,No.2), where he makes a strong case on how non-member
-functions makes classes more encapsulated, not less. Just to skipping
+functions makes classes more encapsulated, not less. Just skipping
 to the core of this provides us with the following algorithm for
 deciding what kind of function to add to a class interface:
 
@@ -341,7 +372,7 @@ deciding what kind of function to add to a class interface:
        if (f needs to be virtual)
                make f a member function of C;
        else if (f is operator>> or operator<<) {
-               make f a non-member funtion;
+               make f a non-member function;
                if (f needs access to non-public members of C)
                        make f a friend of C;
        } else if (f needs type conversions on its left-most argument) {
@@ -352,14 +383,6 @@ deciding what kind of function to add to a class interface:
                make f a non-member function;
        else
                make f a member function of C;
-Unfortunately, to make the best use of this kind of Class API's we
-need namespaces. As soon as Jean-Marc stop using gcc 2.8 and other
-compilers seem more or less up to date on namespaces we will begin to
-use them. _BUT_ we should begin to use the above algoritm ASAP. We
-should also go through old code and apply this algorithm to the
-existing member functions. That will help maintainability in the
-future.
 
 (I'll fill in more from Scott Meyers article when time allows.)