Okay, here’s a teaser on SDL 1.3 coding style from the discussion. Keep
in mind that no code is written yet, and everything is subject to change.
See ya!
-Sam Lantinga, Lead Programmer, Loki Software, Inc.
-------------- next part --------------
A guide to writing SDL library code - Sam Lantinga, May 28, 2001================================================================
Contents:
- License
- Language
- Datatypes
- Format
- API conventions
- Debugging
- Examples
License
SDL is released under the GNU Library General Public License. A full
copy of the license is included in the file “COPYING”, and is available
at: http://www.gnu.org/copyleft/lgpl.html
All patches and contributions to the SDL code are added under this license.
Language
SDL is written in strict ANSI C. This allows compilation on the
widest number of platforms, as well as bindings to many languages.
The API is declared as ‘extern “C”’ so that it can be used directly
in C++ code.
Whenever possible, the SDL code will compile without warnings under
gcc with the -Wall -ansi -pedantic options. Warnings often indicate
potential bugs or non-portable assumptions.
Platform independent SDL code should not directly contain system headers.
If the code relies on functions available in the standard C library, the
code should include “SDL_stdlib.h”, which includes stdlib.h, string.h,
ctype.h, as well as a definition of NULL as ((void *)0).
If the code relies on other functions, it is not considered portable and
should include portable implementations of those functions.
Static functions may be inlined for speed using the inline keyword,
defined in “SDL_stdlib.h”.
Datatypes
A set of platform independent datatypes are provided in “SDL_types.h”,
and should be used whenever specific datatype attributes are desired.
If using variables that are passed to system API calls, the correct
datatype should be used.
For example:
caddr_t, size_t, LPSTR, HANDLE
If using variables that have particular attributes, such as size,
then the SDL versions should be used:
Sint8 - signed 8-bit value
Uint8 - unsigned 8-bit value
Sint16 - signed 16-bit value
Uint16 - unsigned 16-bit value
Sint32 - signed 32-bit value
Uint32 - unsigned 32-bit value
SDL_string - a readable text string, typically ‘char *’ or ‘wchar_t’
If using variables that have no particular attributes, use native C
datatypes.
For example:
int, unsigned int, char *
Floating point should not be used as some architectures must perform
floating point operations using slow software emulation.
Format
SDL code is formatted in Stroustrup style, with tabstops set at every
4 characters, and tabs expanded to spaces. Spaces should be used to
enhance clarity, and the code should be wrapped logically when possible
at 78 characters.
The code should be written as clearly as possible, with comments added
to explain the logic behind complex code.
Each function prototype will include a documentation section which
contains return value, parameters, and non-driver-specific error
conditions. It will also contain a brief note on thread-safety.
The documentation section is set off by /** so documentation tools
can parse it easily.
API conventions
SDL functions are prefixed with “SDL_”, and either return void if they
can not fail, or return a status code of type ‘SDL_status’. This status
code is an enumerated type defined in “SDL_status.h”. The status is
defined such that any status less than zero is a failure of some kind.
If a function must provide additional information, it should save the
information in pointers to datatypes passed as function parameters.
For example:
/**
SDL_CreateObject - create a new object of some type
@param object
A pointer to an object handle, set to point to the new object
@param flags
A flag parameter controlling object creation
@return SDL_status
This function creates an object of some type. You can use this object
with other functions accepting this object. Please don’t write notes
this redundant for real functions.
You should watch out for X, Y, and Z, as they can surprise you.
How much useless documentation can I write for a fictional function?
Thread-safe: yes (or: no, accesses global data)
@see SDL_status, SDL_object
*/
SDL_status
SDL_CreateObject(SDL_object *object, Uint32 flags)
{
SDL_status status = SDL_OKAY;
object_state state;
SDL_object *new_object;
/* This comment adds clarity to the code */
status = internal_function(&state, flags);
if ( status < 0 ) {
return status;
}
/*
* Note that C++ style comments are not allowed by some compilers.
* Also, keep the code formatted to 78 characters if possible.
*/
if ( (status=condition_one(&state)) == SDL_OKAY) &&
(status=condition_two(&state)) == SDL_OKAY) ) {
new_object = create_simple_object(&state, flags);
if ( new_object ) {
add_additional_info(new_object, flags);
*object = new_object;
} else {
status = SDL_STATUS_OUTOFMEMORY;
}
}
return status;
}
Debugging
Whenever you want to provide more debug information to the application
beyond a simple status code, you may use SDL_DEBUG(), a macro defined
in “SDL_debug.h”. This macro is enabled by default, and defines a
function with the following prototype:
void SDL_debug(SDL_debugtype, SDL_debuglevel, const char *file, int line,
const char *fmt, …);
SDL_debugtype is an enumerated type, specifying the subsystem generating
the message. An unspecified subsystem, ‘SDL_DEBUG_GENERAL’, is always
available.
SDL_debuglevel is an enumerated type, specifying the criticality of the
message, one of: SDL_DEBUG_ERROR, SDL_DEBUG_WARNING, SDL_DEBUG_MESSAGE
The ‘file’ is the name of the source file generating the message, passed
via the FILE preprocessor directive.
The ‘line’ is the line in the source file, passed via the LINE
preprocessor directive.
The rest of the arguments form a stdarg format message which can be
up to 1K, and should not contain newline or other special characters.
SDL_debug() assembles a debug message and passes it to a debug callback
function which may be set with SDL_SetDebugCallback(callback).
The prototype for the callback function is:
void callback(SDL_debugtype, SDL_debuglevel, const char *file, int line,
const char *message);
An example of SDL_DEBUG() usage:
if ( non_fatal_condition() ) {
SDL_DEBUG(SDL_DEBUG_GENERAL, SDL_DEBUG_WARNING, __FILE__, __LINE,
"A non fatal condition was encountered: 0x%x", state);
}
For debugging purposes, you can also use the SDL_TRACE() macro, also
defined in “SDL_debug.h”. The SDL_TRACE() takes a numeric trace level
and a single message. The macro will only execute if the SDL library
is built with tracing on greater or equal to the given trace level.
The macro calls SDL_debug() with the current file and line, a debug
type of SDL_DEBUG_GENERAL, and a debug level of SDL_DEBUG_TRACE.
An example of SDL_TRACE() usage:
SDL_TRACE(1, "Entering debug area, watch your step");
if ( everything_ok() ) {
SDL_TRACE(3, "Proceeding normally");
} else {
SDL_TRACE(2, "Special condition, resetting and retrying");
}