(file) Return to CodingGuidelines.htm CVS log (file) (dir) Up to [Pegasus] / pegasus / doc

  1 marek 1.1 <html>
  2           
  3           <head>
  4           <meta http-equiv="Content-Language" content="en-us">
  5           <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
  6           <title>PEP 221 - Pegasus Coding Conventions</title>
  7           <link rel="stylesheet" href="http://www.opengroup.org/stylesheets/info1+margins.css">
  8           </head>
  9           
 10           <body>
 11           
 12           <hr>
 13           
 14           <p align="center"><b><font size="4">Pegasus Enhancement Proposal (PEP)</font></b></p>
 15           <p><b>PEP #:</b> 221</p>
 16           <p><b>Title:</b> Pegasus Coding Conventions</p>
 17           <p><b>Status:</b> Approved</p>
 18           <p><b>Version History:</b></p>
 19           <table border="1" cellspacing="1" bordercolordark="#666666"
 20               bordercolorlight="#CCCCCC" width=100%
 21               style='font-size=10.0pt;font-family:Arial'>
 22 marek 1.1   <tr>
 23               <th bgcolor="#CAE6CA">Version</th>
 24               <th bgcolor="#CAE6CA">Date</th>
 25               <th bgcolor="#CAE6CA">Author</th>
 26               <th bgcolor="#CAE6CA">Change Description</th>
 27             </tr>
 28             <tr>
 29               <td align="center">1.0</td>
 30               <td align="center">23 February 2005</td>
 31               <td align="center">Roger Kumpf</td>
 32               <td>Initial submittal, based on documents in pegasus/doc directory in CVS
 33                   (conventions.txt, portability.txt, CodeReviewNotes.txt, and DOCREMARKS).
 34               </td>
 35             </tr>
 36             <tr>
 37               <td align="center">1.1</td>
 38               <td align="center">1 March 2005</td>
 39               <td align="center">Roger Kumpf</td>
 40               <td>Updated based on 3/1/05 architecture review comments.<br>
 41                   <em>Approved version (Ballot 95).</em></td>
 42             </tr>
 43 marek 1.1   <tr>
 44               <td align="center">2.0</td>
 45               <td align="center">21 March 2005</td>
 46               <td align="center">Roger Kumpf</td>
 47               <td>Opened up for additional conventions.</td>
 48             </tr>
 49             <tr>
 50               <td align="center">2.1</td>
 51               <td align="center">5 August 2005</td>
 52               <td align="center">Roger Kumpf</td>
 53               <td>Updated based on comments and architecture team discussions.</td>
 54             </tr>
 55             <tr>
 56               <td align="center">2.2</td>
 57               <td align="center">21 February 2006</td>
 58               <td align="center">Roger Kumpf</td>
 59               <td>Updated based on review comments.</td>
 60             </tr>
 61             <tr>
 62               <td align="center">2.3</td>
 63               <td align="center">24 February 2006</td>
 64 marek 1.1     <td align="center">Roger Kumpf</td>
 65               <td>Updated based on review comments and architecture team discussion.</td>
 66             </tr>
 67             <tr>
 68               <td align="center">2.4</td>
 69               <td align="center">10 March 2006</td>
 70               <td align="center">Roger Kumpf</td>
 71               <td>Updated based on ballot comments.<br>
 72                   <em>Approved version (Ballot 111).</em>
 73               </td>
 74             </tr>
 75             <tr>
 76               <td align="center">3.0</td>
 77               <td align="center">10 March 2006</td>
 78               <td align="center">Roger Kumpf</td>
 79               <td>Opened up for additional conventions.</td>
 80             </tr>
 81             <tr>
 82               <td align="center">3.1</td>
 83               <td align="center">20 November 2008</td>
 84               <td align="center">Roger Kumpf</td>
 85 marek 1.1     <td>Updated based on review comments.</td>
 86             </tr>
 87             <tr>
 88               <td align="center">3.2</td>
 89               <td align="center">26 November 2008</td>
 90               <td align="center">Roger Kumpf</td>
 91               <td>Updated based on review comments.</td>
 92             </tr>
 93             <tr>
 94               <td align="center">3.3</td>
 95               <td align="center">4 December 2008</td>
 96               <td align="center">Roger Kumpf</td>
 97               <td>Updated based on review comments.<br>
 98                   <em>Approved version (Ballot 160).</em>
 99               </td>
