CodingStyle
===========


This is a short document describing the preferred coding style for the
XviD  core library.   Coding  style  is very  personal,  and we  won't
_force_  our   views  on  anybody.   But  if   everybody  who  submits
patches/codes to the  CVS respect this coding style,  the whole source
would be easier to read/understand for all the others developers.



			Chapter 1: Indentation

Tabs are  4 characters, and  thus indentations are also  4 characters.
We use  tabs as indentation chars,  try not using spaces  as they make
the source code bigger.

In short,  8-char indents would have  made things easier  to read, and
would have the  added benefit of warning you  when you're nesting your
functions too deep. But because of  some parts of the XviD code source
has to use  lot of if/else/for statements together,  we have chosen to
set the standard tab length to 4 characters.

Setting  the tab  length to  4 doesn't  allow you  to write  deep code
paths. Try to  keep your code path as simple as  possible. More than 3
levels is  surely a piece of code  which needs to be  written again if
possible.


		      Chapter 2: Placing Braces

The other issue that always comes  up in C styling is the placement of
braces.  Unlike  the indent size,  there are few technical  reasons to
choose one placement  strategy over the other, but  the preferred way,
is to place the braces just a the end of the line : 

        if (x is true) {
            we do y
        } else {
            we do z
        }

This way we waste no lines with a single brace in it, and can add more
useful comments to the code.

Function and struct braces do not obey this rule, the braces are added
in the next line :

        int function(int x)
        {
            body of function
        }

        struct foo_t
        {
            body of the structure
        }
               
Note that the closing brace is empty on a line of its own, _except_ in
the cases where it is followed by a continuation of the same statement,
ie a "while" in a do-statement or an "else" in an if-statement, like
this:

        do {
            body of do-loop
        } while (condition);

and

        if (x == y) {
            ..
        } else if (x > y) {
            ...
        } else {
            ....
        }


			  Chapter 3: Naming

C  is  a Spartan  language,  and so  should  your  naming be.   Unlike
Modula-2 and Pascal  programmers, C programmers do not  use cute names
like ThisVariableIsATemporaryCounter.  A  C programmer would call that
variable "tmp", which is much easier  to write, and not the least more
difficult to understand.

HOWEVER, while  mixed-case names  are frowned upon,  descriptive names
for global variables are a must.  To call a global function "foo" is a
shooting offense.

GLOBAL variables (to  be used only if you _really_  need them) need to
have  descriptive  names, as  do  global  functions.   If you  have  a
function that counts the number  of active users, you should call that
"count_active_users()"   or  similar,   you  should   _not_   call  it
"cntusr()". Try not  to use global variables as  they break reentrancy
and XviD aims to be (in a long term) a threadable library.


Encoding the  type of  a function into  the name  (so-called Hungarian
notation) is brain  damaged - the compiler knows  the types anyway and
can  check those,  and it  only  confuses the  programmer.  No  wonder
MicroSoft makes buggy programs.

LOCAL variable names  should be short, and to the  point.  If you have
some random  integer loop counter,  it should probably be  called "i".
Calling it "loop_counter" is non-productive,  if there is no chance of
it being mis-understood.  Similarly, "tmp"  can be just about any type
of variable that is used to hold a temporary value.

If  you are  afraid to  mix  up your  local variable  names, you  have
another problem, which is called the function-growth-hormone-imbalance
syndrome.  See next chapter.

		
			 Chapter 4: Functions

Functions  should be short  and sweet,  and do  just one  thing.  They
should fit on one or two  screenfuls of text (the ISO/ANSI screen size
is 80x24,  as we all know),  and do one  thing and do that  well.

The  maximum length  of a  function is  inversely proportional  to the
complexity and indentation level of  that function.  So, if you have a
conceptually  simple  function that  is  just  one  long (but  simple)
case-statement, where you have to do lots of small things for a lot of
different cases, it's OK to have a longer function.

However,  if you  have  a complex  function,  and you  suspect that  a
less-than-gifted  first-year   high-school  student  might   not  even
understand what  the function is all  about, you should  adhere to the
maximum  limits  all the  more  closely.   Use  helper functions  with
descriptive names  (you can  ask the compiler  to in-line them  if you
think it's performance-critical, and it  will probably do a better job
of it that you would have done).

Another  measure of  the function  is the  number of  local variables.
They shouldn't exceed 5-10, or you're doing something wrong.  Re-think
the function,  and split  it into smaller  pieces.  A human  brain can
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.

NB :  This chapter does  not apply very  well to some XviD  parts, but
keep this "philosphy" in mind anyway.


			Chapter 5: Commenting

Comments  are good,  but there  is also  a danger  of over-commenting.
NEVER  try to  explain HOW  your code  works in  a comment:  it's much
better to write the code so  that the _working_ is obvious, and it's a
waste of time to explain badly written code.

