X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgerror.c;h=db31692b0038ea71f379a544e142484ca5a8eb33;hb=14f2376c8a06f0936d734ec6a7e0e836072acf65;hp=015d7096801dd794841fe86bea028de6f9af5f65;hpb=5dbc12e9f1477eb699a92b1ef7363b62bdca68eb;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gerror.c b/glib/gerror.c index 015d709..db31692 100644 --- a/glib/gerror.c +++ b/glib/gerror.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* @@ -32,18 +30,18 @@ * GLib provides a standard method of reporting errors from a called * function to the calling code. (This is the same problem solved by * exceptions in other languages.) It's important to understand that - * this method is both a data type (the #GError - * object) and a set of rules. If you use #GError - * incorrectly, then your code will not properly interoperate with other - * code that uses #GError, and users of your API will probably get confused. - * - * First and foremost: #GError should only be used to report - * recoverable runtime errors, never to report programming - * errors. If the programmer has screwed up, then you should - * use g_warning(), g_return_if_fail(), g_assert(), g_error(), or some - * similar facility. (Incidentally, remember that the g_error() function - * should only be used for programming errors, it - * should not be used to print any error reportable via #GError.) + * this method is both a data type (the #GError struct) and a set of + * rules. If you use #GError incorrectly, then your code will not + * properly interoperate with other code that uses #GError, and users + * of your API will probably get confused. + * + * First and foremost: #GError should only be used to report recoverable + * runtime errors, never to report programming errors. If the programmer + * has screwed up, then you should use g_warning(), g_return_if_fail(), + * g_assert(), g_error(), or some similar facility. (Incidentally, + * remember that the g_error() function should only be used for + * programming errors, it should not be used to print any error + * reportable via #GError.) * * Examples of recoverable runtime errors are "file not found" or * "failed to parse input." Examples of programming errors are "NULL @@ -55,71 +53,70 @@ * * Functions that can fail take a return location for a #GError as their * last argument. For example: - * |[ + * |[ * gboolean g_file_get_contents (const gchar *filename, * gchar **contents, * gsize *length, * GError **error); * ]| - * If you pass a non-%NULL value for the error - * argument, it should point to a location where an error can be placed. - * For example: - * |[ + * If you pass a non-%NULL value for the `error` argument, it should + * point to a location where an error can be placed. For example: + * |[ * gchar *contents; * GError *err = NULL; - * g_file_get_contents ("foo.txt", &contents, NULL, &err); - * g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL)); + * + * g_file_get_contents ("foo.txt", &contents, NULL, &err); + * g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL)); * if (err != NULL) * { - * /* Report error to user, and free error */ + * // Report error to user, and free error * g_assert (contents == NULL); - * fprintf (stderr, "Unable to read file: %s\n", err->message); + * fprintf (stderr, "Unable to read file: %s\n", err->message); * g_error_free (err); * } * else * { - * /* Use file contents */ + * // Use file contents * g_assert (contents != NULL); * } * ]| - * Note that err != NULL in this example is a - * reliable indicator of whether - * g_file_get_contents() failed. Additionally, g_file_get_contents() - * returns a boolean which indicates whether it was successful. + * Note that `err != NULL` in this example is a reliable indicator + * of whether g_file_get_contents() failed. Additionally, + * g_file_get_contents() returns a boolean which + * indicates whether it was successful. * * Because g_file_get_contents() returns %FALSE on failure, if you * are only interested in whether it failed and don't need to display - * an error message, you can pass %NULL for the error - * argument: - * |[ - * if (g_file_get_contents ("foo.txt", &contents, NULL, NULL)) /* ignore errors */ - * /* no error occurred */ ; + * an error message, you can pass %NULL for the @error argument: + * |[ + * if (g_file_get_contents ("foo.txt", &contents, NULL, NULL)) // ignore errors + * // no error occurred + * ; * else - * /* error */ ; + * // error + * ; * ]| * - * The #GError object contains three fields: domain - * indicates the module the error-reporting function is located in, - * code indicates the specific error that occurred, - * and message is a user-readable error message with + * The #GError object contains three fields: @domain indicates the module + * the error-reporting function is located in, @code indicates the specific + * error that occurred, and @message is a user-readable error message with * as many details as possible. Several functions are provided to deal * with an error received from a called function: g_error_matches() * returns %TRUE if the error matches a given domain and code, * g_propagate_error() copies an error into an error location (so the * calling function will receive it), and g_clear_error() clears an * error location by freeing the error and resetting the location to - * %NULL. To display an error to the user, simply display - * error->message, perhaps along with additional - * context known only to the calling function (the file being opened, - * or whatever -- though in the g_file_get_contents() case, - * error->message already contains a filename). + * %NULL. To display an error to the user, simply display the @message, + * perhaps along with additional context known only to the calling + * function (the file being opened, or whatever - though in the + * g_file_get_contents() case, the @message already contains a filename). * * When implementing a function that can report errors, the basic * tool is g_set_error(). Typically, if a fatal error occurs you * want to g_set_error(), then return immediately. g_set_error() * does nothing if the error location passed to it is %NULL. * Here's an example: - * |[ + * |[ * gint * foo_open_file (GError **error) * { @@ -127,12 +124,12 @@ * * fd = open ("file.txt", O_RDONLY); * - * if (fd < 0) + * if (fd < 0) * { * g_set_error (error, - * FOO_ERROR, /* error domain */ - * FOO_ERROR_BLAH, /* error code */ - * "Failed to open file: %s", /* error message format string */ + * FOO_ERROR, // error domain + * FOO_ERROR_BLAH, // error code + * "Failed to open file: %s", // error message format string * g_strerror (errno)); * return -1; * } @@ -145,7 +142,7 @@ * function that can report a #GError. If the sub-function indicates * fatal errors in some way other than reporting a #GError, such as * by returning %TRUE on success, you can simply do the following: - * |[ + * |[ * gboolean * my_function_that_can_fail (GError **err) * { @@ -153,12 +150,12 @@ * * if (!sub_function_that_can_fail (err)) * { - * /* assert that error was set by the sub-function */ + * // assert that error was set by the sub-function * g_assert (err == NULL || *err != NULL); * return FALSE; * } * - * /* otherwise continue, no error occurred */ + * // otherwise continue, no error occurred * g_assert (err == NULL || *err == NULL); * } * ]| @@ -167,7 +164,7 @@ * reporting a #GError, you need to create a temporary #GError * since the passed-in one may be %NULL. g_propagate_error() is * intended for use in this case. - * |[ + * |[ * gboolean * my_function_that_can_fail (GError **err) * { @@ -176,23 +173,22 @@ * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); * * tmp_error = NULL; - * sub_function_that_can_fail (&tmp_error); + * sub_function_that_can_fail (&tmp_error); * * if (tmp_error != NULL) * { - * /* store tmp_error in err, if err != NULL, - * * otherwise call g_error_free() on tmp_error - * */ + * // store tmp_error in err, if err != NULL, + * // otherwise call g_error_free() on tmp_error * g_propagate_error (err, tmp_error); * return FALSE; * } * - * /* otherwise continue, no error occurred */ + * // otherwise continue, no error occurred * } * ]| * * Error pileups are always a bug. For example, this code is incorrect: - * |[ + * |[ * gboolean * my_function_that_can_fail (GError **err) * { @@ -201,8 +197,8 @@ * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); * * tmp_error = NULL; - * sub_function_that_can_fail (&tmp_error); - * other_function_that_can_fail (&tmp_error); + * sub_function_that_can_fail (&tmp_error); + * other_function_that_can_fail (&tmp_error); * * if (tmp_error != NULL) * { @@ -211,15 +207,15 @@ * } * } * ]| - * tmp_error should be checked immediately after - * sub_function_that_can_fail(), and either cleared or propagated - * upward. The rule is: after each error, you must either - * handle the error, or return it to the calling function. + * @tmp_error should be checked immediately after sub_function_that_can_fail(), + * and either cleared or propagated upward. The rule is: after each error, + * you must either handle the error, or return it to the calling function. + * * Note that passing %NULL for the error location is the equivalent * of handling an error by always doing nothing about it. So the * following code is fine, assuming errors in sub_function_that_can_fail() * are not fatal to my_function_that_can_fail(): - * |[ + * |[ * gboolean * my_function_that_can_fail (GError **err) * { @@ -227,10 +223,10 @@ * * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); * - * sub_function_that_can_fail (NULL); /* ignore errors */ + * sub_function_that_can_fail (NULL); // ignore errors * * tmp_error = NULL; - * other_function_that_can_fail (&tmp_error); + * other_function_that_can_fail (&tmp_error); * * if (tmp_error != NULL) * { @@ -240,118 +236,118 @@ * } * ]| * - * Note that passing %NULL for the error location - * ignores errors; it's equivalent to - * try { sub_function_that_can_fail (); } catch (...) {} - * in C++. It does not mean to leave errors - * unhandled; it means to handle them by doing nothing. + * Note that passing %NULL for the error location ignores errors; + * it's equivalent to + * `try { sub_function_that_can_fail (); } catch (...) {}` + * in C++. It does not mean to leave errors unhandled; it means + * to handle them by doing nothing. * * Error domains and codes are conventionally named as follows: - * - * - * The error domain is called - * <NAMESPACE>_<MODULE>_ERROR, + * + * - The error domain is called __ERROR, * for example %G_SPAWN_ERROR or %G_THREAD_ERROR: - * |[ - * #define G_SPAWN_ERROR g_spawn_error_quark () + * |[ + * #define G_SPAWN_ERROR g_spawn_error_quark () * - * GQuark - * g_spawn_error_quark (void) - * { - * return g_quark_from_static_string ("g-spawn-error-quark"); - * } + * GQuark + * g_spawn_error_quark (void) + * { + * return g_quark_from_static_string ("g-spawn-error-quark"); + * } * ]| - * - * - * The quark function for the error domain is called - * <namespace>_<module>_error_quark, - * for example g_spawn_error_quark() or %g_thread_error_quark(). - * - * - * The error codes are in an enumeration called - * <Namespace><Module>Error; - * for example,#GThreadError or #GSpawnError. - * - * - * Members of the error code enumeration are called - * <NAMESPACE>_<MODULE>_ERROR_<CODE>, + * + * - The quark function for the error domain is called + * __error_quark, + * for example g_spawn_error_quark() or g_thread_error_quark(). + * + * - The error codes are in an enumeration called + * Error; + * for example, #GThreadError or #GSpawnError. + * + * - Members of the error code enumeration are called + * __ERROR_, * for example %G_SPAWN_ERROR_FORK or %G_THREAD_ERROR_AGAIN. - * - * - * If there's a "generic" or "unknown" error code for unrecoverable + * + * - If there's a "generic" or "unknown" error code for unrecoverable * errors it doesn't make sense to distinguish with specific codes, - * it should be called <NAMESPACE>_<MODULE>_ERROR_FAILED, - * for example %G_SPAWN_ERROR_FAILED or %G_THREAD_ERROR_FAILED. - * - * + * it should be called __ERROR_FAILED, + * for example %G_SPAWN_ERROR_FAILED. In the case of error code + * enumerations that may be extended in future releases, you should + * generally not handle this error code explicitly, but should + * instead treat any unrecognized error code as equivalent to + * FAILED. * * Summary of rules for use of #GError: - * - * - * Do not report programming errors via #GError. - * - * - * The last argument of a function that returns an error should + * + * - Do not report programming errors via #GError. + * + * - The last argument of a function that returns an error should * be a location where a #GError can be placed (i.e. "#GError** error"). * If #GError is used with varargs, the #GError** should be the last * argument before the "...". - * - * - * The caller may pass %NULL for the #GError** if they are not interested + * + * - The caller may pass %NULL for the #GError** if they are not interested * in details of the exact error that occurred. - * - * - * If %NULL is passed for the #GError** argument, then errors should + * + * - If %NULL is passed for the #GError** argument, then errors should * not be returned to the caller, but your function should still * abort and return if an error occurs. That is, control flow should * not be affected by whether the caller wants to get a #GError. - * - * - * If a #GError is reported, then your function by definition - * had a fatal failure and did not complete whatever - * it was supposed to do. If the failure was not fatal, - * then you handled it and you should not report it. If it was fatal, - * then you must report it and discontinue whatever you were doing - * immediately. - * - * - * A #GError* must be initialized to %NULL before passing its address + * + * - If a #GError is reported, then your function by definition had a + * fatal failure and did not complete whatever it was supposed to do. + * If the failure was not fatal, then you handled it and you should not + * report it. If it was fatal, then you must report it and discontinue + * whatever you were doing immediately. + * + * - If a #GError is reported, out parameters are not guaranteed to + * be set to any defined value. + * + * - A #GError* must be initialized to %NULL before passing its address * to a function that can report errors. - * - * - * "Piling up" errors is always a bug. That is, if you assign a + * + * - "Piling up" errors is always a bug. That is, if you assign a * new #GError to a #GError* that is non-%NULL, thus overwriting * the previous error, it indicates that you should have aborted * the operation instead of continuing. If you were able to continue, * you should have cleared the previous error with g_clear_error(). * g_set_error() will complain if you pile up errors. - * - * - * By convention, if you return a boolean value indicating success - * then %TRUE means success and %FALSE means failure. If %FALSE is - * returned, the error must be set to a non-%NULL - * value. - * - * - * A %NULL return value is also frequently used to mean that an error + * + * - By convention, if you return a boolean value indicating success + * then %TRUE means success and %FALSE means failure. + * Avoid creating functions which have a boolean + * return value and a GError parameter, but where the boolean does + * something other than signal whether the GError is set. Among other + * problems, it requires C callers to allocate a temporary error. Instead, + * provide a "gboolean *" out parameter. There are functions in GLib + * itself such as g_key_file_has_key() that are deprecated because of this. + * + * If %FALSE is + * returned, the error must be set to a non-%NULL value. + * One exception to this is that in situations that are + * already considered to be undefined behaviour (such as when a + * g_return_val_if_fail() check fails), the error need not be set. + * Instead of checking separately whether the error is set, callers + * should ensure that they do not provoke undefined behaviour, then + * assume that the error will be set on failure. + * + * - A %NULL return value is also frequently used to mean that an error * occurred. You should make clear in your documentation whether %NULL * is a valid return value in non-error cases; if %NULL is a valid value, * then users must check whether an error was returned to see if the * function succeeded. - * - * - * When implementing a function that can report errors, you may want + * + * - When implementing a function that can report errors, you may want * to add a check at the top of your function that the error return * location is either %NULL or contains a %NULL error (e.g. - * g_return_if_fail (error == NULL || *error == NULL);). - * - * + * `g_return_if_fail (error == NULL || *error == NULL);`). */ #include "config.h" #include "gerror.h" +#include "gslice.h" #include "gstrfuncs.h" #include "gtestutils.h" @@ -377,6 +373,14 @@ g_error_new_valist (GQuark domain, { GError *error; + /* Historically, GError allowed this (although it was never meant to work), + * and it has significant use in the wild, which g_return_val_if_fail + * would break. It should maybe g_return_val_if_fail in GLib 4. + * (GNOME#660371, GNOME#560482) + */ + g_warn_if_fail (domain != 0); + g_warn_if_fail (format != NULL); + error = g_slice_new (GError); error->domain = domain; @@ -396,7 +400,7 @@ g_error_new_valist (GQuark domain, * Creates a new #GError with the given @domain and @code, * and a message formatted with @format. * - * Return value: a new #GError + * Returns: a new #GError */ GError* g_error_new (GQuark domain, @@ -428,7 +432,7 @@ g_error_new (GQuark domain, * @message contains text you don't have control over, * that could include printf() escape sequences. * - * Return value: a new #GError + * Returns: a new #GError **/ GError* g_error_new_literal (GQuark domain, @@ -471,7 +475,7 @@ g_error_free (GError *error) * * Makes a copy of @error. * - * Return value: a new #GError + * Returns: a new #GError */ GError* g_error_copy (const GError *error) @@ -479,6 +483,9 @@ g_error_copy (const GError *error) GError *copy; g_return_val_if_fail (error != NULL, NULL); + /* See g_error_new_valist for why these don't return */ + g_warn_if_fail (error->domain != 0); + g_warn_if_fail (error->message != NULL); copy = g_slice_new (GError); @@ -491,7 +498,7 @@ g_error_copy (const GError *error) /** * g_error_matches: - * @error: a #GError or %NULL + * @error: (allow-none): a #GError or %NULL * @domain: an error domain * @code: an error code * @@ -499,7 +506,14 @@ g_error_copy (const GError *error) * otherwise. In particular, when @error is %NULL, %FALSE will * be returned. * - * Return value: whether @error has @domain and @code + * If @domain contains a `FAILED` (or otherwise generic) error code, + * you should generally not check for it explicitly, but should + * instead treat any not-explicitly-recognized error code as being + * equilalent to the `FAILED` code. This way, if the domain is + * extended in the future to provide a more specific error code for + * a certain case, your code will still work. + * + * Returns: whether @error has @domain and @code */ gboolean g_error_matches (const GError *error, @@ -517,7 +531,7 @@ g_error_matches (const GError *error, /** * g_set_error: - * @err: a return location for a #GError, or %NULL + * @err: (allow-none): a return location for a #GError, or %NULL * @domain: error domain * @code: error code * @format: printf()-style format @@ -547,12 +561,15 @@ g_set_error (GError **err, if (*err == NULL) *err = new; else - g_warning (ERROR_OVERWRITTEN_WARNING, new->message); + { + g_warning (ERROR_OVERWRITTEN_WARNING, new->message); + g_error_free (new); + } } /** * g_set_error_literal: - * @err: a return location for a #GError, or %NULL + * @err: (allow-none): a return location for a #GError, or %NULL * @domain: error domain * @code: error code * @message: error message @@ -571,16 +588,13 @@ g_set_error_literal (GError **err, gint code, const gchar *message) { - GError *new; - if (err == NULL) return; - new = g_error_new_literal (domain, code, message); if (*err == NULL) - *err = new; + *err = g_error_new_literal (domain, code, message); else - g_warning (ERROR_OVERWRITTEN_WARNING, new->message); + g_warning (ERROR_OVERWRITTEN_WARNING, message); } /** @@ -606,7 +620,10 @@ g_propagate_error (GError **dest, else { if (*dest != NULL) - g_warning (ERROR_OVERWRITTEN_WARNING, src->message); + { + g_warning (ERROR_OVERWRITTEN_WARNING, src->message); + g_error_free (src); + } else *dest = src; } @@ -629,6 +646,7 @@ g_clear_error (GError **err) } } +G_GNUC_PRINTF(2, 0) static void g_error_add_prefix (gchar **string, const gchar *format, @@ -646,20 +664,17 @@ g_error_add_prefix (gchar **string, /** * g_prefix_error: - * @err: a return location for a #GError, or %NULL + * @err: (allow-none): a return location for a #GError, or %NULL * @format: printf()-style format string * @...: arguments to @format * - * Formats a string according to @format and - * prefix it to an existing error message. If - * @err is %NULL (ie: no error variable) then do + * Formats a string according to @format and prefix it to an existing + * error message. If @err is %NULL (ie: no error variable) then do * nothing. * - * If *@err is %NULL (ie: an error variable is - * present but there is no error condition) then - * also do nothing. Whether or not it makes - * sense to take advantage of this feature is up - * to you. + * If *@err is %NULL (ie: an error variable is present but there is no + * error condition) then also do nothing. Whether or not it makes sense + * to take advantage of this feature is up to you. * * Since: 2.16 */ @@ -685,9 +700,8 @@ g_prefix_error (GError **err, * @format: printf()-style format string * @...: arguments to @format * - * If @dest is %NULL, free @src; otherwise, - * moves @src into *@dest. *@dest must be %NULL. - * After the move, add a prefix as with + * If @dest is %NULL, free @src; otherwise, moves @src into *@dest. + * *@dest must be %NULL. After the move, add a prefix as with * g_prefix_error(). * * Since: 2.16