Thursday, December 14, 2006

GnuCash 2.0.3 Bug Fixing

(gnucash:12739): GLib-CRITICAL **: g_date_set_month: assertion `g_date_valid_month (m)' failed

(gnucash:12739): GLib-CRITICAL **: g_date_strftime: assertion `g_date_valid (d)' failed
I had seen the error messages above so often that after 10 minutes, I decided to fix them.

I searched for the error messages and soon landed at the month_name function in src/gnome-utils/gnc-dense-cal.c

#define MONTH_NAME_BUFSIZE 5
/* Takes the number of months since January, in the range 0 to
* 11. Returns the abbreviated month name according to the current
* locale. (i18n'd version of the above static character array.) */
static const gchar *month_name(int mon)
{
static gchar buf[MONTH_NAME_BUFSIZE];
GDate *date;

memset(buf, 0, MONTH_NAME_BUFSIZE);
date = g_date_new();
g_date_set_month(date, mon);
g_date_strftime(buf, MONTH_NAME_BUFSIZE-1, "%b", date);
g_date_free(date);

return buf;
}
The comment above has it: the variable mon will be from 0 to 11 and the number 0 is what choked glib. This is done.

Next, the error message on strftime is cryptic. I went online and searched for what actually g_date_strftime expects and what g_date_new does. From a reliable source, it seems g_date_new creates a new date which is invalid, to make it valid we can use the function g_date_new_dmy.

With all these, let's whack the bugs:

#define MONTH_NAME_BUFSIZE 5
/* Takes the number of months since January, in the range 0 to
* 11. Returns the abbreviated month name according to the current
* locale. (i18n'd version of the above static character array.) */
static const gchar *month_name(int mon)
{
static gchar buf[MONTH_NAME_BUFSIZE];
GDate *date;

memset(buf, 0, MONTH_NAME_BUFSIZE);
/* date = g_date_new();*/
date = g_date_new_dmy(4, G_DATE_JULY, 2006); /* initialize to sane value */
/* printf("%s: setmonth is %d \n", __func__, mon); */ /* Debug statement */
g_date_set_month(date, mon+1);
g_date_strftime(buf, MONTH_NAME_BUFSIZE-1, "%b", date);
g_date_free(date);

return buf;
}
GnuCash developers have my permission to incorporate this fix into the project if they wish.

5 comments:

Anonymous said...

Submit a patch to the developers.

Anonymous said...

Did you upgrade to beta? It doesn't let me post anymore using my blogger account.

And also some javascript error keeps popping up.

Jimmy L. said...

From a s/w engineering viewpoint, this is a failure of documentation or failure of compliance to DBC.

In which case, this hack may have to propagated to several other places...

According to the link you have given, valid months enumerate from 1 to 12. 0 is invalid month, sort of default value.

My guess is to increment 'mon' only. If the g_date_new_dmy is required, it means that there's an extra validity check at g_date_set_month. I would disarm that one, instead of changing g_date_new.

Cuppa Chai said...

As shown at the start of the post, g_date_set_month did give out error message as well. Upon inspection, it seems g_date_new was initialized with invalid values, therefore I used g_date_new_dmy. The error is gone once I had that

Cuppa Chai said...

To 'anonymous': Yes I upgraded to Beta. Could you use firefox to view this page and see if it gets better? :)