/**
 * Assigns an error name and message to a DBusError.  Does nothing if
 * error is #NULL. The message may be #NULL, which means a default
 * message will be deduced from the name. The default message will be
 * totally useless, though, so using a #NULL message is not recommended.
 *
 * Because this function does not copy the error name or message, you
 * must ensure the name and message are global data that won't be
 * freed. You probably want dbus_set_error() instead, in most cases.
 * 
 * @param error the error or #NULL
 * @param name the error name (not copied!!!)
 * @param message the error message (not copied!!!)
 */
void
dbus_set_error_const (DBusError  *error,
		      const char *name,
		      const char *message)
{
  DBusRealError *real;

  _dbus_return_if_error_is_set (error);
  _dbus_return_if_fail (name != NULL);
  
  if (error == NULL)
    return;

  _dbus_assert (error->name == NULL);
  _dbus_assert (error->message == NULL);

  if (message == NULL)
    message = message_from_error (name);
  
  real = (DBusRealError *)error;
  
  real->name = (char*) name;
  real->message = (char *)message;
  real->const_message = TRUE;
}
void
_dbus_set_error_valist (DBusError  *error,
                        const char *name,
                        const char *format,
                        va_list     args)
{
  DBusRealError *real;
  DBusString str;

  _dbus_assert (name != NULL);

  if (error == NULL)
    return;

  _dbus_assert (error->name == NULL);
  _dbus_assert (error->message == NULL);

  if (!_dbus_string_init (&str))
    goto nomem;
  
  if (format == NULL)
    {
      if (!_dbus_string_append (&str,
                                message_from_error (name)))
        {
          _dbus_string_free (&str);
          goto nomem;
        }
    }
  else
    {
      if (!_dbus_string_append_printf_valist (&str, format, args))
        {
          _dbus_string_free (&str);
          goto nomem;
        }
    }

  real = (DBusRealError *)error;

  if (!_dbus_string_steal_data (&str, &real->message))
    {
      _dbus_string_free (&str);
      goto nomem;
    }
  _dbus_string_free (&str);
  
  real->name = _dbus_strdup (name);
  if (real->name == NULL)
    {
      dbus_free (real->message);
      real->message = NULL;
      goto nomem;
    }
  real->const_message = FALSE;

  return;
  
 nomem:
  _DBUS_SET_OOM (error);
}
/**
 * Assigns an error name and message to a DBusError.
 * Does nothing if error is #NULL.
 *
 * The format may be #NULL, which means a (pretty much useless)
 * default message will be deduced from the name. This is not a good
 * idea, just go ahead and provide a useful error message. It won't
 * hurt you.
 *
 * If no memory can be allocated for the error message, 
 * an out-of-memory error message will be set instead.
 *
 * @param error the error.or #NULL
 * @param name the error name
 * @param format printf-style format string.
 */
void
dbus_set_error (DBusError  *error,
		const char *name,
		const char *format,
		...)
{
  DBusRealError *real;
  DBusString str;
  va_list args;
  
  if (error == NULL)
    return;

  /* it's a bug to pile up errors */
  _dbus_return_if_error_is_set (error);
  _dbus_return_if_fail (name != NULL);
  
  _dbus_assert (error->name == NULL);
  _dbus_assert (error->message == NULL);

  if (!_dbus_string_init (&str))
    goto nomem;
  
  if (format == NULL)
    {
      if (!_dbus_string_append (&str,
                                message_from_error (name)))
        {
          _dbus_string_free (&str);
          goto nomem;
        }
    }
  else
    {
      va_start (args, format);
      if (!_dbus_string_append_printf_valist (&str, format, args))
        {
          _dbus_string_free (&str);
          va_end (args);
          goto nomem;
        }
      va_end (args);
    }

  real = (DBusRealError *)error;

  if (!_dbus_string_steal_data (&str, &real->message))
    {
      _dbus_string_free (&str);
      goto nomem;
    }
  _dbus_string_free (&str);
  
  real->name = _dbus_strdup (name);
  if (real->name == NULL)
    {
      dbus_free (real->message);
      real->message = NULL;
      goto nomem;
    }
  real->const_message = FALSE;

  return;
  
 nomem:
  _DBUS_SET_OOM (error);
}