     [file version.texi not included]

SGPEMv2 Developer Manual
************************

This is SGPEMv2 Manual (version VERSION, UPDATED).

Copyright © 2005 University of Padova, dept. of Pure and Applied Mathematics

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A copy of the license is included in the section entitled ``GNU Free Documentation License''.

History
*******

2005, December 11th --- Matteo Settenvini
     Added sources' directory description and repository usage guidelines. Included full FDL license text.

2005, November 8th --- Matteo Settenvini
     First draft of this document

Directory overview
******************

If you need to work on SGPEM sources, you'll probably be interested in understanding how this package directory structure is organized.

What follows is the tree you'll find after uncompressing the SGPEM tar archive.

config/
     Files used by Autotools while configuring and compiling SGPEM.

data/
     Various data SGPEM will use at runtime, like icons, images, XML DTDs, User Interface (*.ui) definition files, and so on.

doc/
     Inside this directory you'll find the User and Developer Manuals, like the one you're reading, ready to be compiled.

desktop/
     The desktop menu entries for FreeDesktop compliant Desktop Environments.

distro/
     Files used to prepare a package for a specific platform, maybe containing the installer data.

glade/
     Glade2 source files that can we used to generate various windows for the GUI.

m4/
     M4 macros used by Autoconf.

po/
     Here are stored the Gettext PO catalogs. If you are a translator, you should first look here in order to localize SGPEM into your language.

src/
     The source files of SGPEM.

Coding style
************

In this chapter we explore some self-imposed coding standards we tried to follow when coding SGPEM. If you plan to extend it in any way, you should abid to the guidelines explained thereafter.

Editors
=======

IDEs are a bad choice, since usually they leave your directory dirty, and full of temporary or project files. Please avoid their use if not strictly necessary.

A good choice for an editor is GNU Emacs, but every other editor supporting mixed mode for indentation and that has Unicode support will do.

Your files should be in ``UNIX mode''; that is, only a char is used for a newline. On DOS-based systems, usually two chars are employed: the newline char and the carriage return one. Failure to check your text files are correctly saved wastes space and others' patience, so please take care.

Indentation mixed mode is useful to ensure that your file will be correctly indented wheter another developer on another machine opens it with Emacs, Vim, Notepad, with a 8-spaces indent, with a 3-spaces one, and so on. A lot of UNIX editors nowadays use mixed mode.

GNU Emacs has another nice property: it can automatically indent code in a whole region for you, with M-x indent-region. Moreover, if you can get accustomed to it, you can activate the automatic indentation while in a programming mode, by typing C-c C-a. Experienced programmers find it saves quite a lot of time, but we guess it's just a matter of taste.

Coding in C++
=============

SGPEM is mostly written in C++, an Object Oriented language ideated by Bjarne Stroustrup and standardized in 1998 by ISO. Here are explained some guidelines you should keep well in mind if you want to contribute to this project.

C++ Coding Style
----------------

