SDL 1.3 Coding Guide

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");
}

It might be a good idea to post a profile for “indent” which provides the
correct formatting, just to make things a little easier.

-RayOn Monday 28 May 2001 10:34, you wrote:

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.

Just one very quick thought on something I found in the guide, SDL_string,
under `Datatypes’.

While I think that something like this is a very good thing (for many reasons,
the least of which identifying your application to the OS), I would like to
state that we should be careful in its implimentation. Too often higher level
libs impliment their own string data types, and inadvertantly break
compatibility with other data types from core or even other libs.

By way of an example, a C++ mail importing/exporting lib I have recently been
working on has run into a snag between Qt’s QString and a string data type used
by another high level lib.

In other words, I think this is a good idea, but we need to be able to get
standard char * and C++ strings (among other things) easily from it. (I guess I
am stating the obvious… but I wouldn’t feel a need if I didn’t already run
into problems like this with other libs before ;-)On Mon, 28 May 2001, you wrote:

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.

Content-Type: text/plain; name=“CodingGuide.txt”


Sam “Criswell” Hart <@Sam_Hart> AIM, Yahoo!:
Homepage: < http://www.geekcomix.com/snh/ >
PGP Info: < http://www.geekcomix.com/snh/contact/ >
Advogato: < http://advogato.org/person/criswell/ >

This is a nice looking beginning of a spec. My comments below are
mostly limited to “raising a flag” in areas that my experience
dictates you may encounter problems…

Sam Lantinga writes:

Static functions may be inlined for speed using the inline keyword,
defined in “SDL_stdlib.h”.

Anything which begins with underscores may be used internally by a
compiler. The keyword “inline” in particular, with one or two
underscores preceding or trailing, may cause you problems as various
compilers use it. I’d suggest using your otherwise standard
convention of a module prefix, and specify an inline function with
SDL_INLINE for greatest portability.

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’

Ditto here, re: prefixing the type with SDL. Since SDL applications
are often linked with other libraries and may include other libraries’
include files – each of which might define these type names slightly
differently – using the SDL prefix (e.g. SDL_Uint16) would provide
the least chance of conflict. (This suggestion based on many years of
experience and fighting this problem on multiple occasions.)

Format

SDL code is formatted in Stroustrup style

I don’t happen to like this style (I find opening braces at ends of
lines difficult to match with their closing brace; I like opening
braces at the beginning of the next line), but you’ll never get
consensus on style. Select what you like, and dictate it.

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.

SDL_status
SDL_CreateObject(SDL_object* *object, Uint32 flags)

You may also want to specify the order of parameters. My preference
is that all input parameters come first, followed by input/output
parameters, followed by output parameters. You seem to prefer the
opposite order, since you put the output parameter SDL_object first.
In either case, consistency is nice to have, so specifying which way
it should be implemented would be beneficial.

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, …);

Since C macros don’t allow for variable-length argument lists, it’s
not possible to comment out all of these debug statements (for speed)
without cluttering the source code with #ifdefs around each call to
SDL_DEBUG() – which kind of defeats the purpose of having a nice
macro for the debug function. To avoid this problem, call the macro
with an extra set of parenthesis around the entire argument list:

    SDL_DEBUG((SDL_DEBUG_GENERAL, SDL_DEBUG_WARNING, __FILE__, __LINE__,
               "A condition was encountered: 0x%x", state));

Then SDL_DEBUG() is defined as:

#ifdef SDL_ENABLE_DEBUG
#  define SDL_DEBUG(params)       SDL_debug params
#else
#  define SDL_DEBUG(params)
#endif

The macro actually contains only one parameter, which is the entire
parameter list to SDL_debug. If SDL_ENABLE_DEBUG is defined (e.g. in
a makefile or at the top of SDL_debug.h) then the parameter list is
provided to the SDL_debug function. Otherwise, when debugging is
disabled (as at release time) no function is called, no code is
executed, and the best speed advantage is achieved.

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);

I’m curious as to why you do it this way? Why not just have SDL_debug
be a user-provided function (with a default version in the SDL library
which is linked if the user doesn’t provide one)? This would
eliminate the 1k limit and provide a generalized debug interface to
the application programmer. This would be my strong preference.

For debugging purposes, you can also use the SDL_TRACE() macro, also

SDL_TRACE can be defined as above, to use the extra set of parenthesis
to allow completely removing the code at release time, for better
speed.

#ifdef SDL_ENABLE_TRACE
#  define SDL_TRACE(params)       SDL_trace params
#else
#  define SDL_TRACE(params)
#endif

Hope this help.

Cheers,

Derrell

Derrell Lipman wrote:

This is a nice looking beginning of a spec. My comments below are
mostly limited to “raising a flag” in areas that my experience
dictates you may encounter problems…

Me too, it’s a good spec.

Static functions may be inlined for speed using the inline keyword,
defined in “SDL_stdlib.h”.

Anything which begins with underscores may be used internally by a
compiler. The keyword “inline” in particular, with one or two
underscores preceding or trailing, may cause you problems as various
compilers use it. I’d suggest using your otherwise standard
convention of a module prefix, and specify an inline function with
SDL_INLINE for greatest portability.

Well, newest C99 has done the reserved-keywords even differently
(underscore+uppercaseletter), partly to avoid older schemes I guess.
AFAIRC, yes, “inline” has some problems in some environments.

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’

Ditto here, re: prefixing the type with SDL. Since SDL applications
are often linked with other libraries and may include other libraries’
include files – each of which might define these type names slightly
differently – using the SDL prefix (e.g. SDL_Uint16) would provide
the least chance of conflict. (This suggestion based on many years of
experience and fighting this problem on multiple occasions.)

it would … because every lib wants a short portable thing of these,
and they don’t #define (so double-incarnation can be check with #defined).
That’s the reason we have stdint.h at last, and really, one
can indeed use it - have a configure-check where the stdint.h
typedefs are (stdint.h inttypes.h), include it to SDL_xxxx.h
and possibly define what’s missing. It does indeed work, and at last
it turned into an autoconf-macro that is atleast an example:
http://www.gnu.org/software/ac-archive/C_Support/ac_need_stdint_h.html

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.

SDL_status
SDL_CreateObject(SDL_object* *object, Uint32 flags)

You may also want to specify the order of parameters. My preference
is that all input parameters come first, followed by input/output
parameters, followed by output parameters. You seem to prefer the
opposite order, since you put the output parameter SDL_object first.
In either case, consistency is nice to have, so specifying which way
it should be implemented would be beneficial.

I’ve heard that argument mostly around corba, instead leave them
as is, partly ordered by importance - arguments that may be sent
as literal-“0” should always be last, “flags” is a good candidate,
and the “context” as first parameter (resembling “this”).

– guido http://savannah.gnu.org/projects/ac-archive
31:GCS/E/S/P C++$++++ ULHS L++w- N++@ d(±) s+a- h.r(*@)>+++ y++ 5++X-

Ray Kelm wrote:

It might be a good idea to post a profile for “indent” which provides the
correct formatting, just to make things a little easier.

http://www.fnal.gov/docs/working-groups/c++wg/indenting.html
says: indent -bad -bap -nbc -nce -i4
and choose between “-bl” and “-br”. (-br for Sam I guess).

Derrell Lipman wrote:

I don’t happen to like this style (I find opening braces at ends of
lines difficult to match with their closing brace; I like opening
braces at the beginning of the next line), but you’ll never get
consensus on style. Select what you like, and dictate it.

Actually, I’come to like a mix between “-br” and “-bl” - all the
loop-constructs while/for have brace on the next line, and “if”'s brace
goes on the same line. Makes it even more easy to just “see” the flow.

– guido http://guidod.4t.com
31:GCS/E/S/P C++$++++ ULHS L++w- N++@ d(±) s+a- y++ 5++X-

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.

[…]

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

To this day, I am AMAZED that these typedefs haven’t conflicted with any
other code. Granted, they are nice and susinct, which I like, but should
we consider the namespace and change them or prefix “SDL_” to them in SDL2?

–ryan.

Hmmm.

I’ve gotten name conflicts from the SDL libraries in my code. It was
interesting debugging it too, since my symbol was in the data segment,
where the library symbol was a subroutine (how the hell did I get here?)

Cheers,
-klsOn Mon, May 28, 2001 at 04:19:02PM -0700, Ryan C. Gordon wrote:

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.

[…]

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

To this day, I am AMAZED that these typedefs haven’t conflicted with any
other code. Granted, they are nice and susinct, which I like, but should
we consider the namespace and change them or prefix “SDL_” to them in SDL2?

–ryan.


// .–=,
…::://::::::::::::::::::::::::::::… (o O & @kevin_at_ank.com
:::::::://:::://://://:/:://::||// / V K
:::::://:::://:/:|//’/’ // ,|’ r , ‘qk
:’’’/
__ // / // |_// // || .’~. .~`,
kls _/-=_/

