
 *********************************************************************
 *                      SOS Coding Conventions                       *
 *********************************************************************

This is a brief description of SOS Coding Conventions.  There are two
sections, strongly recommended and required.  The former are basically
formatting issues, the latter are more techincal details which all
programs must use for commonality and ease of maintenance.

Please see hello.c in the libsos/test directory for examples of a
completely SOSified program.


			     Recommended
**********************************************************************

The following elisp code will get the behavior we want for indention
et al:

--------------------------------------------------
(defun SOS-c-mode-common-hook ()
  "Do what SOS wants for C"
  (interactive)
  (setq comment-column 48)
  (setq c-hanging-comment-ender-p nil)
  (setq c-hanging-comment-beginner-p nil)
  (c-set-style "GNU")
  (setq c-hanging-comment-ender-p nil)
  (setq c-hanging-comment-beginner-p nil)
  )
(add-hook 'c-mode-common-hook 'SOS-c-mode-common-hook)
--------------------------------------------------

Example:
--------------------------------------------------



/*
 * This is a multiline comment
 */
int
main(int argc, char **argv, char **envp)
{
  SOS_ENTRY("hello","main",NULL);

  if (argc)					/* Braces on seperate lines */
    {
      printf("argc == %d\n",argc);
    }

  if (argc)					/* Standard 2 character indent */
    printf("argc == %d\n",argc);

  SOS_RETURN(0);
}
----------------------------------------------------------------------
/*
Please note the three lines of whitespace before the function.
Please note the multi-line comment before the function
Please note comments in column 48 (standard)
Please note two character intents
Please note brace location
Please note use of SOS_ENTRY and SOS_RETURN (described later)


Makefiles
----------------------------------------------------------------------

You are encouraged to use the SOS Makefile conventions which provide
dependancies, trivial program compilation, automagic directory
hierarchy handling, and architecture-specific compilation directories
with very little fuss.

----------------------------------------------------------------------



 *********************************************************************
 *                     REQUIRED SOS CONVENTIONS                      *
 *********************************************************************


SOS function entry/exit functions
----------------------------------------------------------------------

SOS_ENTRY and the various forms of SOS_RETURN are one of the
underlying pillars of the SOS coding convention.  These functions can
be leveraged to give a wide varity of features which are incredibly
useful, especially for debugging and maintenance.

Whenever you write a function, make SOS_ENTRY() the *first* line in
it, and place SOS_RETURN() whereever you would normally return().

SOS_ENTRY does a few things for us.  First it makes it a little more
obvious where a function starts when scanning through the code.
Second, when sos_fun debugging is turned on, we can watch as every
function is entered and exited.  Third, it provides a SOS-stack so we
can tell who called us and print in a portable manner, the list of who
called whom if an error occurs.  Forth, it sets the per-function
debugging levels so that the SOS debugging functions know what
debugging level we are currently at.  Fifth, and from current
experiences least useful, it provides a way to have functions called
when the current function exits.  If you have SIGSEGV trapped,
as we recommend, we can get a backtrace of what function we died
in without necessarily having to find or use a core file.

SOS_RETURN performs cleanup, printing, and such activities.  The
variants of SOS_RETURN are not normally needed--they are used mainly
if you want to preserve errno, if the return value of the function is
a function itself (SOS_RETURN(foo())) and you don't want it to appear
as if the current function exited before foo was called, and stuff
like that.

The only time you should not use these functions are:

* In signal handlers

* In CLC comparison functions (and even then, you probably should have
  it present and #ifdef'd out)

----------------------------------------------------------------------



SOS debugging functions
----------------------------------------------------------------------

Instead of having per-program debugging routines which vary in usage
and are hard to narrow down to debug just what you are looking for,
please use sos_debug_*.  These functions allow you to specify
per-function and per-package debugging levels.  You can load the
current debugging levels from a SOS config file or manually.  The
output of the debugging is directly to whereever is required, and the
overhead is not too bad if debugging is turned off.  The current
function's debugging level is set by SOS_ENTRY.

It is recommended that you use the debugging level as a bitfield
(e.g. use sos_debug_printf_and), but if that doesn't make sense for a
particular function, you can use the _gt or _eq debugging routines.

It is strongly recommended that you document the debugging levels in
the leading function comment or in the leading file comment.

----------------------------------------------------------------------



SOS error functions
----------------------------------------------------------------------

The sos error functions are primarily designed for the purpose of
performing error reporting to higher level functions/humans in a
library (you cannot syslog--you don't know if syslog is initialized &&
you cannot printf since you don't know if any channel is open or
appropreate).  Use them where you normally would do a perror or
something.  The following is very common:

--------------------------------------------------
  if (foo() < 0)
    {
      sos_error_printf("foo failed while frobbing the baz: %s\n",strerror(errno));
      SOS_RETURN(-1);
    }
--------------------------------------------------

----------------------------------------------------------------------



Event queues
----------------------------------------------------------------------

If you have to have events running at points in the future (cron or at
like), please use the sos_eventq routines.  This provides a common
interface to future events and is generic so other things can be
easily added to it.

----------------------------------------------------------------------



CLC high level data structures
----------------------------------------------------------------------

You are forbidden--verbotten--to write ANY linked lists, hash tables,
B trees or anything like that.  CLC provides out of band
data-structures which are bugfree, efficient, and help improve good
coding standards.  We rarely use anything except non-sorted dll
(doubly linked lists), hash tables, and occasionally priority queues.

----------------------------------------------------------------------


soslog
----------------------------------------------------------------------

Use soslog instead of syslog--it is easier to parse automagically and
allows us to, via debugging, to see the stuff being syslogged.

----------------------------------------------------------------------


setProcTitle
----------------------------------------------------------------------

Tell the admins what the hell is going on!  use setProcTitle.

----------------------------------------------------------------------


configuration files
----------------------------------------------------------------------

Don't code custom configuration files for simple values like what port
to use or default host names or whatever.  Use SOS config files
whenever you need simple configuration files.

You still should use lex/yacc for complex files, but even if you have
such a file, defaults and the like should perhaps go in the SOS config
file.

----------------------------------------------------------------------


Internationalization
----------------------------------------------------------------------

You are encouraged to use SOS_GWD instead of constants when printing
messages which users (not admins) will see, so that we have *some*
support for foreign languages.  Full I8N (or whatever it is) support
with wide characters and per-user language selection may be slightly
harder :-)

----------------------------------------------------------------------


Return codes
----------------------------------------------------------------------

Check for return codes.  Yes even for malloc().  Use sos_error a lot.

----------------------------------------------------------------------


CVS
----------------------------------------------------------------------

All source code must be maintained by CVS

----------------------------------------------------------------------


libsos usage
----------------------------------------------------------------------

You are strongly encouraged to use libsos.  For example, looking up IP
addresses or host names is important to get right and important to
take all reasonable permutations, so calling sos_gethbyname() instead
of trying to hack something with inet_atoi and/or gethostbyname is a
loosing proposition.

Network code particularily will benifit by using make_conn, get*by*,
get_conn, bdrelay, and stuff like that.

Terminal-handling stuff is right and easy to use.  sos_signal provides
a portable and consistant way of using signals, etc...

libsos will make your programs more reliable, more portable, and more
maintainable and will decrease your coding time.

libsos:  like it, love it, live it!

----------------------------------------------------------------------