100             </tr>
101           </table>
102           <p>&nbsp;</p>
103           <hr>
104           <p><b>Abstract:</b> This document formalizes the Pegasus coding conventions.
105           </p>
106 marek 1.1 <hr>
107           
108           <h2><font color="#000000">Definition of the Problem</font></h2>
109           <p><The use of inconsistent coding styles is an impediment to
110           effective development and maintenance of Pegasus code.  Formalization of
111           Pegasus coding conventions may help to improve code consistency.
112           </p>
113           
114           <h2><font color="#000000">Proposed Solution</font></h2>
115           <p>The following items comprise the Pegasus coding conventions.</p>
116           
117           <h3>Formatting</h3>
118           <ol>
119             <li>Indent by increments of four spaces.  Indent comments
120                 equally with the associated code.</li>
121             <li>Do not use tab characters.</li>
122             <li>Lines must not span more than 80 columns.</li>
123             <li>Remove trailing spaces at the end of a line.
124                 (Note: This also applies to Makefiles, where trailing spaces may cause
125                 unintended whitespace in generated files.)</li>
126             <li>Put opening brace on a line by itself, aligned with control keyword
127 marek 1.1       or method signature.
128                 Do this:
129                 <pre><code>    for (...)
130               {
131               }</code></pre>
132                 Not this:
133                 <pre><code>    for (...) {
134               }</code></pre>
135                 Or this:
136                 <pre><code>    for (...)
137                 {
138                 }</code></pre>
139             </li>
140             <li>Use braces around the body of a control block (e.g., <code>if</code>,
141                 <code>for</code>, or <code>while</code> statement), even if the body
142                 contains just a single statement.
143                 Do this:
144                 <pre><code>    for (...)
145               {
146                   i++;
147               }</code></pre>
148 marek 1.1       Not this:
149                 <pre><code>    for (...)
150                   i++;</code></pre>
151             </li>
152             <li>Use a new line for <code>else</code> statements rather
153                 than placing then on the same line as a preceding '<code>}</code>'.
154                 Do this:
155                 <pre><code>    if (...)
156               {
157                   i++;
158               }
159               else
160               {
161                   j++;
162               }</code></pre>
163                 Not this:
164                 <pre><code>    if (...)
165               {
166                   i++;
167               } else
168               {
169 marek 1.1         j++;
170               }</code></pre>
171             </li>
172             <li>Use normal indenting for parameters in a complex method signature:
173                 <pre><code>    void MyClass::myMethod(
174                   const char* someReallyLongName,
175                   const char* someOtherReallyLongName);</code></pre>
176             </li>
177             <li>Use normal indenting for all arguments in a complex function call.
178                 Do this:
179                 <pre><code>    callingMyFunction(
180                   arg1,
181                   arg2,
182                   arg3);</code></pre>
183                 Not this:
184                 <pre><code>    callingMyFunction(arg1,
185                                 arg2,
186                                 arg3);</code></pre>
187                 Each argument should be placed on a separate line.
188                 An exception is made for <code>PEG_TRACE</code> and
189                 <code>PEG_TRACE_CSTRING</code> statements, where the first two
190 marek 1.1       arguments should be placed on the opening line:
191                 <pre><code>    PEG_TRACE((TRC_HTTP, Tracer::LEVEL3,
192                   "Connection IP address = %s",
193                   (const char*)_ipAddress.getCString()));</code></pre>
194             </li>
195             <li>For an <code>if</code>, <code>while</code>, or <code>for</code>
196                 condition that does not fit on a single line, indent peer subconditions
197                 according to their level of nesting and indent other continuation lines
198                 using normal indenting.  Do this:
199                 <pre><code>    if ((variable1 == variable2) ||
200                   ((anotherVariableToConsider ==
201                         variable1 + variable2) &&
202                    (dayOfWeek == "Tuesday")))</code></pre>
203                 Not this:
204                 <pre><code>    if ((variable1 == variable2) ||
205                       ((anotherVariableToConsider ==
206                         variable1 + variable2) &&
207                            (dayOfWeek == "Tuesday")))</code></pre>
208             </li>
209             <li>For a statement that does not fit on a single line,
210                 all continuation lines should be indented once from the first line.
211 marek 1.1       For example:
212                 <pre><code>    sum = a + b + c +
213                   d + e + f +
214                   g + h;</code></pre>
215             </li>
216             <li>Do not separate a return type onto its own line.  Avoid this:
217                 <pre><code>    int
218               f()
219               {
220               }</code></pre>
221             </li>
222             <li>Avoid use of &quot;<code>(void)</code>&quot; for an empty parameter list.
223                 Use &quot;<code>()</code>&quot; instead.
224             </li>
225             <li>Avoid adding a space between function/method name the opening parenthesis.
226                 Do this:
227                 <pre><code>    void f(int i);
228               f(10);</code></pre>
229                 Not this:
230                 <pre><code>    void f (int i);
231               f (10);</code></pre>
232 marek 1.1   </li>
233             <li>Include a space between a keyword and an opening parenthesis.
234                 Do this:
235                 <pre><code>    if (i > 0)
236               for (i = 0; i < 10; i++)</code></pre>
237                 Not this:
238                 <pre><code>    if(i > 0)
239               for(i = 0; i < 10; i++)</code></pre>
240             </li>
241             <li>Do not add spaces around a condition.  Do this:
242                 <pre><code>    if (cond)
243               while (cond)</code></pre>
244                 Not this:
245                 <pre><code>    if ( cond )
246               while ( cond )</code></pre>
247             </li>
248             <li>Do not add a space between a template name and its type.  Do this:
249                 <pre><code>    Array&lt;Uint8&gt; myArray;</code></pre>
250                 Not this:
251                 <pre><code>    Array &lt;Uint8&gt; myArray;</code></pre>
252             </li>
253 marek 1.1   <li>Avoid aligning variable names in a declaration list.  Do this:
254                 <pre><code>    int x;
255               float y;</code></pre>
256                 Not this:
257                 <pre><code>    int      x;
258               float    y;</code></pre>
259             </li>
260             <li>Avoid indenting &quot;<code>public:</code>&quot;,
261                 &quot;<code>protected:</code>&quot;, and
262                 &quot;<code>private:</code>&quot;. Do this:
263                 <pre><code>    class X
264               {
265               public:
266                   int f();
267                   ...
268               private:
269                   int _g();
270                   ...
271               };</code></pre>
272             </li>
273             <li>The '<code>#</code>' indicating a preprocessing directive is placed
274 marek 1.1       at the beginning of a line.  Nested preprocessing directives are
275                 indented with one space after the '<code>#</code>' for each level of
276                 nesting.  The <code>#ifndef</code> used for header file include protection
277                 is not considered a level of nesting.  For example:
278                 <pre><code>#ifdef PEGASUS_HAS_SIGNALS
279           # ifdef PEGASUS_OS_TYPE_WINDOWS
280           #  include &lt;windows.h&gt;
281           # else
282           #  include &lt;unistd.h&gt;
283           # endif
284           #endif</code></pre>
285             </li>
286             <li>In a <code>switch</code> statement, indent the <code>case</code>
287                 statement from the <code>switch</code> and indent the case logic from
288                 the <code>case</code> statement.  For example:
289                 <pre><code>    switch(n)
290               {
291                   case 0:
292                       printf("Rock");
293                       break;
294                   case 1:
295 marek 1.1             printf("Paper");
296                       break;
297                   case 2:
298                       printf("Scissors");
299                       break;
300                   default:
301                       printf("Error");
302                       break;
303               }</code></pre>
304             </li>
305             <li>Do not put parentheses around the return value in a
306                 <code>return</code> statement.
307             </li>
308           </ol>
309           
310           <h3>Naming</h3>
311           <ol>
312             <li>For class/struct names, use mixed case with initial upper case and
313                 no underscores: <code>ThisIsAClassName</code>.
314             </li>
315             <li>For public member/variable names, use mixed case with initial lower case
316 marek 1.1       and no underscores: <code>thisIsAMemberName</code>.
317             </li>
318             <li>For public method/function names, use mixed case with initial lower case
319                 and no underscores: <code>thisIsAMethodName()</code>.
320             </li>
321             <li>Prepend an underscore to private and protected member and method names:
322                 <code>_thisIsAPrivateMemberName</code>,
323                 <code>_thisIsAPrivateMethodName()</code>.
324             </li>
325             <li>General constants and macro names should begin with <code>PEGASUS_</code>.
326             </li>
327             <li>Use this format for constant and macro names:
328                 <code>PEGASUS_CONSTANT_NAME</code>.
329             </li>
330             <li>Files names should use mixed case with initial upper case and no
331                 underscores: <code>ThisIsAFileName.cpp</code>.
332             </li>
333             <li>A file should have the same name (and case) as the class it contains.
334             </li>
335             <li>Environment variables must begin with <code>PEGASUS_</code> and have
336                 this form: <code>PEGASUS_ENVIRONMENT_VARIABLE</code>.
337 marek 1.1       This applies to environment variables that control the build and test
338                 configuration as well as those (if any) used by Pegasus at run time.
339             </li>
340             <li>Test executable names should begin with 'Test' (to distinguish them
341                 from other executables) and should use mixed case with initial upper
342                 case and no underscores.  The name should clearly indicate the feature
343                 being tested.  For example: <code>TestFeature1</code>.
344             </li>
345           </ol>
346           
347           <h3>Style</h3>
348           <ol>
349             <li>In a header file, use angle brackets (with a fully qualified path)
350                 rather than quotes when including a file.  Do this:
351                 <pre><code>    #include &lt;Pegasus/Common/Array.h&gt;</code></pre>
352                 Not this:
353                 <pre><code>    #include &quot;Array.h&quot;</code></pre>
354             </li>
355             <li>Use &quot;<code>0</code>&quot; rather than &quot;<code>NULL</code>&quot;
356                 as a null pointer value.
357             </li>
358 marek 1.1   <li>Avoid <code>throw()</code> declarations.  These may be used
359                 only when a method must not (and will not) throw any exception not
360                 specified in the throw clause.  When a <code>throw()</code>
361                 clause is needed, include it on the method declaration and definition.
362             </li>
363             <li>Use <code>const</code> declarations liberally,
364                 but not on "plain old data type" parameters.</li>
365             <li>Catch exceptions by const reference when feasible.</li>
366             <li>Avoid inlining of large functions.</li>
367             <li>Avoid committing binary files to CVS.</li>
368             <li>Resolve compile warnings.</li>
369             <li>Define variables as late as possible.
370                 A single object initialization is more efficient than initialization
371                 followed by assignment.  For example, this logic involves just a single
372                 String construction:
373                 <pre><code>    String s = foo();</code></pre>
374                 while this logic causes two String constructions and an assignment:
375                 <pre><code>    String s;
376               ...
377               s = foo();</code></pre>
378                 </li>
379 marek 1.1   <li>Present resources as part of classes, do not use them directly.</li>
380             <li>Use <code>new</code> and <code>delete</code> to manage dynamic
381                 memory, not <code>malloc</code>, <code>free</code>, or
382                 <code>strdup</code>.</li>
383             <li>When rethrowing an exception from a <code>catch</code>
384                 block, avoid specifying the object to throw so that exception subtype
385                 information is not lost and construction of an extra exception
386                 object is avoided.  Do this:
387                 <pre><code>    catch (Exception&)
388               {
389                   ...
390                   throw;
391               }</code></pre>
392                 Not this:
393                 <pre><code>    catch (Exception& e)
394               {
395                   ...
396                   throw e;
397               }</code></pre></li>
398             <li>Do not check whether a pointer is non-null before
399                 deleting it.  The check is unnecessary, since it is also performed by
400 marek 1.1       the <code>delete</code> operator.  Do this:
401                 <pre><code>    delete ptr;</code></pre>
402                 Not this:
403                 <pre><code>    if (ptr)
404               {
405                   delete ptr;
406               }</code></pre></li>
407             <li>Avoid using the compiler default implementations for
408                 default constructors, copy constructors, and assignment operators.
409                 These should be declared as private and left unimplemented if they
410                 are not intended to be used.  A decision to use a compiler default
411                 should be documented with a comment in the class declaration.</li>
412             <li>Avoid the use of optional parameters in methods which
413                 have interface compatibility requirements.</li>
414             <li>Avoid reading variables from the environment in
415                 production (not debug or test) runtime code.</li>
416             <li>Definitions for the external interface declarations should not appear
417                 in the external interface header files.  Implementation logic for the
418                 external interfaces should be contained in the associated source files.
419                 </li>
420             <li>Pass object parameters by reference, when feasible,
421 marek 1.1       to avoid unnecessary copy constructions.  For example, this:
422                 <pre><code>    void func(const String& s);</code></pre>
423                 is preferred to this:
424                 <pre><code>    void func(String s);</code></pre></li>
425             <li>Avoid using the C++ standard template library (STL) and the standard
426                 <code>string</code> class.  (These tend to produce bloat and may have
427                 portability issues.)  These files should not be included:
428                 <code>&lt;string&gt;</code>,
429                 <code>&lt;vector&gt;</code>,
430                 <code>&lt;map&gt;</code>,
431                 <code>&lt;mmap&gt;</code>,
432                 <code>&lt;set&gt;</code>,
433                 <code>&lt;mset&gt;</code>,
434                 <code>&lt;stack&gt;</code>,
435                 <code>&lt;queue&gt;</code>,
436                 and other STL header files.</li>
437             <li>Do not call <code>assert()</code> directly.  Instead, use
438                 <code>PEGASUS_ASSERT()</code> in production code and
439                 <code>PEGASUS_TEST_ASSERT()</code> in test programs.</li>
440             <li>Do not explicitly initialize Pegasus Strings to
441                 <code>String::EMPTY</code>. This is the default value.</li>
442 marek 1.1   <li>Do not add a null terminator to Pegasus Buffer strings.
443                 <code>Buffer::getData()</code> ensures the resulting string is
444                 null-terminated.</li>
445           </ol>
446           
447           <h3>Documentation</h3>
448           <ol>
449             <li>Class members and methods should be documented with DOC++ comments.</li>
450             <li>Use <code>/** */</code> rather than <code>///</code> for DOC++
451                 comments.
452             </li>
453             <li>Use this comment style for DOC++ comments:
454                 <pre><code>    class X
455               {
456               public:
457           
458                   /**
459                       Creates widgets.
460                       @param numWidgets The number of widgets to create.
461                       @return true if successful, false otherwise.
462                   */
463 marek 1.1         Boolean createWidgets(Uint32 numWidgets);
464               };</code></pre>
465             </li>
466             <li>A description should end with a period, even if it is brief:
467                 <pre><code>    /**
468                   Does something useful.
469               */</code></pre>
470             </li>
471             <li>Add a blank line between documented methods:
472                 <pre><code>    /**
473                   Does something quite useful.
474               */
475               void f();
476           
477               /**
478                   The previous method has a newline after it
479                   to improve its visibility.
480               */
481               void g();</code></pre>
482             </li>
483           </ol>
484 marek 1.1 
485           <h3>Portability Considerations</h3>
486           <ol>
487             <li>The use of platform specific <code>#ifdef</code>'s should be minimized
488                 and discouraged.  It is preferred to abstract the mechanics of
489                 dissimilar platforms in separate modules (such as DirPOSIX.cpp vs.
490                 DirWindows.cpp) or by using abstraction functions or macros such as
491                 those that appear below.</li>
492             <li>In header files, identifiers from the standard library (such as
493                 <code>ostream</code>, <code>istream</code>, <code>cout</code>, and
494                 <code>cerr</code>) must be enclosed in a <code>PEGASUS_STD()</code>
495                 macro (which prepends <code>std::</code> to the argument on some
496                 platforms).
497             </li>
498             <li>Do not use the <code>PEGASUS_STD()</code> macro in a source file.
499                 Instead, specify <code>PEGASUS_USING_STD;</code> at the beginning of
500                 the file.
501             </li>
502             <li>Do not use <code>PEGASUS_USING_STD;</code> or
503                 <code>PEGASUS_USING_PEGASUS;</code> in a header file.
504             </li>
505 marek 1.1   <li>Avoid use of conditional compilation for obscuring platform
506                 differences. Use platform abstractions in the appropriate platform
507                 files or in the System*.cpp files in Common.
508             </li>
509             <li>Windows requires symbols to be explicitly imported/exported from
510                 dynamic libraries.  Linkage.h files are used to define the necessary
511                 linkage macros.  Each dynamic library that exports symbols should
512                 define a <code>PEGASUS_&lt;LIBRARY&gt;_LINKAGE</code> symbol in a
513                 Linkage.h file.  Each symbol that is exported from the library
514                 must be declared with this linkage macro.  For example:
515                 <pre><code>    class PEGASUS_COMMON_LINKAGE String;
516           
517               PEGASUS_COMMON_LINKAGE void globalFunction();</code></pre>
518             </li>
519             <li>A <code>main()</code> function must return an int (required by
520                 Windows NT).
521             </li>
522             <li>Do not use <code>ultostr()</code>; use <code>sprintf()</code>
523                 instead.
524             </li>
525             <li>Do not declare a throw clause without parentheses:
526 marek 1.1       <pre><code>    void f() throw TooBad;</code></pre>
527             </li>
528             <li>Do not include a definition of a static member with its declaration:
529                 <pre><code>    class X
530               {
531               public:
532           
533                   static const Uint32 COLOR = 225;
534               };</code></pre>
535                 Use this instead:
536                 <pre><code>    class X
537               {
538               public:
539           
540                   static const Uint32 COLOR;
541               };</code></pre>
542                 And add the definition in the source file:
543                 <pre><code>    const Uint32 X::COLOR = 225;</code></pre>
544             </li>
545             <li>Use <code>PEGASUS_64BIT_CONVERSION_WIDTH</code> for
546                 printf and scanf conversions of 64-bit integers rather than
547 marek 1.1       <code>ll</code> or <code>L</code>.
548                 Do this:
549                 <pre><code>    Sint64 i64 = 10;
550               printf(&quot;i64 value = %&quot; PEGASUS_64BIT_CONVERSION_WIDTH &quot;d.\n&quot;, i64);</code></pre>
551                 Instead of this:
552                 <pre><code>    Sint64 i64 = 10;
553               printf(&quot;i64 value = %lld.\n&quot;, i64);</code></pre>
554             </li>
555             <li>Do not include class scoping on methods or members in a class definition.
556                 Do this:
557                 <pre><code>    class X
558               {
559               public:
560           
561                   int myMethod();
562               };</code></pre>
563                 Not this:
564                 <pre><code>    class X
565               {
566               public:
567           
568 marek 1.1         int X::myMethod();
569               };</code></pre>
570             </li>
571             <li>Do not use <code>Pegasus::</code> to scope symbols.  Not all platforms
572                 support C++ namespaces, and this will cause a compilation failure.  If
573                 a symbol must be explicitly scoped to the Pegasus namespace, use the
574                 <code>PEGASUS_NAMESPACE()</code> macro instead.</li>
575             <li>Use consistent declarations of <code>const</code> parameters in method
576                 declarations and definitions.</li>
577           </ol>
578           
579           
580           <h2><font color="#000000">Discussion</font></h2>
581           <p>Suggestions for additional conventions are listed here for discussion:
582           <ul>
583             <li>Handling of error conditions (cerr vs. logging) and exceptions</li>
584             <li>Testing (perhaps reference another document)</li>
585             <li>Is it appropriate to make a statement about defining
586                 localizable messages in the appropriate message bundle?
587             </li>
588           </ul>
589 marek 1.1 </p>
590           
591           
592           <hr>
593           <p><i><font size="2">Copyright (c) 2005 EMC Corporation; Hewlett-Packard
594           Development Company, L.P.; IBM Corp.; The Open Group;
595           VERITAS Software Corporation</font><br>
596           <br>
597           <font size="1">Permission is hereby granted, free of charge, to any person
598           obtaining a copy&nbsp; of this software and associated documentation files
599           (the &quot;Software&quot;), to deal in the Software without restriction,
600           including without limitation the rights to use, copy, modify, merge, publish,
601           distribute, sublicense, and/or sell copies of the Software, and to permit
602           persons to whom the Software is furnished to do so, subject to the following
603           conditions:</font><br>
604           <font size="2"><br>
605           </font>
606           <font size="1">THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE
607           INCLUDED IN ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS
608           PROVIDED&nbsp; &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
609           IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
610 marek 1.1 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
611           AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
612           LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
613           OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
614           SOFTWARE.</font></i></p>
615           <hr>
616           <p>Template last modified: <b>March 9th 2004</b> by <b>Martin Kirk<br>
617           </b>Template version: <b>1.8</b></p>
618           
619           </body>
620           
621           </html>

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2