.\" Copyright (c) 2007-2023 Julien Nadeau Carriere .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED .\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES .\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR .\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, .\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING .\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" .Dd February 17, 2023 .Dt AG_ERROR 3 .Os Agar 1.7 .Sh NAME .Nm AG_Error .Nd agar error handling .Sh SYNOPSIS .Bd -literal #include .Ed .Sh DESCRIPTION This manual page describes the error handling system which is used by all Agar libraries, and available to applications as well. .Sh ERROR RETURNS .nr nS 1 .Ft void .Fn AG_SetError "const char *fmt" "..." .Pp .Ft void .Fn AG_SetErrorS "const char *msg" .Pp .Ft void .Fn AG_SetErrorV "const char *code" "const char *msg" .Pp .Ft "const char *" .Fn AG_GetError "void" .Pp .Ft void .Fn AG_FatalError "const char *msg" .Pp .Ft void .Fn AG_FatalErrorF "const char *fmt" "..." .Pp .Ft void .Fn AG_FatalErrorV "const char *code" "const char *message" .Pp .Ft void .Fn AG_SetFatalCallback "void (*callback)(const char *msg)" .Pp .Ft "const char *" .Fn AG_Strerror "int errno" .Pp .nr nS 0 .Fn AG_SetError sets the error message from the .Xr printf 3 style format string .Fa fmt . .Fn AG_SetErrorS sets the error message from the string .Fa msg . .Pp .Fn AG_SetErrorV is a macro which sets the error message to either .Fa msg if Agar was built with .Dv AG_VERBOSITY or the shortened code .Fa code if Agar was built without .Dv AG_VERBOSITY . .Pp .Fn AG_GetError returns the error message string last set by .Fn AG_SetError . .Pp Note: If Agar was compiled with THREADS support then the error code and error message are both contained in thread-local storage. .Pp The .Fn AG_FatalError function outputs the given error message to the user and causes abnormal termination of the program. .Pp The .Fn AG_FatalErrorV variant is a macro which expands to .Fa msg if Agar was built with .Dv AG_VERBOSITY , otherwise it expands to the shortened code .Fa code . .Pp .Fn AG_SetFatalCallback function sets a user provided callback to be called by .Fn AG_FatalError instead of simply terminating the process. The callback is expected to do program-specific cleanup and then terminate the program itself. An error message is passed to the callback via the .Fa msg argument. .Pp The .Fn AG_Strerror function returns an error message for the given platform-specific error code (e.g., on POSIX platforms, the argument should be a valid .Xr errno 2 value). .Sh DEBUG ROUTINES .nr nS 1 .Ft void .Fn AG_Verbose "const char *fmt" "..." .Pp .Ft void .Fn AG_Debug "AG_Object *obj" "const char *fmt" "..." .Pp .Ft void .Fn AG_Debug2 "AG_Object *obj" "const char *fmt" "..." .Pp .Ft void .Fn AG_SetVerboseCallback "int (*fn)(const char *msg)" .Pp .Ft void .Fn AG_SetDebugCallback "int (*fn)(const char *msg)" .Pp .nr nS 0 The .Fn AG_Verbose routine prints a message on the error console if .Va agVerbose is non-zero. .Pp The .Fn AG_Debug routine outputs text to the debugging console if .Va agDebugLvl is >= 1. .Fn AG_Debug2 outputs text to the debugging console if .Va agDebugLvl is >= 2. If .Fa obj is not NULL then the name (or pointer address) of .Fa obj is prepended to the message. .Pp The .Fn AG_SetVerboseCallback and .Fn AG_SetDebugCallback routines arrange for .Fa fn to be invoked by .Fn AG_Verbose and .Fn AG_Debug . If the callback routine returns 1, the message will not be printed. .Sh ERROR WRAPPERS .nr nS 1 .Ft "void *" .Fn AG_Malloc "AG_Size size" .Pp .Ft "void *" .Fn AG_TryMalloc "AG_Size size" .Pp .Ft "void *" .Fn AG_Realloc "void *ptr" "AG_Size size" .Pp .Ft "void *" .Fn AG_TryRealloc "void *ptr" "AG_Size size" .Pp .Ft void .Fn AG_Free "void *ptr" .Pp .nr nS 0 The .Fn AG_Malloc function calls .Xr malloc 3 to allocate .Fa size bytes of uninitialized memory for general-purpose storage of data and objects. If insufficient memory is available, .Fn AG_Malloc raises a fatal error. .Pp The .Fn AG_TryMalloc function calls .Xr malloc 3 to allocate .Fa size bytes of uninitialized memory for general-purpose storage of data / objects. If insufficient memory is available, .Fn AG_TryMalloc sets the error message to "Out of memory" (E0) and returns NULL. .Pp The .Fn AG_Realloc function calls .Xr realloc 3 to change the size of the allocated memory area referenced by .Fa ptr from its current size to a new .Fa size in bytes. On success, it returns a pointer to the newly reallocated memory area (which may be different than .Fa ptr ) . If insufficient memory is available, .Fn AG_Realloc raises a fatal error. .Pp The .Fn AG_TryRealloc function calls .Xr realloc 3 to change the size of the allocated memory area referenced by .Fa ptr from its current size to a new .Fa size in bytes. On success, it returns a pointer to the newly reallocated memory area (which may be different than .Fa ptr ) . If insufficient memory is available, .Fn AG_TryRealloc sets the error message to "Out of memory" (E0) and returns NULL. .Pp Passing a .Fa ptr of NULL to .Fn AG_Realloc or .Fn AG_TryRealloc is equivalent to calling .Fn AG_Malloc or .Fn AG_TryMalloc . .Pp .Fn AG_Free causes the allocated memory referenced by .Fa ptr to be released (made available for future allocations) by calling .Xr free 3 . If .Fa ptr is NULL then .Fn AG_Free is a no-op. .Sh EXAMPLES The following code print a message on the debugging console: .Bd -literal -offset indent .\" SYNTAX(c) AG_Verbose("This is a global debugging message\\n"); .Ed .Pp Debug messages may contain ANSI SGR sequences: .Bd -literal -offset indent .\" SYNTAX(c) AG_Verbose("This message contains " AGSI_RED AGSI_ITALIC "ANSI" AGSI_RST "\\n"); AG_Verbose("This message uses an " AGSI_COURIER "alternate font" AGSI_RST "\\n"); .Ed .Pp The following code prints a debugging message in relation to an .Xr AG_Object 3 in particular: .Bd -literal -offset indent .\" SYNTAX(c) AG_Debug(myObject, "Hello! This is a contextual debugging message. " "My flags = 0x%x\\n", myObject->flags); .Ed .Pp The following code illustrates the use of .Fn AG_SetError by a function, and the use of .Fn AG_GetError by its caller: .Bd -literal -offset indent .\" SYNTAX(c) int SomeOperation(int x) { if (x > 10) { AG_SetError("x is too large (%d > 10)", x); return (-1); } return (0); } if (SomeOperation(x) != 0) AG_Verbose("Failed: %s\\n", AG_GetError()); .Ed .Pp The following code allocates, reallocates and frees memory: .Bd -literal -offset indent .\" SYNTAX(c) void *buffer, *bufferNew; /* Allocate 4K of memory. Fatal if allocation fails. */ buffer = AG_Malloc(4096); /* Allocate 4K of memory. Print a message if allocation fails. */ if ((buffer = AG_TryMalloc(4096)) == NULL) AG_Verbose("Allocation failed\\n"); /* Grow the buffer to 8K. Fatal if reallocation fails. */ buffer = AG_Realloc(buffer, 8192); /* Grow the buffer to 8K. Print a message if reallocation fails. */ if ((bufferNew = AG_TryRealloc(buffer, 8192)) == NULL) { AG_Verbose("Allocation failed\\n"); } buffer = bufferNew; /* Release the allocated memory. */ AG_Free(buffer); .Ed .Sh SEE ALSO .Xr AG_Intro 3 , .Xr AG_Object 3 , .Xr AG_Threads 3 .Sh HISTORY The .Nm interface first appeared in Agar 1.0. .Fn AG_SetErrorV and .Fn AG_FatalErrorV appeared in Agar 1.6.0. .Fn AG_Debug2 appeared in Agar 1.7.0.