add @todo
[platform/upstream/dbus.git] / dbus / dbus-errors.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-errors.c Error reporting
3  *
4  * Copyright (C) 2002  Red Hat Inc.
5  * Copyright (C) 2003  CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 1.2
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24 #include "dbus-errors.h"
25 #include "dbus-internals.h"
26 #include <stdarg.h>
27 #include <stdio.h>
28
29 /**
30  * @defgroup DBusErrors Error reporting
31  * @ingroup  DBus
32  * @brief Error reporting
33  *
34  * Types and functions related to reporting errors.
35  *
36  *
37  * In essence D-BUS error reporting works as follows:
38  *
39  * @code
40  * DBusResultCode result = DBUS_RESULT_SUCCESS;
41  * dbus_some_function (arg1, arg2, &result);
42  * if (result != DBUS_RESULT_SUCCESS)
43  *   printf ("an error occurred\n");
44  * @endcode
45  * 
46  * @{
47  */
48
49 typedef struct
50 {
51   const char *name; /**< error name */
52   char *message; /**< error message */
53
54   unsigned int const_message : 1; /** Message is not owned by DBusError */
55 } DBusRealError;
56
57 /**
58  * Set a result code at a result code location,
59  * if code_address is not #NULL.
60  *
61  * @param code_address place to store the result code.
62  * @param code the result code itself.
63  */
64 void
65 dbus_set_result (DBusResultCode *code_address,
66                  DBusResultCode  code)
67 {
68   if (code_address)
69     *code_address = code;
70 }
71
72 /**
73  * Returns a string describing the given result code.
74  *
75  * @param code the result code to describe.
76  * @returns a constant string describing the code.
77  */
78 const char*
79 dbus_result_to_string (DBusResultCode code)
80 {
81   /* This is a switch to the compiler will complain if we
82    * aren't handling some codes
83    */
84   switch (code)
85     {
86     case DBUS_RESULT_SUCCESS:
87       return "Success";
88     case DBUS_RESULT_FAILED:
89       return "Unknown error";
90     case DBUS_RESULT_NO_MEMORY:
91       return "Not enough memory available";
92     case DBUS_RESULT_IO_ERROR:
93       return "Error reading or writing data";
94     case DBUS_RESULT_BAD_ADDRESS:
95       return "Could not parse address";
96     case DBUS_RESULT_NOT_SUPPORTED:
97       return "Feature not supported";
98     case DBUS_RESULT_LIMITS_EXCEEDED:
99       return "Resource limits exceeded";
100     case DBUS_RESULT_ACCESS_DENIED:
101       return "Permission denied";
102     case DBUS_RESULT_AUTH_FAILED:
103       return "Could not authenticate to server";
104     case DBUS_RESULT_NO_SERVER:
105       return "No server";
106     case DBUS_RESULT_TIMEOUT:
107       return "Connection timed out";
108     case DBUS_RESULT_NO_NETWORK:
109       return "Network unavailable";
110     case DBUS_RESULT_ADDRESS_IN_USE:
111       return "Address already in use";
112     case DBUS_RESULT_DISCONNECTED:
113       return "Disconnected.";
114     case DBUS_RESULT_INVALID_ARGS:
115       return "Invalid argumemts.";
116     case DBUS_RESULT_NO_REPLY:
117       return "Did not get a reply message.";
118     case DBUS_RESULT_FILE_NOT_FOUND:
119       return "File doesn't exist.";
120       
121       /* no default, it would break our compiler warnings */
122     }
123
124   return "Invalid error code";
125 }
126
127 /**
128  * Initializes a DBusError structure.
129  * 
130  * @todo calling dbus_error_init() in here is no good,
131  * for the same reason a GError* has to be set to NULL
132  * before you pass it in.
133  *
134  * @param error the DBusError.
135  */
136 void
137 dbus_error_init (DBusError *error)
138 {
139   DBusRealError *real;
140
141   _dbus_assert (error != NULL);
142
143   _dbus_assert (sizeof (DBusError) == sizeof (DBusRealError));
144
145   real = (DBusRealError *)error;
146   
147   real->name = NULL;  
148   real->message = NULL;
149
150   real->const_message = TRUE;
151 }
152
153 /**
154  * Frees an error created by dbus_error_init().
155  *
156  * @param error memory where the error is stored.
157  */
158 void
159 dbus_error_free (DBusError *error)
160 {
161   DBusRealError *real;
162
163   real = (DBusRealError *)error;
164
165   if (!real->const_message)
166     dbus_free (real->message);
167 }
168
169 /**
170  * Assigns an error name and message to a DBusError.
171  * Does nothing if error is #NULL.
172  *
173  * @todo calling dbus_error_init() in here is no good,
174  * for the same reason a GError* has to be set to NULL
175  * before you pass it in.
176  *
177  * @param error the error.
178  * @param name the error name (not copied!!!)
179  * @param message the error message (not copied!!!)
180  */
181 void
182 dbus_set_error_const (DBusError  *error,
183                       const char *name,
184                       const char *message)
185 {
186   DBusRealError *real;
187
188   if (error == NULL)
189     return;
190
191   dbus_error_init (error);
192   
193   real = (DBusRealError *)error;
194   
195   real->name = name;
196   real->message = (char *)message;
197   real->const_message = TRUE;
198 }
199
200 /**
201  * Assigns an error name and message to a DBusError.
202  * Does nothing if error is #NULL.
203  *
204  * @param error the error.
205  * @param name the error name (not copied!!!)
206  * @param format printf-style format string.
207  * @returns #TRUE on success.
208  */
209 dbus_bool_t
210 dbus_set_error (DBusError  *error,
211                 const char *name,
212                 const char *format,
213                 ...)
214 {
215   DBusRealError *real;
216   va_list args, args2;
217   int message_length;
218   char *message;
219   char c;
220
221   if (error == NULL)
222     return TRUE;
223   
224   va_start (args, format);
225
226   va_copy (args2, args);
227   
228   /* Measure the message length */
229   message_length = vsnprintf (&c, 1,format, args) + 1;
230
231   message = dbus_malloc (message_length);
232
233   vsprintf (message, format, args2);
234   
235   if (!message)
236     return FALSE;
237
238   va_end (args);
239
240   dbus_error_init (error);
241   real = (DBusRealError *)error;
242   
243   real->name = name;
244   real->message = message;
245   real->const_message = FALSE;
246   
247   return TRUE;
248 }
249
250 /** @} */