Derrell Lipman wrote:

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, …);

Since C macros don’t allow for variable-length argument lists, it’s
not possible to comment out all of these debug statements (for speed)
without cluttering the source code with #ifdefs around each call to
SDL_DEBUG() – which kind of defeats the purpose of having a nice
macro for the debug function. To avoid this problem, call the macro
with an extra set of parenthesis around the entire argument list:

    SDL_DEBUG((SDL_DEBUG_GENERAL, SDL_DEBUG_WARNING, __FILE__, __LINE__,
               "A condition was encountered: 0x%x", state));

This is simply not true! CPP (C Pre-Processor) macros can have variable
length argument lists. I use them for my own debuging code which,
coincidently, works almost exactly like this. The define goes like

#define SDL_DEBUG(type, level, string, ARGS…) SDL_debug(type, level,
string, ARGS)

And to remove it, use a definition like this:

#ifdef SDL_ENABLE_DEBUGING
… see above for define …
#else
#define SDL_DEBUG(type, level, string, ARGS…)
#endif

cpp is wiley little program!!

-- David Snopek

/-- libksd –
| The C++ Cross-Platform Game Framework
| Only want to write it once??
| http://libksd.sourceforge.net
------------

David Snopek wrote:

Derrell Lipman wrote:

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, …);

