Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

511 lines
16 KiB

Project Coding Conventions
***** Declarations, Naming and Hungarian
The following Hungarian conventions are used in the tree, as a minimum.
Other conventions may be added to these, but should not change the meaning of
any of these conventions. If a variable does not start with Hungarian,
it should begin with a capital letter (Foo) to so indicate. Otherwise,
the first letter after the Hungarian should be capitalized (pfnFoo).
These prefixes are ordered in the order of their precedence (So m_ is
before p is before fn, so you write m_pfnFoo).
Prefix Meaning Why
-------------------------------------------------------------------------------
g_ Global Prefix of global variables.
m_ Member of Class All methods of class will have these variables
always in scope. They need to be different to
protect the namespace in methods.
p Pointer Always helpful to know if variable is
pointer or pointer pointer (pp)
h Handle Denotes a reference to memory that cannot be
directly interpreted as a pointer
b Bool To distinguish TRUE/FALSE containing variable
from other integers
c Count (signed integer) To indicate that this integer contains a count
of something. Is signed so (--count < 0) tests
can be used.
f Floating point (single) To indicate native floating point type.
d Floating point (double)
fn Function Usually with pfn to indicate a pointer to a
function.
i Signed integer i and u are used to distinguish signed
and unsigned integers
o Offset Used to flag memory offsets. Useful in memory
structures in DSP and Chip simulations.
s String s and sz distinguish between non-zero
terminated and zero terminated strings.
sz Zero Terminated String
u Unsigned integer
'p' should be used in conjunction with a base type tag for pointers to
simple types, so a pointer to an unsigned integer is 'pu' rather than
just 'p'. Complex types do not have tags so pointers to structures or
objects will only have a 'p' prefix.
***** Differences From Other Hungarian Styles
Many kinds of Hungarian are used around the company, ranging from very
strict to very relaxed. The Hungarian described here is fairly relaxed and
the following Hungarian conventions are not used:
There is no distinction between far and near pointers. Pointers are
always 'p'; there is no 'lp'.
Arrays are not distinguished with a special prefix.
int iFoo[7] instead of int aiFoo[7] or int rgiFoo[7].
Functions are not tagged for return type.
int Foo() instead of int iFoo().
Variables holding flags are not specially distinguished.
UINT32 uFlags instead of UINT32 grfFlags or UINT32 fFlags.
Classes and structs do not have tags.
FooClass *pFoo instead of FooClass *pfcFoo.
Examples:
TCHAR g_szDllName[80];
PHANDLE phFile;
PD3DVERTEX pVtx;
C++ const's follow the Hungarian of their type. #define's are all cap's.
Classes are mixed case starting with a capital. Structures are all cap's, with
"tagNAME" used to name the structure, and "NAME" used to name the typedef:
typedef struct tagCHUNKELEM
{
struct tagCHUNKELEM *pNext;
EscNodeBase *pNode;
EscMatrix *pMatrix;
} CHUNKELEM, *PCHUNKELEM;
Structure types should always have a P<struct> typedef associated with
them and P<type> should be used in favor of <type> *.
***** Standard Types
A set of standard types of known size has been defined. These types
should be used for any data element that must be a particular size.
typedef signed char INT8;
typedef short int INT16;
typedef long int INT32;
typedef __int64 INT64;
typedef unsigned char UINT8;
typedef unsigned short int UINT16;
typedef unsigned long int UINT32;
typedef unsigned __int64 UINT64;
typedef float FLOAT;
typedef double DOUBLE;
If a data element does not require a particular size then the standard
INT and UINT types can be used. FLOAT and DOUBLE are IEEE standard formats
and take 32 and 64 bits, respectively.
The standard Win32 TCHAR should be used for strings where the character
set can be ANSI or Unicode. __TEXT() can be used to declare TCHAR
strings and the CRT file tchar.h has many standard routines #defined for
Unicode and ANSI builds.
***** Comments for Files, Functions and Code
Comments should use // instead of /* */ unless an in-line comment is
absolutely necessary.
All files must have a descriptive header comment which gives information
on the contents of the file and any other file-specific information.
C/C++ style:
//-----------------------------------------------------------------------------
//
// This file contains code dealing with foo and also bar.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//-----------------------------------------------------------------------------
Assembly style is the same except with ; instead of //.
;------------------------------------------------------------------------------
;
; This file has optimized routines for foo.
;
; Copyright (C) Microsoft Corporation, 1997.
;
;------------------------------------------------------------------------------
All functions and methods must have a header comment giving an overview
of what the function does, what its inputs are and what its outputs are.
C/C++ style:
//-----------------------------------------------------------------------------
//
// CreateFoo
//
// Takes a bar and a baz and creates a foo from them. If the foo is
// successfully created it is returned and the baz is updated to
// reflect the new count of foos using it.
//
//-----------------------------------------------------------------------------
Assembly style has ; instead of // and more information about exactly
how the code is entered and left. If the function is declared with
arguments then no explicit documentation is necessary in the header, but
if arguments are passed in registers then the header should indicate
this. Return values are assumed to be in eax unless otherwise specified.
;------------------------------------------------------------------------------
;
; CreateFoo
;
; Takes a bar and a baz and creates a foo from them. If the foo is
; successfully created it is returned and the baz is updated to
; reflect the new count of foos using it.
;
; Expects bar in eax and baz in ebx.
; Destroys ecx and edx.
;
;------------------------------------------------------------------------------
All code should have at least a simple comment for each basic block and
more comments as necessary. Assembly code should be heavily commented
with notes on register and FP stack usage, unusual tricks, instruction
pairing issues, etc.
Classes should generally have a function-like comment describing the
reason for their existence and an overview of their interface. Trivial
classes do not need a comment. Structs generally need only a mention of
their use, although if they have complicated features or methods they
may need a class-like header.
***** Microsoft Internal
Any code or comments which are for internal use only are bracketed as
follows. The brackets and text are stripped for the file versions which
are made public.
//@@BEGIN_MSINTERNAL
microsoft-only stuff here
//@@END_MSINTERNAL
***** File Naming
We'll be using a mix of C and C++ so we need to distinguish files
that are C-compatible from those that are not.
Use .c for plain C files.
Use .h for plain C headers or headers which can be included safely in
plain C files. This includes headers which have C++ constructs
protected by ifdef __cplusplus. .h files that may be included in C++
code should have internal extern "C" blocks.
Use .cpp for C++ files.
Use .hpp for C++-only headers.
***** General Code Style
Lines should not exceed eighty columns. This is much more pleasant for
those of us that do not use large windows.
Functions should be fewer than one hundred lines long unless structure
or performance requires a longer function. In general functions should
be even shorter, with sub-functions created as necessary.
Any commented-out code must have an explanatory comment with it
describing why it is commented out but not removed entirely.
Global variables should be avoided unless absolutely necessary.
Use uSize members of structs that may need to be resized later with
backwards compatibility. When using uSize make sure to validate sizes
everywhere to force callers to use it properly.
Headers should be protected with #ifndef <file> #define <file> #endif
blocks for inclusion safety.
***** C++ Usage Guidelines
C++ has a lot of things in it which can make code more difficult to read
or slower. The following is a list of suggestions on things to
avoid. These rules can be broken if necessary.
Avoid overloading operators.
Avoid default parameters.
Avoid multiple inheritance.
Avoid exceptions. This means that constructors cannot fail since they
can't return anything. If an object requires initialization that can
fail the constructor should put the object in an invalid state and a
method called Initialize should be used to fully create the object.
Avoid public data members. Use accessor methods instead.
Avoid placing method bodies inline in class declarations. Bodies of
inline methods should follow the class declaration in the header file.
Avoid naming conflicts with functions so that :: is not needed.
***** C/C++ Code Style
Indentation and spacing should be done entirely with spaces; no tabs
should be used. One indentation level is four spaces.
Braces should be on separate lines and aligned with each other. All
statements must be bracketed even if they are only a single line.
Case statements should align with the brackets of the switch. break
statements in case statements should be indented once from the case.
Functions should be declared so that their name begins on the first
character of a line. Return types, calling conventions and other
decorations should be on a preceeding line. Arguments can immediately
follow the name.
Functions should always declare a return type and use (void) if they
have no arguments.
Complete Example:
foo.hpp:
//-----------------------------------------------------------------------------
//
// This file contains the declaration of the Foo class.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//-----------------------------------------------------------------------------
#ifndef _FOO_HPP_
#define _FOO_HPP_
// Flags for the Foo class.
#define FOO_INVALID 0x00000001
#define FOO_MATCH 0x00000002
// Special numbers for checking.
#define FOO_RETURN_NEGONE 0xfefefefe
#define FOO_DO_NOTHING 0xefefefef
//-----------------------------------------------------------------------------
//
// class Foo
//
// The Foo class is responsible for keeping a buffer of things to check.
//
//-----------------------------------------------------------------------------
class Foo
{
public:
Foo(void);
BOOL Initialize(int cElts);
~Foo(void);
int Check(int iCheck);
inline UINT32 GetFlags(void);
private:
INT m_cElts;
INT m_cUsed;
PINT m_piBuffer;
UINT32 m_uFlags;
};
//-----------------------------------------------------------------------------
//
// Foo::GetFlags
//
// Accessor method for a Foo's flags.
//
//-----------------------------------------------------------------------------
inline UINT32
GetFlags(void)
{
return m_uFlags;
}
#endif // _FOO_HPP_
foo.cpp:
//-----------------------------------------------------------------------------
//
// This file contains the implementation of the Foo class.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//-----------------------------------------------------------------------------
#include "foo.hpp"
//-----------------------------------------------------------------------------
//
// Foo::Foo
//
// Initializes a Foo to an invalid state.
//
//-----------------------------------------------------------------------------
Foo::Foo(void)
{
m_piBuffer = NULL;
m_uFlags = FOO_INVALID;
m_cElts = 0;
m_cUsed = 0;
}
//-----------------------------------------------------------------------------
//
// Foo::Initialize
//
// Constructs a Foo.
//
//-----------------------------------------------------------------------------
BOOL
Foo::Initialize(int cElts)
{
// Allocate a buffer.
m_piBuffer = new int[cElts];
if (m_piBuffer == NULL)
{
return FALSE;
}
m_cElts = cElts;
m_uFlags = 0;
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Foo::~Foo
//
// Cleans up a Foo.
//
//-----------------------------------------------------------------------------
Foo::~Foo(void)
{
delete m_piBuffer;
}
//-----------------------------------------------------------------------------
//
// Foo::Check
//
// Checks for the given number in the buffer. If a match is found,
// return the index of the match. If no match is found, add the number
// to the buffer and return its index. If the buffer overflows, -1 is
// returned.
//
// If the number is one of the special numbers, return its special code.
//
//-----------------------------------------------------------------------------
int
Foo::Check(int iCheck)
{
int i;
// Check for initialization.
if (m_uFlags & FOO_INVALID)
{
return -1;
}
// Check for a special number.
switch(iCheck)
{
case FOO_RETURN_NEGONE:
return -1;
case FOO_DO_NOTHING:
break;
default:
break;
}
// Look for an existing match.
for (i = 0; i < m_cUsed; i++)
{
if (m_piBuffer[i] == iCheck)
{
m_uFlags |= FOO_MATCH;
return i;
}
}
// No match was found, so add the new number if there's space.
if (m_cUsed == m_cElts)
{
return -1;
}
m_piBuffer[m_cUsed] = iCheck;
return m_cUsed++;
}
***** Assembly Style
All assembly ops and registers should be in lower case. Each line is
indented eight spaces from the left margin. Assembler directives and
macros are always in uppercase.
Complete Example:
;------------------------------------------------------------------------------
;
; This file has optimized routines for foo.
;
; Copyright (C) Microsoft Corporation, 1997.
;
;------------------------------------------------------------------------------
.386p
.MODEL FLAT
.CODE
;------------------------------------------------------------------------------
;
; Foo
;
; Takes a pointer to a bar and returns the total bit count for it and its
; successor.
;
;------------------------------------------------------------------------------
Foo PROC PUBLIC,
pBar:PBAR
LOCAL cBits:DWORD
; Get bit count for current bar.
mov ecx, pBar
mov eax, [ecx+BAR_cBits]
mov cBits, eax
; Get successor bar in ecx.
push ecx
call UpdateBar
mov ecx, eax
; Sum bit counts for return.
mov eax, cBits
add eax, [ecx+BAR_cBits]
ret
Foo ENDP
END
***** Asserts, Debug Output and Other Debugging Aids
Assert checks should be placed where appropriate. These should be used
where unexpected but still possible bad things can happen.
Note that parameter validation will occur in the D3D runtime, so checking
of state and items like vertex type is not necessary.
We will use the new DX DPF support defined in newdpf.h.