aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/libgamma-error.c.gpp
blob: a606dd7351ea1540df4140918a0f9d703396fcbe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* -*- c -*- */
/**
 * libgamma -- Display server abstraction layer for gamma ramp adjustments
 * Copyright (C) 2014, 2015  Mattias Andrée (maandree@member.fsf.org)
 * 
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "libgamma-error.h"


#include <stddef.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>



$>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)
{
  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. */
      const char* error = libgamma_name_of_error(error_code);
      long int gid = (long int)libgamma_group_gid;
      if (libgamma_group_name == NULL)
	/* 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 == NULL)
    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;
}