Since C macros don’t allow for variable-length argument lists, it’s
not possible to comment out all of these debug statements (for speed)
without cluttering the source code with #ifdefs around each call to
SDL_DEBUG() – which kind of defeats the purpose of having a nice
macro for the debug function. To avoid this problem, call the macro
with an extra set of parenthesis around the entire argument list:

    SDL_DEBUG((SDL_DEBUG_GENERAL, SDL_DEBUG_WARNING, __FILE__, __LINE__,
               "A condition was encountered: 0x%x", state));

This is simply not true! CPP (C Pre-Processor) macros can have variable
length argument lists. I use them for my own debuging code which,
coincidently, works almost exactly like this. The define goes like

#define SDL_DEBUG(type, level, string, ARGS…) SDL_debug(type, level,
string, ARGS)

And to remove it, use a definition like this:

#ifdef SDL_ENABLE_DEBUGING
… see above for define …
#else
#define SDL_DEBUG(type, level, string, ARGS…)
#endif

cpp is wiley little program!!

variable-length arguments for macros have become a standard
with ISO C99, some compilers had variable-length arguments
a looooong time before that, especially the gcc. Just don’t
think that this is portable - atleast it is far less
widespread than “inline”. It is up to Sam to decide how
feature-old a compiler may be to handle SDL - IMVHO there’s
no need to make libsdl extra portable to unknown compilers
and it is feasable to prescribe a least-version of compilers
for the supported platforms. If msvc shall be able to link
with the sdl.dll then atleast one shall look into the
feature-list of the msvc releases. If lcc or wcc does not
have it we can probably skip that IMMHO. -Guido

David Snopek wrote:

Derrell Lipman wrote:

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, …);

