2003-02-13 Richard Hult <rhult@codefactory.se>
[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_FIELDS:
115       return "Invalid fields.";
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 void
128 dbus_error_init (DBusError *error)
129 {
130   DBusRealError *real;
131
132   _dbus_assert (error != NULL);
133
134   _dbus_assert (sizeof (DBusError) == sizeof (DBusRealError));
135
136   real = (DBusRealError *)error;
137   
138   real->name = NULL;  
139   real->message = NULL;
140
141   real->const_message = TRUE;
142 }
143
144 void
145 dbus_error_free (DBusError *error)
146 {
147   DBusRealError *real;
148
149   real = (DBusRealError *)error;
150
151   if (!real->const_message)
152     dbus_free (real->message);
153 }
154
155 void
156 dbus_set_error_const (DBusError  *error,
157                       const char *name,
158                       const char *message)
159 {
160   DBusRealError *real;
161
162   if (error == NULL)
163     return;
164
165   dbus_error_init (error);
166   
167   real = (DBusRealError *)error;
168   
169   real->name = name;
170   real->message = (char *)message;
171   real->const_message = TRUE;
172 }
173
174 dbus_bool_t
175 dbus_set_error (DBusError  *error,
176                 const char *name,
177                 const char *format,
178                 ...)
179 {
180   DBusRealError *real;
181   va_list args, args2;
182   int message_length;
183   char *message;
184   char c;
185
186   if (error == NULL)
187     return TRUE;
188   
189   va_start (args, format);
190
191   va_copy (args2, args);
192   
193   /* Measure the message length */
194   message_length = vsnprintf (&c, 1,format, args) + 1;
195
196   message = dbus_malloc (message_length);
197
198   vsprintf (message, format, args2);
199   
200   if (!message)
201     return FALSE;
202
203   va_end (args);
204
205   dbus_error_init (error);
206   real = (DBusRealError *)error;
207   
208   real->name = name;
209   real->message = message;
210   real->const_message = FALSE;
211   
212   return TRUE;
213 }
214
215 /** @} */