These are some notes on coding style, and things you should keep in mind whenever extending SGPEM source code. Patches to the source that don't uniform to these guidelines are likely to be rejected and need rework. Coding styles are highly subjective and are often the cause of harsh holy wars. Here we try also to give a rationale of these choices, supporting our statements.

 1. Left curly braces go on a newline, respect to the statement that comes before them. Right curly braces are to be put into a newline too. It may make you feel uneasy at first, but this behaviour is preferable because it clearly let you identify code blocks. Moreover, it is observed that putting left curly braces on the same line of a statement isn't a rule you always follow: a lot of exceptions are raised by particular situations, like: ``should my brace go on the same line after a class initialization list? and after a for loop declaration? what happens after namespaces declaration?'' So it's best to stick to a well known practice and put it always on a newline. A lot of complex software projects follow this rule because it also increases manutenibility: keep in mind that you aren't writing code for yourself, but for others to read.

 2. The return type for every function goes on a line, while the function name and its parameters go on the following, without any leading space. This makes easier to grep the source. For example, if you're searching for a declaration of int foo::bar() inside a large directory, grepping for: '/^foo::bar/g' will immediately pop out the correct result, whereas, if you didn't follow this rule, you would have searched for '/foo::bar/g', thus finding all recurrences of the function in the code, even function calls.

 3. Use the following example to understand how we want you to space expressions:

           type var = exp1 OP (exp2 OP fun1(exp3));

     And for parameters, the following spacing is preferable:

           function(par1, par2 = value, ...)

 4. Please define pointers like type* var instead of type *var.

 5. Labels go indented on the same level of the containing code block. For example:

          switch(x) {
          case 1:
               // foo
          case 2:
               // bar
          default:
               // baz
          }

     Remember that also public, protected and private are labels.

 6. Put incomplete class declarations before their interface, documenting it. For example:

          //! I'm a useless class
          /** This class is completely useless. */
          class C;
                // [...]

          class C {
          public:
                // [...]
          };

 7. All header files of the libs and the engine follow a common model. Try to adhere to it by looking at existing headers. Document them fully, even if it is tedious, using a Doxygen-like syntax. The payback will be high, I assure you.

 8. Class names are composed of capitalized words. Member functions are composed of capitalized words except for the very first letter. Member data are lowercase words (sometimes separated by an underscore). Enums members are lowercase and they have a prefix that tells something about their function, e.g., in an enum named signal, ``signal_*;''. Macro names are written all in capital.

 9. Private member object and function names always begin with an underscore. Public and protected ones don't.

 10. Some (broken?) versions of autotools had problems with extensions other than .cc for C++ implementation files (e.g. automake didn't produce correct implicit rules for them). Consequently, in order to avoid problems, we require you to use the following extensions:

       * .cc : C++ implementation files

       * .hh : C++ header files

       * .tcc : Template implementation files

     You can also add to the end of your ~/.emacs the line:

          (add-to-list 'auto-mode-alist (cons "\\.tcc\\'" 'c++-mode))

     to automatically associate the .tcc extension to the c++-mode.

C++ Coding Conventions
----------------------

Some common rules you should keep in mind when writing new code:

 1. Never use std::cout/cerr if you can do without them. Use printf() and fprintf() from cstdio instead,so that marking strings for gettext translation will be easier.

 2. Don't use ``using'' directives into the global space, even in a .cc, and neither in other namespaces. If you don't keep this in mind, you're buying to everybody a (big) problem. ``using'' makes sense at the beginning of a function to improve code readability, and you should be specific:

      1. ``using namespace std;'' is bad

      2. ``using std::string;'' is good

 3. When treating long template names, remember that typedef (along with typename as needed) are your best friends, expecially at the beginning of class declarations or function definitions.

 4. ``Syscalls'' are evil for portability. Thread calls can sometimes escape this rule (since they're quite different from system to system, and GNU/Linux ones are really good), but remember that every UNIX/Win32/Solaris/etc. native call you use means extra-work somewhere in the near future. If a portable toolkit we're using provides the same functionality, it should be preferred to a system call.

 5. Only exportable classes and functions inside a library should be marked with correct visibility attribute (usually a macro we defined as DLL_EXPORT). All the others are marked with --visibility=hidden from the compiler, and aren't available outside the DSO (Dynamic Shared Object) they live in, so that they don't clutter the DSO namespace.

 6. When you do something, remember to update the ChangeLog. This is essential. More on this on see Committing changes.

 7. Remember macros for inclusion at the beginning of header files, as well in template implementation files. In the latter case, you may want to include the template implementation files in the corresponding header files. An example of a correct inclusion directive is:

          #ifndef HELLO_WORLD_HH
          #define HELLO_WORLD_HH 1

          // interface definitions

          #endif

 8. Please follow this order when declaring a class interface:

      1. Incomplete declarations of nested classes and friend functions / classes declarations.

      2. Typedefs

      3. Enums

      4. Non-static member functions

      5. Static member functions

      6. Static constant data members

      7. Variable data members

     Static non-const data members shouldn't exist. Nested classes go declared outside their containing class. For example:

          class C;

          class C {
                class D;
                // ...
          };

          class C::D {
                // ...
          };

     The order for visibility should be: public, then protected, then private.

Committing changes
******************

SGPEM sources are held in a repository managed by Subversion. This is not an introduction on how to use this tool. For that, you should refer to its own manual, located at http://svnbook.red-bean.com/. Rather, it sets some ``best practices'' you ought to follow committing changes to the repository.

Introduction and goals
======================

The Subversion repository, commonly referred to just as ``repository'', is the place where all the material produced within this project will live.

There is a strong need to maintain an history of development data, even on plain documentation, whether it is a proprietary file format describing an UML chart, or some lovely C source code.

Mantaining versioned files for everything makes developers more free to cut, modify, hack, and revamp them, with the safety that older versions can always be fetched again.

This document describes some guidelines for maintaining the repository as clean as possible, by defining some restrictive rules that developers must respect in order to avoid abusing of the customizability this tool offers.

Repository layout
=================

The layout you'll find inside the repository will be:

swe/docs
     (subdirectories: internals, externals, manuals, misc)

     Contains all drafts intended for the developers.  This directory doesn't support tagging and branching because drafts has ``eternal'' life. If needs arise, they'll rather need to be renamed appending their version to their filename (-01, -02, etc.).

swe/trunk
     (subdirectories: doc, src, ...)

     This is the main development area where source files are held. Usually, official releases spin off the trunk. For a list of the directories layed out therein, please refer to Directory overview.

swe/tags

     It contains copies of the trunk/ directory. Note that tagging the trunk directory reflects in a double space only for your local working copy, while it is a O(1) operation for the server. Changes and commits are NOT allowed here.  Please note that tagging must be agreeded with project administrator.

     The format of a tag is:

          <version_number>

     Example:

          1.0

swe/branches

     This is the same as tags, except that commits are allowed inside the branch. Please refer to common development models to decide what should or should not be done inside a branch. Note that branching isn't something everybody should do: it should be agreed together with the project administrator.

     The format of a branch is:

          <version_number>-r<revision_number>--<branch_name>

     Example:

          1.2-r164--guirestyle

Basic svn usage
===============

In your daily use of the repository you will mostly need to know a very small subgroup of svn commands. Other ones are usually for fine tuning operations (like setting file binary flags, keyword expansion, managing the repository tree, etc.), which are tasks carried out by the repository administrator.

Here there's a quick reference about such commands:

svn checkout http://svn.thgnet.it/swe/drafts
     Downloads a copy of the current drafts/ directory contents. Checking out the root repository dir (/swe/) may result, in near future, to a big download, as branch and tags will be stored inside the root directory.

svn update (short form: svn up)
     Recursively updates the current directory to the latest revision. Use option -r N to update to a specific revision.

svn status
     Shows the status of your working copy against the repository.

svn diff
     Shows differences in unified diff format between your working copy and the base version of the current revision selected (usually it means the latest). If you want to compare two different revisions you can add a -r N:M parameter.

svn lock filename
     Locks a file so that everybody except the lock owner can't commit over it. This is particularly useful for binary files: you should always try to acquire a lock before starting editing.

Gold rules on committing
========================

A versioning system, by definition, records everything that goes through it. So it may be a good idea not to commit garbage or make changes that will probably be rejected by the team. The repository mustn't be used as a temporary file storage system (so just don't use it to transfer files from work to home or vice-versa!).

When you commit something, it should be an acceptable piece of work. Of course, it can happen that later inspection demonstrates it's better to revert some changesets, but that's the purpose of having a centralized versioning system.

Avoid big commits altogether. A detailed description of your intentions should hit the mailing list before even starting to write such a patch. Then, committing your work must happen via small incremental patches.

Also please avoid making structural tree changes (creating, moving, removing, renaming directories) without asking first the repository administrator.

Everything can be reverted by svn, but that's not an excuse for sloppiness.

How to write good log messages
==============================

Be as descriptive as possible, concisely. If your changeset was discussed on the mailing list or at a meeting, make a clear reference to it.

Please be consistent with the message format. Use a clean english language, employing only abbreviations contained in the glossary document.

Always prepend a dash (-) for each changeset description, followed by a space. This will make clear, in case of line wrapping, what is part of the list and what is simply a new line.

Every sentence must end with a full stop. If a particular description is composed by several sub-descriptions, use a colon (:), and use a tab space to indent the inner list.

You can use only one level of nesting for lists. If you need more, you are probably making an oversized commit.

An example of the log format is the following:

     - Change description 1.
     - Change description 2:
      <tab>  - Part 1 of change description 2.
      <tab>  - Part 2 of change description 2.
     - Change description 3. This particular change has a very long message
       describing this atomic commit.

Conflicts resolution
====================

As in any other concurrent development system, conflicts may happen. this will be demanded to the official Subversion Book (ch. 3 sect. 5.4) for an explanation on how to handle them. We will just quote something to keep well in mind, however:

     In the end, it all comes down to one critical factor: user communication. When users communicate poorly, both syntactic and semantic conflicts increase. No system can force users to communicate perfectly, and no system can detect semantic conflicts. So there's no point in being lulled into a false promise that a locking system will somehow prevent conflicts; in practice, locking seems to inhibit productivity more than anything else.

Version Control with Subversion, a.k.a. ``The Subversion Book''

     [file fdl.texi not included]