Since C macros don’t allow for variable-length argument lists, it’s
not possible to comment out all of these debug statements (for speed)
without cluttering the source code with #ifdefs around each call to
SDL_DEBUG() – which kind of defeats the purpose of having a nice
macro for the debug function. To avoid this problem, call the macro
with an extra set of parenthesis around the entire argument list:

    SDL_DEBUG((SDL_DEBUG_GENERAL, SDL_DEBUG_WARNING, __FILE__, __LINE__,
               "A condition was encountered: 0x%x", state));

This is simply not true! CPP (C Pre-Processor) macros can have variable
length argument lists. I use them for my own debuging code which,
coincidently, works almost exactly like this. The define goes like

#define SDL_DEBUG(type, level, string, ARGS…) SDL_debug(type, level,
string, ARGS)

And to remove it, use a definition like this:

#ifdef SDL_ENABLE_DEBUGING
… see above for define …
#else
#define SDL_DEBUG(type, level, string, ARGS…)
#endif

cpp is wiley little program!!

    -- David Snopek

variable-length arguments for macros have become a standard
with ISO C99, some compilers had variable-length arguments
a looooong time before that, especially the gcc. Just don’t
think that this is portable - atleast it is far less
widespread than “inline”. It is up to Sam to decide how
feature-old a compiler may be to handle SDL - IMVHO there’s
no need to make libsdl extra portable to unknown compilers
and it is feasable to prescribe a least-version of compilers
for the supported platforms. However, Sam said that it
should be “-ansi -pedantic” - and gcc 2.95.2 says:

test.c:3: warning: ANSI C does not allow macro with variable arguments

because “gcc -ansi” refers to pre-C99 which is C89.

– guido Edel sei der Mensch, hilfreich und gut
31:GCS/E/S/P C++$++++ ULHS L++w- N++@ d(±) s+a- h.r(*@)>+++ y++ 5++X-

On Mon May 28, 2001 at 07:34:15AM -0700, the boisterous
Sam Lantinga
wrote to me:

void SDL_debug(SDL_debugtype, SDL_debuglevel, const char *file, int line,
const char *fmt, …);

I would add the function name to the debug output, not only the file/line.
IMHO this is very usefull.

void SDL_debug(SDL_debugtype, SDL_debuglevel, const char *file,
const char *function, int line, const char *fmt, …);

#define SDL_DEBUG(type, level, fmt, ARGS…)
SDL_debug(type, level, FILE, FUNCTION, LINE, fmt, ARGS);

But be aware that you have to pass a format with arguments if you use such
a construct.

SDL_DEBUG(SDL_INFO, 1, “Initializing …\n”);
will not work.

And output should look like this (with debuglevel to 1000 ;-):
Error:hugo.c:hugo_init:354:Couldn’t create hugo - Textfile busy
And with debuglevel to 0:
Couldn’t create hugo
And with debuglevel to 1:
Couldn’t create hugo - Textfile busy
and so on …

And yes, this is a complete nonsense example :wink:

what do you think about this?
Thomas–
___ Obviously we do not want to leave zombies around.
/\ - W. Richard Stevens
( ^ >
/ \ Thomas Krennwallner
(
/) Fingerprint: 9484 D99D 2E1E 4E02 5446 DAD9 FF58 4E59 67A1 DA7B

Thomas Krennwallner wrote:

On Mon May 28, 2001 at 07:34:15AM -0700, the boisterous
Sam Lantinga
wrote to me:

void SDL_debug(SDL_debugtype, SDL_debuglevel, const char *file, int line,
const char *fmt, …);

I would add the function name to the debug output, not only the file/line.
IMHO this is very usefull.

void SDL_debug(SDL_debugtype, SDL_debuglevel, const char *file,
const char *function, int line, const char *fmt, …);

#define SDL_DEBUG(type, level, fmt, ARGS…)
SDL_debug(type, level, FILE, FUNCTION, LINE, fmt, ARGS);

Again, FUNCTION is not in C89, and C99 specified it as a different
symbol ("_Function"?). Older MSVC don’t have it IIRC, I don’t know at
which release they came to support a similiar syntax that could be used
for a #define FUNCTION in the headers.

But be aware that you have to pass a format with arguments if you use such
a construct.
No, you don’t need to. In my own logging-style, I use C’s strconstcat,
for SDL_debug it could look like

#ifndef GNUC
#define FUNCTION “…”
#endif

#define SDL_DEBUG(type, level, fmt, ARGS…)
SDL_debug(type, level, “%s:%s:%s:” fmt,\ // <-- fmt is a "xxx"
FILE, LINE, FUNCTION, ARGS);

and then, use printf-argtypeVSformat-checking available in gcc. :-)))))

