/* -*- c -*- */ /* See LICENSE file for copyright and license details. */ #include "libgamma-error.h" #include #include #include #include #include $>set -u $>cd src/extract $>export PATH=".:${PATH}" /** * Group that the user needs to be a member of if * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned */ #ifndef __WIN32__ __thread gid_t libgamma_group_gid = 0; gid_t libgamma_group_gid_get(void) { return libgamma_group_gid; } void libgamma_group_gid_set(gid_t value) { libgamma_group_gid = value; } #else short libgamma_group_gid = 0; #endif /** * Group that the user needs to be a member of if * `LIBGAMMA_DEVICE_REQUIRE_GROUP` is returned, * `NULL` if the name of the group `libgamma_group_gid` * cannot be determined */ #ifndef __WIN32__ __thread const char *libgamma_group_name = NULL; const char * libgamma_group_name_get(void) { return libgamma_group_name; } void libgamma_group_name_set(const char *value) { libgamma_group_name = value; } #else const char *libgamma_group_name = NULL; #endif /** * Prints an error to stderr in a `perror` fashion, * however this function will not translate the `libgamma` * errors into human-readable strings, it will simply * print the name of the error. If the value `error_code` * is the value of `LIBGAMMA_ERRNO_SET`, `perror` will be * used to print the current error stored in `errno`. * If `error_code` is non-negative (an `errno` value`), that * value will be stored in `errno` and `perror` will be * used to print it. Additionally, if the `error_code` is * the value of `LIBGAMMA_DEVICE_REQUIRE_GROUP` the * required group will be printed with its numerical value * and, if known, its name. * * @param name The text to add at the beginning * @param value The error code, may be an `errno` value */ void libgamma_perror(const char *name, int error_code) { const char *error; long int gid; if (error_code >= 0) { /* Print the stored errno value */ errno = error_code; perror(name); } else if (error_code == LIBGAMMA_ERRNO_SET) { /* Print errno */ perror(name); } else if (error_code == LIBGAMMA_DEVICE_REQUIRE_GROUP) { /* Print the error name and the required group membership */ error = libgamma_name_of_error(error_code); gid = (long int)libgamma_group_gid; if (!libgamma_group_name) { /* Group name unknown */ if (name && *name) fprintf(stderr, "%s: %s: %ld\n", name, error, gid); else fprintf(stderr, "%s: %ld\n", error, gid); } else { /* Group name known, ID is second class */ if (name && *name) fprintf(stderr, "%s: %s: %s (%ld)\n", name, error, libgamma_group_name, gid); else fprintf(stderr, "%s: %s (%ld)\n", error, libgamma_group_name, gid); } } else if (error_code < LIBGAMMA_ERROR_MIN) { /* If the error code does not exist, print "(?)" */ if (name && *name) fprintf(stderr, "%s: (?)\n", name); else fprintf(stderr, "(?)\n"); } else { /* Print the name of the error */ if (name && *name) fprintf(stderr, "%s: %s\n", name, libgamma_name_of_error(error_code)); else fprintf(stderr, "%s\n", libgamma_name_of_error(error_code)); } } /** * Returns the name of the definition associated with a `libgamma` error code * * @param value The error code * @return The name of the definition associated with the error code, * `NULL` if the error code does not exist; the return string * should not be `free`:d */ const char * libgamma_name_of_error(int value) { /* Map from error codes to error names. The output of $(libgamma-error-extract --list) is sorted by error code in decreasing order */ static const char* error_names[] = { $>for error in $(libgamma-error-extract --list); do "${error}", $>done }; /* Return `NULL` if the error code is invalid */ if (value < LIBGAMMA_ERROR_MIN || value >= 0) return NULL; /* Convert error code from {-1, -2, -3, ...} to {0, 1, 2, ...} * and look up the error's name and return it */ return error_names[-value - 1]; } /** * Return the value of a `libgamma` error definition refered to by name * * @param name The name of the definition associated with the error code * @return The error code, zero if the name does is `NULL` * or does not refer to a `libgamma` error */ int libgamma_value_of_error(const char *name) { /* Return 0 (not a valid error code) if the error name is `NULL` */ if (!name) return 0; /* Test error names against `name` and return the value of the match error */ $>for error in $(libgamma-error-extract --list); do if (!strcmp(name, "${error}")) return ${error}; $>done /* Return 0 (not a valid error code) if the error name is unknown */ return 0; }