Skip to content

Commit

Permalink
Merge pull request #411 from shelhamer/readme-whitespace-and-versioning
Browse files Browse the repository at this point in the history
Developer Readme whitespace and versioning
  • Loading branch information
Soeren Sonnenburg committed Apr 2, 2012
2 parents a17ad85 + 787d681 commit 142a356
Showing 1 changed file with 79 additions and 38 deletions.
117 changes: 79 additions & 38 deletions src/README.developer
Expand Up @@ -73,7 +73,7 @@ int main(int argc, char** argv)
for (int32_t i=0; i<6; i++)
matrix[i]=i;

// create three 2-dimensional vectors
// create three 2-dimensional vectors
// shogun will now own the matrix created
CRealFeatures* features= new CRealFeatures();
features->set_feature_matrix(matrix, 2, 3);
Expand Down Expand Up @@ -166,11 +166,26 @@ FORMATTING:
for vim in ~/.vimrc

set cindent " C style indenting
set ts=4 " tabstop
set ts=4 " tabstop
set sw=4 " shiftwidth

- avoid whitespaces at end of lines and never use them for indentation; only
ever use tabs for indentations
- for newlines use LF only; avoid CRLF and CR. Git can be configured to convert
all newlines to LF as source files are commited to the repo by:

git config --global core.autocrlf input

(for more information consult http://help.github.com/line-endings/)

- avoid trailing whitespace (spaces & tabs) at end of lines and never use spaces
for indentation; only ever use tabs for indentations.

for emacs:

(add-hook 'before-save-hook 'delete-trailing-whitespace)

for vim in ~/.vimrc (implemented as an autocmd, use wisely):

autocmd BufWritePre * :%s/\s\+$//e

- semicolons and commas ;, should be placed directly after a variable/statement

Expand Down Expand Up @@ -209,7 +224,8 @@ ever use tabs for indentations
//foo
}

however exceptions are OK if readability is increased (as in function definitions)
however exceptions are OK if readability is increased (as in function
definitions)

- don't put multiple assignments on a single line

Expand Down Expand Up @@ -257,17 +273,17 @@ MACROS & IFDEFS:
- use macros sparingly
- avoid defining constants using macros (bye bye typechecking), use

const int32_t FOO=5;
const int32_t FOO=5;

or enums (when defining several realted constants)

instead

- use ifdefs sparingly (really limit yourself to the ones necessary)
as their extreme usage makes the code completely unreadable. to achieve
that it may be necessary to wrap a function of (e.g. for
pthread_create()/CreateThread()/thread_create() a wrapper function to create a
thread and inside of it the ifdefs to do it the solaris/win32/posix way)
- use ifdefs sparingly (really limit yourself to the ones necessary) as their
extreme usage makes the code completely unreadable. to achieve that it may be
necessary to wrap a function of (e.g. for
pthread_create()/CreateThread()/thread_create() a wrapper function to create a
thread and inside of it the ifdefs to do it the solaris/win32/posix way)
- if you need to use ifdefs always comment the corresponding #else / #endif
in the following way:

Expand All @@ -293,8 +309,9 @@ TYPES:

- classes must be (directly or indirectly) derived from CSGObject

- don't use fprintf/printf, but SG_DEBUG/SG_INFO/SG_WARNING/SG_ERROR/SG_PRINT (if in a from
CSGObject derived object) or the static SG_SDEBUG/... functions elsewise
- don't use fprintf/printf, but SG_DEBUG/SG_INFO/SG_WARNING/SG_ERROR/SG_PRINT
(if in a from CSGObject derived object) or the static SG_SDEBUG/... functions
elsewise

FUNCTIONS:

Expand All @@ -307,47 +324,48 @@ FUNCTIONS:
generally easily keep track of about 7 different things, anything more
and it gets confused. You know you're brilliant, but maybe you'd like
to understand what you did 2 weeks from now.

GETTING / SETTING OBJECTS

