Paul's Thoughts on Coding
Style and Philosophy

Over the years since 1962 when I first began writing programs, I have developed a style of coding that greatly enhances the ability of people, including myself, to read and understand the logic of the code.    Have you ever looked at a piece of code you wrote a few years ago and had difficulty following and understanding the code?   

Unix coding philosophy

It seems that the coding style currently being taught in universities is all about coding speed and neglects the poor guy (or gal) who must, some day, come behind the original coder and understand the program logic in order to repair or improve it.    Video displays used to view code have a very limited number of horizontal lines which can cause readers to be constantly scrolling up and down to understand the logic of a piece of code.    The inability of the reader to see a complete set of logic without scrolling, introduces an element of error, since the viewer must be doing two operations at once (reading/understanding and scroll) instead of just concentrating on understanding the logic.   

There are two objectives of computer coding:
1 get the computer to do what you want.
2 make the logic of the program easily understood by anyone reading the code.
This second objective us usually neglected or ignored (in the name of haste) by todays coders.

I believe that consistency in coding style is extremely important for the reader (the compiler couldn't care less).
At the end of this doc are some code snippets from msg.c in the infrastructure which illustrate the following guidelines.

Coding Guidelines:

/*H********************************************************************
* Opaque Request Response message system.
* Copyright Paul Turner Sept 1997
* "$Id: msg.c,v 1.67 2008/07/23 17:52:31 pturner Exp $";
*H*********************************************************************/
#include    
#include    
#include    
#include    "inf.h"
#include    "msg.h"

// ===================== DEFINITIONS ====================================
#ifndef _UCHAR
#define _UCHAR
typedef unsigned char uchar;
#endif
#define     DFLTTIMEOUT   10000             // 10 SEC
#define     MSGDFLTLEN    40000
#define     MSGDTF        0X00000001
#define     MSGREQ        0X00000002
#define     MSGPEND       0X00000004
#define     SEPCHR        ESC
#define     RNDUP(val,mdl) (mdl>0?((val +(mdl-1))&-mdl):val)
#define     barf( tblA )   _barf( tblA, sizeof( tblA ))

typedef struct msgs   {                         // MESSAGE CONTROL BLOCK
                int          sd;
                int          flags;
                int          type;
                int          code;
                int          reqId;
                int          eType;
                int          eCode;
                int          tid;
                char         questor[STRMAX];
                char         rPath[STRMAX];
                clok_t       stamp;
                char        *mp;
                char         peer[STRMAX];
        }msgs_t;

typedef struct msgThd    {                // MESSAGE THREAD CONTROL BLOCK
                int               tid;
                int               flags;
                char             *mp;
#ifdef INF_PTHREADS
                pthread_mutex_t   mut;
                pthread_cond_t    cond;
#else
                char             *mut;
                char             *cond;
#endif
        }mThd_t;

// ====================== PROTOTYPES ====================================
static int    freeHndl( int hndl );
static int    msgCtl( char *msg, char *ap );
static int    msgDconn( void *context, int sd );
static int    msgGetBigFld( int hndl, char *fNam, int typ, int outSiz, char *out);
static int    msgPutBigBin( int hndl, char *fldNam, int datLen, char *dat );
static int    msgPutBigStr( int hndl, char *fldNam, int datLen, char *dat );
static int    multiPktRcv( int hdl, char *fNam, int typ, int bSiz, void *dat);
static char  *pkt_rcv( int timOut );
static char  *pkt_rcvL( int timOut );
static int    msgReOpn( msgs_t *mc );
static char  *multiPktSnd( char *msg, int hndl );
static int    msg_snd( char*mp );
static int    newHndl();

// =================== GLOBAL VARIABLES =================================
static int     MsgTimeOut = DFLTTIMEOUT, MsgDfltLen = MSGDFLTLEN;
static int     HndlUse, HndlFree;
static msgs_t *Msgs[MAXMSGS];
static mThd_t  Mthd[MAXPTIDS];
#ifdef  INF_PTHREADS
static pthread_mutex_t   HndlLck = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t   RxLck   = PTHREAD_MUTEX_INITIALIZER;
#else
static char   *HndlLck;
static char   *RxLck;
#endif

CFG_BGN( "Msg" )               // CONFIGURATION VARIABLE DEFINITION
	CFG_INT( "MSG_DFLT_LEN", MsgDfltLen )
	CFG_INT( "MSG_DFLT_TIMOT", MsgTimeOut )
CFG_END

CTL_BGN                                       // INFCTL DEFINITIONS
	CTL_CB( "Msg", msgCtl )
CTL_END

/*F**********************************************************************
* DESC: Wait to receive a message.
* RTRN: message handle else ERR.
*F**********************************************************************/
int
msgRcv( int watTim )
{
	int        hndl;
	char      *mp, *sp;

	if( !(mp = pkt_rcv( watTim )) || ((int)mp == ERR) )
		return( (int)mp );
	hndl = newHndl();                  // ALLOCATE A HANDLE FOR THE NEW MESSAGE
	Msgs[hndl]->mp = mp;
	Msgs[hndl]->sd = ioGetHndl( mp );
	if( !Msgs[hndl]->peer[0] )
	{
		if( !(sp = ioGetPeer( mp )))
			return( trcErr( "no peer, discard msg, Sd %d", ioGetHndl(mp)));
		strcpy( Msgs[hndl]->peer, ioGetPeer( mp ) );
		zotChr( Msgs[hndl]->peer, ATSIGN );
	}
	moGetI( mp, "type", Msgs[hndl]->type );
	moGetI( mp, "code", Msgs[hndl]->code );
	moGetI( mp, "reqId", Msgs[hndl]->reqId );
	moGetI( mp, "msgTid", Msgs[hndl]->tid );
	moGetS( mp, "questor", Msgs[hndl]->questor );
	if( moGetI( mp, "execType", Msgs[hndl]->eType ) > 0 );
	{                                        // ITS A ROUTED MESSAGE
		moGetI( mp, "execCode", Msgs[hndl]->eCode );
		moGetS( mp, "rtrPath" , Msgs[hndl]->rPath );
	}
	moRew( mp );     // REWIND THE MESSAGE BEFORE RETURNING IT TO CALLER
	trc( TRC_MSG +20, "OK, hndl:%d, mp: 0X%08lX", hndl, (long)mp );
	return( hndl +1 );      // INCR HANDLE BEFORE RETURNING IT TO CALLER
}
/*F**********************************************************************
* DESC: make a response to a received message.
* RTRN: The new message handle.
*F**********************************************************************/
int
msgMkRsp( int oHndl, int stat )
{
	int       nHndl;
	char     *mpo, *mpn, *pp;
	msgs_t   *mcn;

	trc( TRC_MSG +20, "hndl: %d, stat %d", oHndl -1
		, stat );       	
	if( (--oHndl >MAXMSGS) || (oHndl <0) || !Msgs[oHndl]      // DECR HANDLE 
     	|| !(mpo=Msgs[oHndl]->mp))
		return( trcErr( "bad handle %d or no mp", oHndl));
	pp = ioGetPeer( mpo );
	zotChr( pp, ATSIGN );
	if( !(mpn = ioDupMsg( mpo, MsgDfltLen )))
		return( trcErr( "ioDupMsg error"));
	nHndl = newHndl();
	mcn = Msgs[nHndl];
	mcn->mp = mpn;
	moSetFlg( mpn, MO_RSP );                        // MARK MSG AS RESPONSE
	mcn->code = RESPONSE;
	mcn->type = Msgs[oHndl]->type;                    // MULTI-PKT NEEDS THIS
	mcn->reqId = Msgs[oHndl]->reqId;                  // MULTI-PKT NEEDS THIS
	if( Msgs[oHndl]->eType != 0 )
	{                     // ITS A ROUTER TYPE MESSAGE GET THE PERTINENT STUFF
		mcn->eType = Msgs[oHndl]->eType;
		mcn->eCode = Msgs[oHndl]->eCode;
		strcpy( mcn->rPath, Msgs[oHndl]->rPath );
	}
	strcpy( mcn->peer, pp );
	moRst( mpn, MsgDfltLen );
	if( trcIsMsk( TRC_SRC ) )
		moSetFlg( mpn, MO_TRC );
	moPutI( mpn, "type", Msgs[oHndl]->type );
	moPutI( mpn, "code", RESPONSE );
	moPutI( mpn, "status", stat );
	moPutI( mpn, "reqId", Msgs[oHndl]->reqId );
	if( Msgs[oHndl]->tid )                        //  NEW pt 08/30/07 @ 09:53
 		moPutI( mpn, "msgTid", Msgs[oHndl]->tid );
	if( Msgs[oHndl]->eType != 0 )
	{                // ITS A ROUTER TYPE MESSAGE PUT THE PERTINENT STUFF
		moPutI( mpn, "execType", Msgs[oHndl]->eType );
		moPutI( mpn, "execCode", Msgs[oHndl]->eCode );
		moPutS( mpn, "rtrPath", Msgs[oHndl]->rPath );
	}
	return( nHndl +1);                 // INCR HANDLE BEFORE RETURNING IT
}

/*F**********************************************************************
* DESC: Search a message for the next field.
* RTRN: OK, else ERR, else NOTFND.
*F**********************************************************************/
int
msgNxtFld( int hndl, char *fldNam, int *fLen )
{
	int       rtn, tot, cnt, len;
	char     *mp, *dp, nam[STRMAX], fNam[STRMAX], dat[STRMAX];

	if( (--hndl >MAXMSGS) || (hndl <0) || !Msgs[hndl] || !(mp=Msgs[hndl]->mp) )
		return( trcErr( "bad handle %d, Fld %s", hndl, fldNam));
	while( 1 )
	{
		if( moTstFldFlg( mp, "*", MOBIGFLD ) )
		{                          // CURRENT IS BIG FIELD, READ THROUGH IT
			moCurDat( mp, nam, dat );
			moGetI( mp, nam, tot );
			dp = malloc( MsgDfltLen +1);
			for( cnt =1; (tot >0) ; cnt++, tot -= len )
			{
				sprintf( fNam, "%s%c%d", nam, SEPCHR, cnt );
				len = multiPktRcv( hndl, fNam, MO_STR, MsgDfltLen +1, dp );
  			}
			free( dp );
		}
		if( (rtn = moNxtFld( mp, fldNam, fLen )) >0 )
		{
			if( moTstFldFlg( mp, "*", MOBIGFLD ) )
			{
				switch( rtn )
				{
					case MO_INT:
					case MO_BIN:
						break;
					case MO_STR: 
						if( moGetS( mp, fldNam, dat ) <=0 )
							trcErr( "bigFld [%s] Str get len failed", fldNam );
						*fLen = atol( dat );
						break;
				}
			}
			return( trc( TRC_MSG +20, "hndl: %d, %s, Typ:%d", hndl, fldNam, rtn), rtn);
		}
		if( !rtn && (moIsNxtRcd( mp ) || !moTstFlg( mp, MO_DTF )))
			return( NOTFND );
		ioFree( mp );
		trc( TRC_MSG +20, "receiving, hndl: %d", hndl );
		if( !MsgTimeOut )
		{
			rtn =trcErr( "MsgTimeOut Zero???" );
			break;
		}
		if( !(mp = pkt_rcv( MsgTimeOut )) || ((int)mp == ERR) )
		{
			rtn = 0;
			trcErr( "pkt_rcv timeout [%d] or err %d", MsgTimeOut, (int)mp );
			break;
		}
		Msgs[hndl]->mp = mp;
	}
	return( rtn );
}