Lumiera  0.pre.03
»edit your freedom«
error-state.c
Go to the documentation of this file.
1 /*
2  ERROR-STATE - Lumiera C error flag implementation
3 
4  Copyright (C) Lumiera.org
5  2008, Christian Thaeter <ct@pipapo.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
36 #include "lib/error.h"
37 
38 #include <pthread.h>
39 
40 
41 /*
42  predefined errors
43 */
44 LUMIERA_ERROR_DEFINE (ERRNO, "errno");
45 LUMIERA_ERROR_DEFINE (EERROR, "could not initialise error system");
46 LUMIERA_ERROR_DEFINE (UNKNOWN, "unknown error");
47 
48 
49 /* Thread local storage */
50 static pthread_key_t lumiera_error_tls;
51 static pthread_once_t lumiera_error_initialized = PTHREAD_ONCE_INIT;
52 
57 {
58  lumiera_err err;
59  char* extra;
60 };
61 
62 typedef struct lumiera_errorcontext_struct lumiera_errorcontext;
63 typedef lumiera_errorcontext* LumieraErrorcontext;
64 
65 
66 static void
67 lumiera_error_tls_delete (void* err)
68 {
69  if (err)
70  free (((LumieraErrorcontext)err)->extra);
71  free(err);
72 }
73 
74 static void
75 lumiera_error_tls_init (void)
76 {
77  if (!!pthread_key_create (&lumiera_error_tls, lumiera_error_tls_delete))
78  LUMIERA_DIE (EERROR);
79 }
80 
81 
82 LumieraErrorcontext
83 lumiera_error_get (void)
84 {
85  pthread_once (&lumiera_error_initialized, lumiera_error_tls_init);
86 
87  LumieraErrorcontext self = pthread_getspecific (lumiera_error_tls);
88  if (!self)
89  {
90  /* malloc() and not lumiera_malloc() here because nothing else might be initialised when calling this */
91  self = malloc (sizeof *self);
92  if (!self)
93  LUMIERA_DIE (EERROR);
94 
95  self->err = NULL;
96  self->extra = NULL;
97  pthread_setspecific (lumiera_error_tls, self);
98  }
99 
100  return self;
101 }
102 
103 
104 lumiera_err
105 lumiera_error_set (lumiera_err nerr, const char* extra)
106 {
107  LumieraErrorcontext self = lumiera_error_get ();
108 
109  if (!self->err)
110  {
111  self->err = nerr;
112  free (self->extra);
113  if (extra)
114  self->extra = strdup (extra);
115  else
116  self->extra = NULL;
117  }
118 
119  return self->err;
120 }
121 
122 
123 lumiera_err
125 {
126  LumieraErrorcontext self = lumiera_error_get ();
127  lumiera_err err = self->err;
128 
129  if (err)
130  self->err = NULL;
131  return err;
132 }
133 
134 const char*
136 {
137  return lumiera_error_get ()->extra;
138 }
139 
140 
141 lumiera_err
143 {
144  return lumiera_error_get ()->err;
145 }
146 
147 int
148 lumiera_error_expect (lumiera_err expected)
149 {
150  LumieraErrorcontext self = lumiera_error_get ();
151  lumiera_err err = self->err;
152 
153  if (err == expected)
154  {
155  if (err)
156  self->err = NULL;
157  return 1;
158  }
159  else
160  return 0;
161 }
lumiera_err lumiera_error_peek(void)
Check current error state without clearing it Please avoid this function and use lumiera_error() if p...
Definition: error-state.c:142
int lumiera_error_expect(lumiera_err expected)
Expect some error Check that the current error state matches some expectation, if true then the error...
Definition: error-state.c:148
Lumiera error handling (C interface).
Holding error and some context data.
Definition: error-state.c:56
#define LUMIERA_DIE(err)
Abort unconditionally with a &#39;Fatal Error!&#39; message.
Definition: error.h:63
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:124
lumiera_err lumiera_error_set(lumiera_err nerr, const char *extra)
Set error state for the current thread.
Definition: error-state.c:105
const char * lumiera_error_extra(void)
Query the extra context for the last error.
Definition: error-state.c:135
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition: error.h:80