In this file are instructions for developers and those wishing to
contribute to Linbox. It is intended both for the uninitiated and for
the reference of existing developers.

I. Compilation and installation

If you are installing from a tarred distribution, please see the file
INSTALL for basic instructions on how to install Linbox. If you are
installing from CVS, please see the instructions in section (III)
below.

II. Basic layout

Linbox is a template library, so installation requires very little
actual compilation. Nearly all of the library is in header
files. Directories in the source distribution are as follows, relative
to the tree's root:

doc/      - Documentation (see below)
examples/ - Simple examples to help new users get started with the
		library
macros/   - Files to assist the build system
linbox/      - All library source (i.e. header files) goes here
	algorithms/ - Specific algorithms
	blackbox/   - Black box (i.e. matrix) objects
	element/    - Objects representing field elements
	field/      - Objects representing fields (e.g. rationals,
			integers modulo p, etc.)
	randiter/   - Random number generators
	solutions/  - Easy-to-use interfaces for solutions to problems
	vector/     - Vector implementations
	util/	    - Utility routines that don't belong anywhere else
		integer/ - C++ source code for GMP integer wrapper
test/     - Tests for library performance and correctness
util/     - Scripts and other miscellaneous items, mostly for making
		library maintenance easier 

N.B. Though the doc/ directory contains some top-level and tutorial
documentation, reference documentation is stored in parallel with the
source code, under the src/ tree.

III. CVS

Linbox is stored in a CVS repository at the University of Delaware. To
access the latest bleeding edge copy of Linbox from this source, you
will need a working copy of CVS and all of the GNU development tools
(e.g. autoconf, automake, GNU make, and so on). To access CVS:

0. Make sure you have the necessary tools installed

You will need CVS installed. See http://www.cvshome.org/

You will need GNU Autoconf, GNU Automake, GNU Libtool, and the GNU
multiprecision library (GMP) to compile Linbox. Make sure the bin
directories of the first three of those are all in your PATH, e.g. if
you have Libtool installed in /usr/local/algebra/libtool, make sure
/usr/local/algebra/libtool/bin is in your PATH.

Also, if Automake is installed in a place separate from Autoconf, you
will need to set the environment variable ACLOCAL_FLAGS to "-I
<automake prefix>/share/aclocal", where <prefix> is the install prefix
of Automake. Similarly, if Libtool is installed to a separate prefix,
you should add "-I <libtool prefix>/share/aclocal" to ACLOCAL_FLAGS,
where <libtool prefix> is the install prefix of Libtool.

Of the four tools I have mentioned, only GMP is required if you are
installing from a tarball. GNU Autoconf, GNU Automake, and GNU Libtool
are only required for users of CVS and those individuals interested in
doing major development work on the library.

See http://www.gnu.org/software/autoconf/ for GNU Autoconf,
http://www.gnu.org/software/automake/ for GNU Automake, and
http://www.gnu.org/software/libtool/ for GNU Libtool.

1. Set your CVSROOT environment variable (on Bourne shell):

export CVSROOT=:pserver:<username>@linbox.pc.cis.udel.edu:/home/cvs

(and on the C shell):

setenv CVSROOT :pserver:<username>@linbox.pc.cis.udel.edu:/home/cvs

2. Log in to CVS; you only ever need to do this once for any given
Unix shell account:

cvs login

3. Check out the linbox module

cvs -z3 co linbox

The -z3 option compresses the data in transit, making the operation
faster for remote users.

4. Switch to the newly-created linbox directory and run the script
autogen.sh, optionally specifying the installation prefix:

cd linbox
./autogen.sh [--prefix=<prefix>] [options]

[options] include the following:

	--with-gmp<prefix>    Prefix of your GMP installation
	--with-ntl=<prefix>    Prefix of your NTL installation

GMP is *required* for the library to compile, so you must specify
--with-gmp=<prefix> if <prefix> is not a standard location such
as /usr or /usr/local otherwise you juste give the option --with-gmp.

5. Install the library:

make install

When you want to update your tree with the contents of the main CVS
repository, issue the following command from the linbox/ directory:

cvs -z3 up -dP

The -z3 option is as before and the -dP option tells CVS to update the
directory structure as well as the files. Note that the order of items
in that command *is* important.

You should receive some information on what files have been updated. 
If any files have a "U" or "P" before them, this means that there has
been a change.  You are getting an updated version. 
If any files have a "M" before them, this means that a change in the
repository has been merged with your version.  The appropriate question
is "should I commit my version to the repository?"
If any files have a "?" before them, this means that this is a file
that CVS (and hence the rest of the team) knows nothing about.  If it
is not a file created by build or install activity, the appropriate
question is "should I add this to the repository?"
If any files have a "C" before them, this means what you have
conflicts with what is in the repository. In other words, you made
changes while someone else made other changes and CVS does not know
how to reconcile the two. You will need to edit that file manually,
looking for and fixing lines like

that show the sections that could not be reconciled.

If you have made changes and would like to commit them to the global
repository, issue the command

cvs -z3 ci [<filename(s)>]

The optional filename(s) argument specifies what you would like to
commit; the default is to commit everything that has changed in the
current directory and its descendents. When you enter this command, a
text editor will come up prompting you for a log message. *ALWAYS
ENTER A LOG MESSAGE DESCRIBING WHAT YOU HAVE CHANGED*. Failure to do
so may result in your changes being backed out by the
administrator. When you are done entering your message, simply save
and exit the text editor.

If you are not a main Linbox developer but would like to submit some
addition or modification, your code is welcome. Please email a patch
(use 'cvs -z3 diff -u' to form a patch) to us and we will consider
including it.

IV. Coding standards

1. Indentation style

