]> git.lyx.org Git - lyx.git/blob - development/Code_rules/Rules
change to use ostreams instead of string when writing files. fiddling with insettext...
[lyx.git] / development / Code_rules / Rules
1 Rules for the code in LyX
2 -------------------------
3 [updated from the C++STYLE distrubuted with the GNU C++ Standard]
4
5 The aim of this file is to serve as a guide for the developers, to aid us to
6 get clean and uniform code. Still uncomplete.
7
8 We really like to have new developers joining the LyX Project. However
9 since we have had problems in the past with developers leaving the
10 project and their contributed code in a far from perfect state. Most
11 of this happened before that we really became aware of these issues,
12 but still, we don't want it to happen again. So we have put together
13 some guidelines and rules for the developers.
14
15 In general, if you want to contribute to the main source, we expect at least 
16 that you:
17
18 - write good C++ code: Readable, well commented and taking advantage of the 
19   OO model.
20 - adapt the code to the structures already existing in LyX, or in case that 
21   you have better ideas, discuss them on the developer's list before writing 
22   the code.
23 - take advantage of the C++ standard library.
24
25 - we use the preincrement operator whenever possible, it has potential
26   of beeing faster than postincrement. (same goes for decrement)
27 - we try to give variables minimal scope.
28
29 These guidelines should save us a lot of work while cleaning up the code and 
30 help us to have quality code. LyX has been haunted by problems coming from 
31 unfinished projects by people who have left the team. Those problems will 
32 hopefully disappear if the code is easy to hand over to somebody else.
33
34 When you send in a patch or commit to the LyX cvs repository we expect
35 you to add a ChangeLog entry. The entry should have this syntax:
36
37 1999-12-13  Lars Gullik Bjønnes  <larsbj@lyx.org>
38
39         * src/support/lyxstring.C (find): assert bug fixed.
40
41 * Pointers and references
42   char * p = "flop";
43   char & c = *p;
44       -NOT-
45   char *p = "flop"; // wrong
46   char &c = *p;     // wrong
47
48  Some time ago we had a huge discusion on this subject and after
49 convincing argumentation from Asger this is what we decided. Also note
50 that we will have:
51  char const * p;
52       -NOT-
53  const char * p;
54
55 * Operator names and parentheses
56   operator==(type)
57        -NOT-
58   operator == (type)  // wrong
59
60   The == is part of the function name, separating it makes the
61 declaration look like an expression.
62
63 * Function names and parentheses
64   void mangle()
65        -NOT-
66   void mangle ()  // wrong
67
68 * Enumerators
69   enum {
70         one = 1,
71         two = 2,
72         three = 3
73   };
74   -NOT-
75   enum { one = 1, two = 2, three 3 };
76
77 * Naming rules for classes
78
79   - Use descriptive but simple and short names. For stuff specific to LyX
80     use LyX as prefix. Some modules, like mathed or spellchecker, could have
81     other prefixes.
82     [I am not so sure about the LyX prefix]
83
84   - Class names are usually capitalized, and function names lowercased.
85     Enums are named like Classes, enum values in CAPS.
86
87   - Long variables are named like thisLongVariableName.
88
89   New types are capitalized, so this goes for typedefs,classes,structs
90 and enums.
91
92 * Formatting
93
94   - Please adapt the formatting of your code to the setting in LyX in that
95     particular file. Lars and Asger are slowly, but surely moving the source 
96     towards Linux kernel style formatting, aka K&R style. We suggest that you 
97     also do this, but this is NOT something that has been decided generally.
98
99
100 * Use existing structures
101
102   - Use string whereever possible. LyX will someday move to Unicode, and
103     that will be easy if everybody uses string now.
104
105   - Check out the filename and path tools in filetools.h
106
107   - Check out the string tools in lstring.h, and the SubString class
108     and the regex class.
109
110   - Use the DebugStream class to report errors and messages using
111     the lyxerr instantation.
112
113   [add description of other existing structures]
114
115
116 * Declarations
117   
118   - Use this order for the access sections of your class: public,
119     protected, private. The public section is interesting for every
120     user of the class. The private section is only of interest for the
121     implementors of the class (you). [Obvously not true since this is
122     for developers, and we do not want one developer only to be able to
123     read and understand the implementation of class internals. Lgb]
124   
125   - Avoid to declare global objects in the declaration file of the class. 
126     If the same variable is used for all object, use a static member.
127
128   - Avoid global or static variables. An exception to this rule is 
129     very private stuff like the math stack.
130
131   - Use the const keyword like this: char const * instead of const char *
132     because this is more logical.
133
134
135 * Documentation
136
137   - The documentation is generated from the header files.
138   - You document for the other developers, not for yourself.
139   - You should document what the funtion do, not the implementation.
140   - in the .C files you document the implementation.
141   - Single line description (///), multiple lines description (/** ... */)
142   - You make the documentation by doing "make srcdoc" in the root,
143     and then you'll find HTML in the srcdoc/ directory. Read with
144     Netscape for best results.
145
146
147 * NAMING RULES FOR USER-COMMANDS
148    
149   Here's the set of rules to apply when a new command name is introduced:
150  
151   1) Use the object.event order. That is, use `word-forward' instead of 
152      `forward-word'.
153   2) Don't introduce an alias for an already named object. Same for events.
154   3) Forward movement or focus is called `forward' (not `right').
155   4) Backward movement or focus is called `backward' (not `left').
156   5) Upward movement of focus is called `up'.
157   6) Downward movement is called `down'.
158   7) The begin of an object is called `begin' (not `start').
159   8) The end of an object is called `end'.
160
161
162 * Using external GUI constructors (XForms fdesign)
163
164   - Fdesign generated files should not be changed at all. The only changes
165     needed are gettext, compability with 0.81 or when you have made your own
166     xforms objects and have just a dummy in the .fd file in place of your
167     own. In case you have to change the generated files for any of the
168     reasons above, you should provide a patch against the clean generated
169     file. Your callbacks must be in a separate file.
170
171  *************************************************************
172
173  How to create class interfaces.
174  (a.k.a How Non-Member Functions Improve Encapsulation)
175  ======================================================
176
177         I recently read an article by Scott Meyers in C/C++ Users
178 Journal (Vol.18,No.2), where he makes a strong case on how non-member
179 functions makes classes more encapsulated, not less. Just to skipping
180 to the core of this provides us with the following algorithm for
181 deciding what kind of function to add to a class interface:
182
183         - We need to add a function f to the class C's API.
184
185         if (f needs to be virtual)
186                 make f a member function of C;
187         else if (f is operator>> or operator<<) {
188                 make f a non-member funtion;
189                 if (f needs access to non-public members of C)
190                         make f a friend of C;
191         } else if (f needs type conversions on its left-most argument) {
192                 make f a non-member function;
193                 if (f needs access to non-public members of C)
194                         make f a friend of C;
195         } else if (f can be implemented via C's public interface)
196                 make f a non-member function;
197         else
198                 make f a member function of C;
199  
200 Unfortunately, to make the best use of this kind of Class API's we
201 need namespaces. As soon as Jean-Marc stop using gcc 2.8 and other
202 compilers seem more or less up to date on namespaces we will begin to
203 use them. _BUT_ we should begin to use the above algoritm ASAP. We
204 should also go through old code and apply this algorithm to the
205 existing member functions. That will help maintainability in the
206 future.
207
208 (I'll feel in more from Scott Meyers article when time allows.)