![]() |
das2C
das core C utilities (v3)
|
#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <sys/stat.h>#include <sys/types.h>#include <das3/defs.h>

Go to the source code of this file.
Data Structures | |
| struct | das_error_msg |
| Structure returned from das_get_error(). More... | |
Macros | |
| #define | DASERR_DIS_EXIT 0 |
| Used to indicate that errors should trigger program exit. | |
| #define | DASERR_DIS_RET 1 |
| Used to indicate that errors should trigger library functions to return error values. | |
| #define | DASERR_DIS_ABORT 43 |
| Used to indicate that errors should trigger program abort with a core dump. | |
| #define | das_error(nErrCode, ...) das_error_func(__FILE__, __func__, __LINE__, nErrCode, __VA_ARGS__ ) |
| Signal an error condition. | |
| #define | das_error_str(nErrCode, sMsg) das_error_func_fixed(__FILE__, __func__, __LINE__, nErrCode, sMsg) |
| Signal an error condition with a message that is not a format string. | |
| #define | das_error_false(nErrCode, ...) (das_error_func(__FILE__, __func__, __LINE__, nErrCode, __VA_ARGS__), false) |
| Raise an error and return false, for a function that reports failure as a bool rather than a DasErrCode. | |
| #define | das_error_null(nErrCode, ...) (das_error_func(__FILE__, __func__, __LINE__, nErrCode, __VA_ARGS__), NULL) |
| Raise an error and return NULL, for a function that answers with a pointer. | |
| #define | das_within(A, B, E) (fabs((A) - (B)) < (E) ? true : false) |
| Check to see if two floating point values are within an epsilon of each other. | |
| #define | DAS_XML_BUF_LEN 1000000 |
| The limit on xml packet length, in bytes. | |
| #define | DAS_XML_NODE_NAME_LEN 256 |
| The limit of xml element name length, in bytes. | |
| #define | DAS_MAX_ID_BUFSZ 64 |
| The size of an char buffer large enough to hold valid object IDs. | |
Typedefs | |
| typedef void(* | das_log_handler_t) (int nLevel, const char *sMsg, bool bPrnTime) |
| Definition of a message handler function pointer. | |
Functions | |
| DAS_API void | das_init (const char *sProgName, int nErrDis, int nErrBufSz, int nLevel, das_log_handler_t logfunc) |
| Initialize any global structures in the Das2 library. | |
| DAS_API const char * | das_version (void) |
| Return the version of this library. | |
| DAS_API void | das_finish (void) |
| A do nothing function on Unix, closes network sockets on windows. | |
| DAS_API void | das_abort_on_error (void) |
| Error handling: Trigger Core Dumps. | |
| DAS_API void | das_exit_on_error (void) |
| Error handling: Normal Exit Set the library to call exit(ErrorCode) when a problem is detected. | |
| DAS_API void | das_return_on_error (void) |
| Error handling: Normal Return Set the library to return normally to the calling function with a return value that indicates a problem has occurred. | |
| DAS_API int | das_error_disposition (void) |
| Error handling: get the library's error disposition. | |
| DAS_API void | das_errdisp_get_lock (void) |
| Used for co-operative locking of time-limited error disposition changes. | |
| DAS_API void | das_errdisp_release_lock (void) |
| Used for co-operative locking of time-limited error disposition changes. | |
| DAS_API void | das_error_setdisp (int nDisp) |
| The inverse of das_error_disposition. | |
| DAS_API void | das_print_error (void) |
| Error handling: Print formatted error to standard error stream Set the library to output formatted error messages to the processes standard error stream. | |
| DAS_API bool | das_save_error (int maxmsg) |
| Error handling: Save formatted error in a message buffer. | |
| DAS_API const char * | das_lib_version (void) |
| Get the library version. | |
| DAS_API bool | das_assert_valid_id (const char *sId) |
| Check that a string is suitable for use as an object ID. | |
| DAS_API void | das_store_str (char **psDest, size_t *puLen, const char *sSrc) |
| Store string in a buffer that is reallocated if need be. | |
| DAS_API char * | das_string (const char *fmt,...) |
| Allocate a new string on the heap and format it. | |
| DAS_API char * | das_strip (char *sLine, char cComment) |
| Strip whitespace from a string. | |
| DAS_API size_t | das_tokncpy (char *dest, const char *src, size_t n) |
| Copy string as an XML token. | |
| DAS_API const char * | das_xml_escape (char *dest, const char *src, size_t uOutLen) |
| Translate unsafe characters for XML string output. | |
| DAS_API char * | das_strdup (const char *sIn) |
| Copy a string into a new buffer allocated on the heap. | |
| DAS_API uint8_t * | das_memset (uint8_t *pDest, const uint8_t *pSrc, size_t uElemSz, size_t uCount) |
| A memset that handles multi-byte items | |
| DAS_API char * | das_vstring (const char *fmt, va_list ap) |
| Store a formatted string in a newly allocated buffer. | |
| DAS_API bool | das_isdir (const char *path) |
| Is the path a directory. | |
| DAS_API DasErrCode | das_mkdirsto (const char *path) |
| Insure directories to a specific location exist. | |
| DAS_API const char * | das_userhome (void) |
| Get the home directory for the current account. | |
| DAS_API bool | das_copyfile (const char *src, const char *dest, mode_t mode) |
| Copy a file to a destination creating directories as needed. | |
| DAS_API bool | das_isfile (const char *path) |
| Is the path a file. | |
| DAS_API int | das_dirlist (const char *sPath, char ppDirList[][256], size_t uMaxDirs, char cType) |
| Get a sorted directory listing. | |
| DAS_API double | das_strtod_c (const char *nptr, char **endptr) |
| A C locale string to double converter. | |
| DAS_API char * | das_b64_encode (const unsigned char *data, size_t input_length, size_t *output_length) |
| Encode binary data as base64 (RFC 4648) characters in a new buffer. | |
| DAS_API int | das_b64_decode_buf (const char *data, size_t input_length, unsigned char *out, size_t out_cap, size_t *output_length) |
| Decode base64 (RFC 4648) into a caller-provided buffer, no allocation. | |
| DAS_API unsigned char * | das_b64_decode (const char *data, size_t input_length, size_t *output_length) |
| Decode base64 (RFC 4648) into a newly allocated buffer, symmetric with das_b64_encode. | |
| bool | dascmd_isArg (const char *sArg, const char *sShort, const char *sLong, bool *pLong) |
| See a given string matches the short or long form of an option. | |
| bool | dascmd_getArgVal (char *sDest, size_t uDest, char **argv, int argc, int *pArgIdx, const char *sShort, const char *sLong) |
| Get the value of an argument if the current entry in argv matches either the short or long form of an option. | |
| #define das_error | ( | nErrCode, | |
| ... | |||
| ) | das_error_func(__FILE__, __func__, __LINE__, nErrCode, __VA_ARGS__ ) |
Signal an error condition.
This routine is called throughout the code when an error condition arrises.
The default handler for error conditions prints the message provided to the standard error channel and then calls exit(nErrCode). To have the library call your handler instead use the das_set_error_handler() function. To have the library abort with a core dump on an error use das_abort_on_error().
Each source file in the code has it's own error code. Though it's probably not that useful to end users, the codes are provided here:
Application programs are recommended to use values 64 and above to avoid colliding with future das2 error codes.
| nErrCode | The value to return to the shell, should be one of the above. |
| #define das_error_str | ( | nErrCode, | |
| sMsg | |||
| ) | das_error_func_fixed(__FILE__, __func__, __LINE__, nErrCode, sMsg) |
Signal an error condition with a message that is not a format string.
Use this when the message comes from elsewhere (a caller, a parser, a library) and may contain '' characters. Nothing is interpreted.
| #define das_error_false | ( | nErrCode, | |
| ... | |||
| ) | (das_error_func(__FILE__, __func__, __LINE__, nErrCode, __VA_ARGS__), false) |
Raise an error and return false, for a function that reports failure as a bool rather than a DasErrCode.
return das_error(...) is correct in the DasErrCode functions that are most of this library, and silently WRONG in a bool one: das_error() hands back a non-zero code, which as a bool is true, so the failure reports success. The types are both integers and no compiler diagnostic exists for it. Write return das_error_false(...) in a bool function and the question does not come up.
| #define das_error_null | ( | nErrCode, | |
| ... | |||
| ) | (das_error_func(__FILE__, __func__, __LINE__, nErrCode, __VA_ARGS__), NULL) |
Raise an error and return NULL, for a function that answers with a pointer.
| #define DAS_XML_BUF_LEN 1000000 |
The limit on xml packet length, in bytes.
(ascii encoding.)
| typedef void(* das_log_handler_t) (int nLevel, const char *sMsg, bool bPrnTime) |
Definition of a message handler function pointer.
Message handlers need to be prepared for any of the string pointers sMsg, sDataStatus, or sStackTrace to be null.
| nLevel | The message level. If nLevel is equal to or greater than das_log_getlevel() then the message should be logged. |
| sMsg | The message, usually not null. |
| bPrnTime | The current system time should be included in the log output. |
| DAS_API void das_init | ( | const char * | sProgName, |
| int | nErrDis, | ||
| int | nErrBufSz, | ||
| int | nLevel, | ||
| das_log_handler_t | logfunc | ||
| ) |
Initialize any global structures in the Das2 library.
This should be the first function your program calls before using any Das2C functions. In general Das2C tries to avoid global structures but does use them in following areas:
This function initializes defaults for the items above.
| sProgName | The name of the program using the library. Used in some error messages. |
| nErrDis | Set the behavior the library takes when an error is encountered. May be one of DASERR_DIS_EXIT, call exit() when an error occurs; DASERR_DIS_RET, return with an error code; or DASERR_DIS_ABORT, call abort(). The value of DASERR_DIS_EXIT is 0 so you can use that for the default behavior. If DASERR_DIS_RET is used, the function das_get_error() can be used to retrieve the most recent error message. |
| nErrBufSz | If not zero, a global error message buffer will be allocated that is this many bytes long and error message will be saved into the buffer instead of being sent to the standard error channel. Messages can be retrieved via das_get_error(). If zero, these will be send to the standard error channel as soon as they occur. Saving errors is only useful if the error disposition is DAS2_ERRDIS_RET as otherwise the program exits before the message can be output. |
| nLevel | Set the logging level to one of, DASLOG_TRACE, DASLOG_DEBUG, DASLOG_NOTICE, DASLOG_WARN, DASLOG_ERROR, DASLOG_CRITICAL. |
| logfunc | A callback for handling log messages. The callback need not be thread safe as it will only be triggered inside mutual exclusion (mutex) locks. If NULL messages are printed to the standard error channel. |
The error disposition does not affect any errors that are encountered within das_init. Errors should not occur during initialization, any that do trigger a call to exit()
| DAS_API void das_abort_on_error | ( | void | ) |
Error handling: Trigger Core Dumps.
Call this function to have the library exit via an abort() call instead of using exit(ErrorCode). On most systems this will trigger the generation of a core file that can be used for debugging.
| DAS_API void das_exit_on_error | ( | void | ) |
Error handling: Normal Exit Set the library to call exit(ErrorCode) when a problem is detected.
This is usually what you want and the library's default setting.
| DAS_API void das_return_on_error | ( | void | ) |
Error handling: Normal Return Set the library to return normally to the calling function with a return value that indicates a problem has occurred.
This will be the new default, but is not yet tested.
| DAS_API int das_error_disposition | ( | void | ) |
Error handling: get the library's error disposition.
| DAS_API void das_errdisp_get_lock | ( | void | ) |
Used for co-operative locking of time-limited error disposition changes.
Acquire this lock before your critical section, then release it. All code that want's to toggle the error disposition should use this, but it's not enforceable, except by code review.
YOU MUST BE SURE YOUR FUNCTION CAN'T EXIT BEFORE THE LOCK IS RELEASED!
| DAS_API void das_errdisp_release_lock | ( | void | ) |
Used for co-operative locking of time-limited error disposition changes.
Release this lock before your critical section, then release it. All code that want's to toggle the error disposition should use this, but it's not enforceable, except by code review.
| DAS_API void das_error_setdisp | ( | int | nDisp | ) |
The inverse of das_error_disposition.
| nDisp | One of DAS2_ERRDIS_EXIT, DAS2_ERRDIS_ABORT, DAS2_ERRDIS_RET |
| DAS_API void das_print_error | ( | void | ) |
Error handling: Print formatted error to standard error stream Set the library to output formatted error messages to the processes standard error stream.
This is the default.
| DAS_API bool das_save_error | ( | int | maxmsg | ) |
Error handling: Save formatted error in a message buffer.
Set the library to save formatted error message to a message buffer.
| maxmsg | maximum message size. The buffer created will be maxmsg in length, meaning any formatted messages longer than the available buffer size will be truncated to maxmsg-1 |
| DAS_API const char * das_lib_version | ( | void | ) |
Get the library version.
| DAS_API bool das_assert_valid_id | ( | const char * | sId | ) |
Check that a string is suitable for use as an object ID.
Object ID strings are ascii strings using only characters from the set a-z, A-Z, 0-9, and _. They do not start with a number. They are no more than 63 bytes long. Basically they can be used as variable names in most programming languages.
If the das_error_disposition is set to exit this function never returns.
| sId |
| DAS_API void das_store_str | ( | char ** | psDest, |
| size_t * | puLen, | ||
| const char * | sSrc | ||
| ) |
Store string in a buffer that is reallocated if need be.
| psDest | a pointer to the storage location |
| puLen | a pointer to the size of the storage location |
| sSrc | the source string to store. |
| DAS_API char * das_string | ( | const char * | fmt, |
| ... | |||
| ) |
Allocate a new string on the heap and format it.
Except for using das_error on a failure, this is a copy of the code out of man 3 printf on Linux.
| DAS_API char * das_strip | ( | char * | sLine, |
| char | cComment | ||
| ) |
Strip whitespace from a string.
| sLine | - Pointer to a writable null terminated string, or a NULL pointer. |
| cComment | - Treat the character if it was a null character terminating the string. Replace it with an actual null if found. Use '\0' to avoid stripping "comments". |
| DAS_API size_t das_tokncpy | ( | char * | dest, |
| const char * | src, | ||
| size_t | n | ||
| ) |
Copy string as an XML token.
Copy a string ignoring leading and traily spaces. Internal whitespace characters are converted to regular spaces and collapsed
| dest | The buffer to receive string data, may be UTF-8 if desired The output string is always null terminated if n > 1 |
| src | the source string, may be UTF-8 if desired |
| n | the size of the dest buffer |
| DAS_API const char * das_xml_escape | ( | char * | dest, |
| const char * | src, | ||
| size_t | uOutLen | ||
| ) |
Translate unsafe characters for XML string output.
At present only the characters set [ " < > & ] are translated. All white space characters are preserved. So long as dest is at least one byte long the result is null terminated.
| dest | The buffer to receive the output |
| src | The data source |
| uOutLen | the size of the dest buffer. |
| DAS_API char * das_strdup | ( | const char * | sIn | ) |
Copy a string into a new buffer allocated on the heap.
| sIn | the string to copy |
| DAS_API uint8_t * das_memset | ( | uint8_t * | pDest, |
| const uint8_t * | pSrc, | ||
| size_t | uElemSz, | ||
| size_t | uCount | ||
| ) |
A memset that handles multi-byte items
Uses memcpy because the amount of data written in each call goes up exponentially and memcpy is freaking fast, much faster than a linear write loop for large arrays.
| pDest | The destination area must not overlap with pSrc |
| pSrc | A location for an individual element to repeat in pDest |
| uElemSz | The size in bytes of a single element |
| uCount | The number of elements to repeat in pDest |
| DAS_API char * das_vstring | ( | const char * | fmt, |
| va_list | ap | ||
| ) |
Store a formatted string in a newly allocated buffer.
This version is suitable for calling from variable argument functions.
Except for using das_error on a failure, this is a copy of the code out of man 3 printf on Linux.
| fmt | - a printf format string |
| ap | A va_list list, see vfprintf or stdarg.h for details |
| DAS_API bool das_isdir | ( | const char * | path | ) |
Is the path a directory.
| path | The directory in question, passed to stat(2) |
| DAS_API DasErrCode das_mkdirsto | ( | const char * | path | ) |
Insure directories to a specific location exist.
| sPath | a full path to a file. If this string contains no path separators, the function does nothing. |
| DAS_API const char * das_userhome | ( | void | ) |
Get the home directory for the current account.
| DAS_API bool das_copyfile | ( | const char * | src, |
| const char * | dest, | ||
| mode_t | mode | ||
| ) |
Copy a file to a destination creating directories as needed.
If the files exists at the destination it in overwritten. Directories are created as needed. Directory permissions are are the same as the file with the addition that for each READ permission in the mode, directory EXEC permission is added.
| src | - name of file to copy |
| dest | - name of destination |
| mode | - the permission mode of the destination file, 0664 is recommended if you can decide on the output permissions mode. (mode argument not present in WIN32 version) |
| DAS_API bool das_isfile | ( | const char * | path | ) |
Is the path a file.
| path | The file in question, passed to stat(2) |
| DAS_API int das_dirlist | ( | const char * | sPath, |
| char | ppDirList[][256], | ||
| size_t | uMaxDirs, | ||
| char | cType | ||
| ) |
Get a sorted directory listing.
| sPath | The path to the directory to read. |
| ppDirList | A pointer to a 2-D character array where the first index is the directory item and the second index is the character position. The max value of the second index must be = NAME_MAX - 1. The value NAME_MAX is defined in the POSIX header limits.h |
| uMaxDirs | The maximum number of directory entries that may be stored |
| cType | May be used to filter the items returned. If cType = 'f' only files will be return, if cType = 'd' then only directories will be returned. Any other value, including 0 will return both. |
| DAS_API double das_strtod_c | ( | const char * | nptr, |
| char ** | endptr | ||
| ) |
A C locale string to double converter.
This is essentially the same as the C-lib function strtod, except it always evaluates strings in the "C" locale no matter the current locale of the program. It does not alter the current program's locale.
| nptr | The starting point of the string to convert |
| endptr | Where to store a pointer to the last item converted |
Notes: Errno is set as normal for the underlying strtod implementation.
| DAS_API char * das_b64_encode | ( | const unsigned char * | data, |
| size_t | input_length, | ||
| size_t * | output_length | ||
| ) |
Encode binary data as base64 (RFC 4648) characters in a new buffer.
(Credit: stackoverflow user ryyst)
| data | A pointer to the data to encode |
| input_length | The number of input bytes to encode |
| output_length | a pointer to location to receive the encoded length (4 * ceil(input_length/3), '=' padded; the buffer is NOT NUL terminated) |
| DAS_API int das_b64_decode_buf | ( | const char * | data, |
| size_t | input_length, | ||
| unsigned char * | out, | ||
| size_t | out_cap, | ||
| size_t * | output_length | ||
| ) |
Decode base64 (RFC 4648) into a caller-provided buffer, no allocation.
| data | The base64 characters (length a multiple of 4, '=' padded) |
| input_length | The number of base64 characters |
| out | The caller's output buffer |
| out_cap | The capacity of out |
| output_length | receives the number of decoded bytes written. Decoded output is at most 3/4 of input_length, so: out_cap >= 3*input_length/4 always suffices. |
| DAS_API unsigned char * das_b64_decode | ( | const char * | data, |
| size_t | input_length, | ||
| size_t * | output_length | ||
| ) |
Decode base64 (RFC 4648) into a newly allocated buffer, symmetric with das_b64_encode.
Caller frees. Returns NULL on malformed input or alloc failure (with *output_length set to 0).
| bool dascmd_isArg | ( | const char * | sArg, |
| const char * | sShort, | ||
| const char * | sLong, | ||
| bool * | pLong | ||
| ) |
See a given string matches the short or long form of an option.
This is commonly used in loops over each command line argument. It works for arguments in the form:
-a value –my-arg=value
The form that has spaces between the long option name and the value is not supported
| sArg | - A string to test |
| sShort | - The short form of an option |
| sLong | - The long form of an option |
| pLong | - If not NULL, the associated bool value is set to true if the long form of a argument was found. |
| bool dascmd_getArgVal | ( | char * | sDest, |
| size_t | uDest, | ||
| char ** | argv, | ||
| int | argc, | ||
| int * | pArgIdx, | ||
| const char * | sShort, | ||
| const char * | sLong | ||
| ) |
Get the value of an argument if the current entry in argv matches either the short or long form of an option.
This is typically used to test command line arguments in a loop. It works for arguments in the form:
-a value –my-arg=value
The form that has spaces between the long option name and the value is not supported
| sDest | - The location to receive the option value |
| uDest | - The size of the location to receive the option value Note the macro DAS_FIELD_SZ is useful for getting the size of a field in a structure. |
| argv | - The list of command line parameters |
| argc | - The number of command line parameters |
| pArgIdx | - A pointer to the current argument index. It is incremented if the option is found. |
| sShort | - The short form of the option |
| sLong | - The long form of the option |