– guido Edel sei der Mensch, hilfreich und gut
31:GCS/E/S/P C++$++++ ULHS L++w- N++@ d(±) s+a- h.r(*@)>+++ y++ 5++X-

Again, FUNCTION is not in C89, and C99 specified it as a different
symbol ("_Function"?). Older MSVC don’t have it IIRC, I don’t know at
which release they came to support a similiar syntax that could be used
for a #define FUNCTION in the headers.

good point.

But be aware that you have to pass a format with arguments if you use such
a construct.
No, you don’t need to. In my own logging-style, I use C’s strconstcat,
for SDL_debug it could look like

#ifndef GNUC
#define FUNCTION “…”
#endif

#define SDL_DEBUG(type, level, fmt, ARGS…)
SDL_debug(type, level, “%s:%s:%s:” fmt,\ // <-- fmt is a "xxx"
FILE, LINE, FUNCTION, ARGS);

and then, use printf-argtypeVSformat-checking available in gcc. :-)))))

Also good, but I meant that this fails on gcc:

#include #include

static void
debug (const char *file, const char *func, int line, const char *fmt, …)
{
va_list ap;

fprintf (stdout, "%s:%s:%d: ", file, func, line);
va_start (ap, fmt);
vfprintf (stdout, fmt, ap);
va_end (ap);
}

#define DEBUG(fmt, ARGS…)
debug (FILE, FUNCTION, LINE, fmt, ARGS);

int
main ()
{
int hugo = 0;
DEBUG (“This works: %d\n”, hugo);
DEBUG (“This doesn’t work\n”);
}

$ gcc hugo.c -o hugo
hugo.c: In function main': hugo.c:23: parse error before)’

So long
ThomasOn Mon, May 28, 2001 at 11:38:47PM -0700, the boisterous Guido Draheim <Guido.RR at gmx.de> wrote:


/\ Thomas Krennwallner
( ^ > Fingerprint: 7B58 6ED2 676F 75D8 4DD1 5A83 DC68 E62F 85F3 D58F
/ \ Phone: +43 2252 810810 18
(
/)

E. Moritz GmbH
office at e-moritz.at
http://www.e-moritz.at/

David Snopek writes:

Derrell Lipman wrote:

Since C macros don’t allow for variable-length argument lists…

This is simply not true! CPP (C Pre-Processor) macros can have variable…

#define SDL_DEBUG(type, level, string, ARGS…) SDL_debug(type, level,
string, ARGS)

Yup, you’re right. I had forgotten about that feature. Sorry about
the mis-information I presented.

Derrell

“Derrell” == Derrell Lipman <Derrell.Lipman at UnwiredUniverse.com> writes:

Derrell> David Snopek writes:

Derrell Lipman wrote:

Since C macros don’t allow for variable-length argument lists…

This is simply not true! CPP (C Pre-Processor) macros can have variable…

#define SDL_DEBUG(type, level, string, ARGS…) SDL_debug(type, level,
string, ARGS)

Derrell> Yup, you’re right. I had forgotten about that feature. Sorry about
Derrell> the mis-information I presented.

Should you ever encounter a preprocessor that does not support
`…’, you can always use the following trick instead:

#if DEBUG
void SDL_debug (SDL_debugtype, SDL_debuglevel, const char *file,
int line, const char *fmt, …);
#else

define SDL_debug while (0) while

#endif

This rely on dead code removal, and it’s
also an interesting use of the comma operator :)–
Alexandre Duret-Lutz