If a class stores a pointer to an object it should call SG_REF(obj) to
increase the objects reference count and SG_UNREF(obj) on class desctruction (which will
decrease the objects reference count and call the objects destructor if ref_count()==0.
Note that the caller (from within C++) of any get_* function returning an object should
also call SG_UNREF(obj) when done with the object. This makes the swig wrapped interfaces
automagically take care of object destruction.

If a class function returns a new object this has to be stated in the corresponding swig
.i file for cleanup to work, e.g. if apply() returns a new CLabels then the .i file
should contain %newobject CClassifier::apply();

If a class stores a pointer to an object it should call SG_REF(obj) to increase
the objects reference count and SG_UNREF(obj) on class desctruction (which will
decrease the objects reference count and call the objects destructor if
ref_count()==0. Note that the caller (from within C++) of any get_* function
returning an object should also call SG_UNREF(obj) when done with the object.
This makes the swig wrapped interfaces automagically take care of object
destruction.

If a class function returns a new object this has to be stated in the
corresponding swig .i file for cleanup to work, e.g. if apply() returns a new
CLabels then the .i file should contain %newobject CClassifier::apply();

NAMING CONVENTIONS:

- naming variables:
- in classes are member variables are named like m_feature_vector (to avoid
shadowing and the often hard to find bugs shadowing causes)
shadowing and the often hard to find bugs shadowing causes)
- parameters (in functions) shall be named e.g. feature_vector
- don't use meaningless variable names, it is however fine to use short names
- don't use meaningless variable names, it is however fine to use short names
like i,j,k etc in loops
- class names start with 'C', each syllable/subword starts with a capital letter,
e.g. CStringFeatures
e.g. CStringFeatures

- constants/defined objects are UPPERCASE, i.e. REALVALUED

- function are named like get_feature_vector() and should be limited to as few arguments as
possible (no monster functions with > 5 arguments please)
possible (no monster functions with > 5 arguments please)

- objects which can deal with features of type DREAL and class SIMPLE don't need
to contain Real/Simple in class name
to contain Real/Simple in class name

-others are required to clarify class/type they can handle, e.g.
CSparseByteLinearKernel, CSparseGaussianKernel
- others are required to clarify class/type they can handle, e.g.
CSparseByteLinearKernel, CSparseGaussianKernel


-variable and function names are all lowercase (except for class Con/Destructors)
syllables/subwords are separated by '_', e.g. compute_kernel_value(), my_local_variable
- variable and function names are all lowercase (except for class Con/Destructors)
syllables/subwords are separated by '_', e.g. compute_kernel_value(), my_local_variable

-class member variables all start with m_, e.g. m_member (this is to avoid shadowing)
- class member variables all start with m_, e.g. m_member (this is to avoid shadowing)

- features
-featureclass Simple/Sparse
Expand All @@ -362,7 +380,30 @@ syllables/subwords are separated by '_', e.g. compute_kernel_value(), my_local_v

VERSIONING SCHEME:

- an automagic version will be created from the date of the last svn update.
if that is not enough make releases:
The git repo for the project is hosted on GitHub at
https://github.com/shogun-toolbox/shogun. To get started, create your own fork
and clone it. Remember to set the upstream remote to the main repo by:

git remote add upstream git://github.com/shogun-toolbox/shogun.git

Each time you want to develop new feature / fix a bug / etc consider creating
new branch using:

git checkout -b new_feature_name

While being on new_feature_name branch, develop your code, commit things and do
everything you want.

Once your feature is ready (please consider larger commits that keep shogun in
compileable state), rebase your new_feature_name branch on upstream/master
with:

git fetch upstream
git checkout master
git rebase upstream/master
git checkout new_feature_name
git rebase master

and send a pull request.

e.g.: svn cp trunk releases/shogun_0.1.0
To make a release, refer to the Makefile in the root dir of the repo.

0 comments on commit 142a356

Please sign in to comment.