Generally, you  want your  comments to tell  WHAT your code  does, not
HOW.  Also, try  to avoid putting comments inside  a function body: if
the function is  so complex that you need  to separately comment parts
of it, you should probably go back  to chapter 4 for a while.  You can
make  small comments  to  note or  warn  about something  particularly
clever (or ugly), but try  to avoid excess.  Instead, put the comments
at the head of the function, telling people what it does, and possibly
WHY it does it.


		      Chapter 6: Emacs settings

That's OK,  we all  do.  You've probably  been told by  your long-time
Unix user helper that "GNU  emacs" automatically formats the C sources
for  you, and  you've  noticed that  yes,  it does  do  that, but  the
defaults it uses are less than desirable (in fact, they are worse than
random typing  - a  infinite number of  monkeys typing into  GNU emacs
would never make a good program).

So, you  can either get rid  of GNU emacs,  or change it to  use saner
values.  To do the latter, you  can stick the following in your .emacs
file:

(defun xvid-c-mode ()
  "C mode with adjusted defaults for use with the XviD Sources."
  (interactive)
  (c-mode)
  (message "Loading xvid-c-mode")
  (c-set-style "K&R")
  (setq c-basic-offset 4)
  (setq indent-tabs-mode t tab-width 4)
  (turn-on-follow-mode)
  (toggle-truncate-lines)
  (setq make-backup-files nil)
  (setq column-number-mode t)
)

This  will define  the "M-x  xvid-c-mode command".   When  hacking the
library, if you  put the string -*- xvid-c -*-  somewhere on the first
two lines, this mode will be automatically invoked. Also, you may want
to add

(setq auto-mode-alist (cons '("/.*/xvidcore.*/.*\\.[ch]$" . xvid-c-mode)
                            auto-mode-alist))

to  your .emacs  file if  you want  to have  xvid-c-mode  switched on
automagically when you edit source files under */xvidcore/.


			  Chapter 7: indent

But even  if you fail in getting  emacs to do sane  formatting, or you
are using  another kind of editors  (vim?, vc++??, notepad  ??? <- you
crazy :-) everything is lost: use "indent". 

Now, again, GNU indent has the same brain dead settings that GNU emacs
has, which  is why  you need to  give it  a few command  line options.
However, that's  not too  bad, because even  the makers of  GNU indent
recognize the authority  of K&R (the GNU people  aren't evil, they are
just severely misguided  in this matter), so you  just give indent the
options : 

-bad -bap -nbbo -nbc -br -c33 -cd33 -ncdb -ce -ci4 -cli0 -cp33 -cs -d0
-di1 -nfc1 -nfca -nhnl -i4 -ip0 -l79 -lp -npcs -nprs -psl -saf -sai
-saw -nsc -nsob -nss -ut -ts4 -bfda

Look at the  man pages for more details  about each option. Basically,
our style is very close to the K&R one.

"indent" has a lot of options, and especially when it comes to comment
re-formatting you  may want to  take a look  at the manual  page.  But
remember: "indent" is not a fix for bad programming.


			Chapter 8: Reentrance

Well, at  the moment, XviD is  not a reentrant  library because during
its development, some mistakes have  been comited. But reentrance is a
long term aim  for this project so you should not  write code which is
not reentrant.

To ensure you're writting reentrant code, check that :

  - you're not using global variables (except constants because
    they're used in read only access). 
  - you're not using static variables (except constants because
    they're used in read only access).
  - functions use only local variables.
  - functions do not return data locally allocated on the stack.


			   Chapter 9: Types

A while  ago, almost  all variables got  an extra type,  like int32_t,
uint8_t  etc...  to make  them  of  identical  size on  all  platforms
(defined in compiler specific  headers or in src/portab.h). You should
use  those  types  only  when  really needed.  When  defining  a  loop
variable, you must  use platform natural types defined  as 'int'. This
makes the code  faster because the compiler transforms  the int in the
natural size  of the CPU :  32 bit on  32 bit CPUs (x86,  powerpc) and
64bit on 64 bit CPUs (ultra sparc, AMD hammer, Intel Itanium, Motorola
powerpc64)

But  don't forget  that  the  minimum platform  targeted  by the  XviD
library is a  32bit cpu. So a  'int' should (never say 'is'  in such a
case) always be 32bit long (or bigger)


		       Chapter 10: Portability

The  code  _must_ be  portable.  Don't  use  specific functions  to  a
compiler/OS/libC.  Don't  use  specific  compiler pragmas,  or  syntax
extensions. The code _must_ be ANSI C  compliant  to ease  portability
on exotic platforms with only ANSI C compilers, much  more  widespread
than ISO C99 compilers.

Btw, if you  have to use those deprecated/not  portable features, then
use the src/portab.h to write a wrapper for each targeted system. 

For the moment, the supported platforms are :
  - Win32 family (x86) with VC++
  - Cygwin env (bypassing the cygwin.dll with -mno-cygwin flag)
  - Mingw + Minsys
  - GNU/Linux (x86 and  ppc for optimized code, or  any other arch for
    the pure C version of the library)
  - *BSD (same archs as GNU/Linux)
  - Solaris.

Last edited: $Date: 2004/03/22 22:36:23 $
