Hi, and welcome aboard the ORBit-C++ team!

-------------------------------------------------------------------------------
Contents:
-------------------------------------------------------------------------------

0. contact info
1. job list
2. developer FAQ
3. tricks and hints for developers
4. coding conventions

-------------------------------------------------------------------------------
0. contact info
-------------------------------------------------------------------------------

You can find the project homepage at
http://orbitcpp.sourceforge.net/

We have two lists, both of which carry ~2 mails a day.
* orbitcpp-list@lists.sourceforge.net      
  general development and support
  http://lists.sourceforge.net/mailman/options/orbitcpp-list/

* orbitcpp-commits@lists.sourceforge.net
  read-only auto-generated commit notification list
  http://lists.sourceforge.net/mailman/options/orbitcpp-commits

You can find the names and addresses of people involved with this project
by viewing the AUTHORS file.

-------------------------------------------------------------------------------
1. job list
-------------------------------------------------------------------------------
Read this file, pick one of these open jobs, mail the list about it, get going:
being an orbitcpp developer is as easy as this.

- make one pseudo-object base class/template (like o2cpp)
- make ObjectId be real sequence<octet>
- struct, union
- sequence, array
- enum
- constants
- attributes
- complete the orb and poa implementations (policies, activators etc.)
- any
- dii
- dsi
- typecodes
- provide CORBAservices headers

-------------------------------------------------------------------------------
2. developer FAQ
-------------------------------------------------------------------------------

* What are basic facts that i should know about?
  - We do not do any IIOP/... connection handling ourselves, our goal is
  to provide a minimal wrapper around the stubs and skeletons generated
  by ORBit-C that does however fully comply with the c++ spec.

  - In order to do so, we strive for identity of memory footprints
  between c and c++ types. This allows marshalling of corba types from
  c++ to c with a simple reinterpret_cast (i.e. little or no overhead).
  This should be possible for everything but exceptions,
  but for some special cases (like object references), this requires special
  precautions (and/or kludges :)

  - Because of the above, we must stop the compiler from thunking the
  object refs when implicitly upcasting. In order to acheive this,
  special smart pointers are employed when multiple inheritance is
  used in the idl.
  
  
* What is the basic idl compiler design?

  It is modeled around the basic notion of an IDLElement (language.hh), which
  can be nearly everything that is a named entity of IDL, e.g.
  an operation, an interface, a type, but not an argument of an operation.
  The most important subclass of IDLElement is IDLScope. An IDLScope can
  contain several (distinctly named) IDLElements (which can in turn be
  IDLScopes, of course). With this model, we represent the entire scoping
  hierarchy brought about in the IDL file in a tree-like manner. 
  For example, consider
  
  module A {
    interface B {
      void opb1();
      void opb2();
    }
    interface C {
      void opc1();
      void opc2();
    }
  }
  
  which would result in the following tree, rooted at the root scope:
  
  + Root
  |
  +--+ module A (scope)
     |
     +--+ interface B (scope)
     |  |
     | 	+-- operation opb1() (element)
     |	|
     |	`-- operation opb1() (element)
     |
     `--+ interface B (scope)
        |
       	+-- operation opb1() (element)
      	|
      	`-- operation opb1() (element)
     
  As you can see, scopes form the inner nodes of the tree, whereas the leaf
  nodes feature elements.
  
  The root scope is part of the compiler state (in pass.hh), but it can be 
  accessed from any IDLElement by simply calling its getRootScope() method.
  
  Elements (and thus also scopes) have tool functions to get canonicalized
  names for them in various naming conventions, whether unqualified or not.
  Those are get(C|CPP|IDL)Identifier and getQualified(C|CPP|IDL)Identifier,
  both of which are pretty self-explanatory if called without parameters.
  The *Qualified* functions however leave room for tweaking. E.g., the
  up_to parameter lets you specify up to (but not including) which scope
  the qualified name should be built. (default being NULL, meaning gobble
  up everything, terminate when there are no more scopes to go, which 
  automatically puts some equivalent to "::" in front. If you want to avoid
  this, specify the root scope for this parameter). Scopes can do
  (recursive) name lookup for you. (lookup(), lookupLocal()) Scopes also
  have STL-style iterator functions to enable you to iterate over their 
  member nodes. (begin() and end())
  
  The next important notion in the compiler is IDLType. A class derived
  from IDLType defines all the methods necessary for the code generation passes
  to know how to marshal and demarshal it. (all declared pure virtual in 
  IDLType, see types.hh)

  All type representations in the compiler inherit from IDLType. If you 
  want to parse a type, you typically have two IDL_trees, typespec and dcl, 
  which you may pass to the type parser (declared in types.hh, instantiated 
  in the compiler state) to obtain an IDLType. If you add a built-in type,
  you must of course ammend the type parser.
  
  IDL has user-named types, such as structs and enums, which implies that 
  there can be classes which inherit from both IDLType and 
  IDLElement or IDLScope. If you want to make your own such type, be sure
  to override IDLElement's isType, a feature to enable the type parser
  to determine whether some resolved name really corresponds to a type
  before doing a cast (this is a bit like typeid).

  The compiler works in four passes, in the following order:
  - Information gathering (pass_gather.*)
    builds the aforementioned scope tree
  - Type translation (pass_xlate.*)
    writes a c++ mapping of user-defined IDL types
  - Stub production (pass_stubs.*)
  - Skel production (pass_skels.*)
  
  Only the first two passes iterate over libIDL's IDL_tree (which is
  why they inherit from IDLIteratingPass, from pass_idl_it.hh), the other
  two just iterate over the interface list (in the compiler state)
  
  This may give you an impression on what is where in the compiler.
  I suspect this explanation is not too good, feel free to mail the list
  with improvements.
  
-------------------------------------------------------------------------------
3. tricks and hints for developers
-------------------------------------------------------------------------------

* debugging the idl compiler:
  put the piece of idl you want to debug into test/idl-torture/test.idl,
  run "gdb orbit-idl". The provided .gdbinit file will run everything up
  to the point where the c++ part of the compiler is entered.
  (requires source-built orbit)
  
* making the compiler build much faster:
  specify --enable-debug and --disable-static on the ./configure command
  line.

-------------------------------------------------------------------------------
4. coding conventions
-------------------------------------------------------------------------------
* naming convention is like the CORBA c++ mapping, with object members named 
  like m_data
  
* base indentation is one tab (best viewed to be 4 spaces wide)

* indentation style is k&r, like this:

8< ----------------------------------------------------------------------------
namespace CORBA {
	class Apple : public Pear {
		int *a;
		
		void inline(int *b) {
			cout << "Hi there" << endl;
		}
		
		void outofline();
	};
}

void 
CORBA::Apple::outofline() {
	cout << "Hi again" << endl;
}
8< ----------------------------------------------------------------------------