We use the Linux indentation style, i.e. K&R with 1-tab = 8-space indents. 
We would like to keep this standard, so please use it for any code
submitted to the project. The first line of code files should be
/* -*- mode: C++; style: linux -*- */
This will ensure linux indentation for emacs users.
We make two exceptions to this indentation pattern, however.
	1. There is no need to indent within the "namespace LinBox" block.
	2. public, private, protected tags may be indented a half-tab.
Here is an example:

namespace LinBox 
{
void myFunction (int a, int b, int c)
{
	int d;

	if (a == 0) {
		d = 1;
	}
	else if (a == 1) {
		d = 2;
		myOtherFunction (b, c);
	} else 
		d = 3;
} // myFunction

template <class T>
class MyClass : public MyOtherClass 
{
	int _b;

    public:
	MyClass (int a)
		: MyOtherClass (a), _b (0)
	{
	}
}; // MyClass
} // LinBox

2. Naming conventions

We use Java/Smalltalk conventions for naming classes, methods, and
variables. Classes whose names have several words have all the words
juxtaposed without underscores, and each word has its first letter
capitalized (e.g. MyClass, MyOtherClass). Methods are similar, except
that the first letter of the first word is lower case
(e.g. myMethod). Global constants should be all upper case with
underscores between the words (e.g. MY_CONSTANT). In addition,
variables that are members of classes should begin with an underscore
to differentiate them from methods and parameters (e.g. int _myMember;
int myMember () const;).

Directory and file names should be in lower case, with words separated
by a hyphen ('-'), e.g. my-file.h

We generally avoid abbreviations so as to avoid confusion among users
of the library. However, some very commonly used features are
abbreviated and some words commonly used together are treated as a
single word. For example, we use "minpoly" rather than
"MinimalPolynomial" and "Blackbox" rather than "BlackBox".

3. Licensing

This code is licensed under the GNU Lesser General Public License (see
COPYING for details); all contributed code should be similarly
licensed. We cannot accept any code that is released under a license
legally incompatible with the LGPL, so please either license the code
under the LGPL or explicitly place it in the public domain if you are
unsure. Technically, code released without a license at all and not
explicitly placed in the public domain is incompatible with the LGPL,
so licensing it is important.

3B. Intellectual property

The original author of a program holds the copyright to that program.
If another author changes the program, the changes are copyrighted to
that other author provided that in the preamble a change is announced
and that the places where the changes are made are annodated by the
initials of the author and a date.

4. Checklist for adding files

The procedure for adding a file is based on the type of file being
added.

4.A. Adding header files

In the text below <filename> refers to the file you are adding and
<dir> refers to the directory where the file you are adding is
located.

	1. Make sure the file has the correct format, with the
	   author's name and a copyright and license notice at the
	   file's top. Also make sure it follows coding standards to
	   the best of your ability.

	2. Open <dir>/Makefile.am and locate the list that starts with
	   include_HEADERS. Add your file to that list. If you add it
	   to the end of the list, make sure the preceding line ends
	   with a backslash '/'.

	3. Add an entry to linbox-new/ChangeLog of the following form:

		2002-02-03  Bradford Hovinen  <hovinen@ximian.com>

			* <dir>/Makefile.am (include_HEADERS): Added <filename>

	   Replace the date, name, and email I have given with the
	   current date and your own name and email.

	4. Run the command "cvs add <filename>" from the directory
	   where the file is located.

	5. Commit your changes with "cvs ci", issued from the
	   linbox-new directory. When the editor opens up to enter
	   your log entry, use the text that you just entered in the
	   ChangeLog.

4.B. Adding a test

All tests should go in the directory tests. They should be in the form
of a standalone program that can run a sensable test with no command
line arguments, preferably with a name prefixed by "test-". In the
text below, <test> refers to the name of your test binary,
e.g. test-minpoly. <mod-test> refers to the result of replacing all
"-" and "." characters in <test> with an underscore "_". <test-source>
refers to the name of the source file; the procedure works just as
well if you have multiple source files. By convention, the name of the
source file should be <test>.C

	1. As above, make sure the file has the correct format.

	2. Open tests/Makefile.am. Add <test> to the line that starts
	   with "BASIC_TESTS = ".

	3. You will see a list of blocks that look like:

		test_sparse_matrix_SOURCES = 		\
			test-0-matrix.C		\
			test-common.C	test-common.h

	   Below the last such block, add a block of the following form:

		<mod-test>_SOURCES = 		\
			<test-source>		\
			test-common.C	test-common.h

	4. Open tests/.cvsignore and add <test> on a line by itself
	   to that file.

	5. Open linbox-new/ChangeLog and add a block of the following
	   format:

		2002-02-03  Bradford Hovinen  <hovinen@ximian.com>

			* tests/Makefile.am (BASIC_TESTS): Added <test>

	6. Add the file to cvs with "cvs add <test-source>"

	7. Commit your changes with "cvs ci tests", issued from the
	   linbox-new directory. Use the text you entered in ChangeLog
	   for your log entry.

5. Miscellanae

We put all of our declarations in the namespace LinBox. Please put the
lines

namespace LinBox
{

... // Your code here

}

in all header files of contributed code.

All header files should have a set of preprocessor directives to
prevent multiple inclusion. If your header file is named
my-header-file.h, use

#ifndef __MY_HEADER_FILE_H
#define __MY_HEADER_FILE_H

... // Your code here

#endif // __MY_HEADER_FILE_H

surrounding the whole file, except possibly any comments you have at
the top.

All files should contain a comment at the top indicating the file
name, copyright, authors, and licensing. Additional documentation
would be useful. You may use any of the files in this library as a
template.

==================
The Linbox Team
