From af7ac6c3a13b3bc1771fdf55750644ea5f2cb3cd Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Tue, 22 Aug 2000 01:35:47 +0000 Subject: [PATCH] Clean up date code. Move Transaction date string routines to Transaction.c from date.c. Move Timespec definition from Transaction.h to date.h. Use 'const char *' for date routines where appropriate. Fix a memory leak in reconcile-list.c. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2685 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 7 +++ src/engine/Transaction.c | 16 ++++++ src/engine/Transaction.h | 36 +++++------- src/engine/date.c | 49 +++++------------ src/engine/date.h | 103 +++++++++++++++++++++-------------- src/engine/util.c | 10 ++-- src/engine/util.h | 21 ++++--- src/gnome/dialog-transfer.c | 6 +- src/gnome/reconcile-list.c | 16 ++++-- src/gnome/window-adjust.c | 11 ++-- src/gnome/window-reconcile.c | 11 ++-- src/register/datecell.h | 2 +- 12 files changed, 152 insertions(+), 136 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce1786a59a..adab338df6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2000-08-21 Dave Peticolas + * src/gnome/reconcile-list.c (gnc_reconcile_list_fill): fix + a memory leak. xaccTransGetDateStr returns a malloc'd string. + + * src/engine/: Move transaction date routines from date.c to + Transaction.c. Move definition of Timespec from Transaction.h + to date.h. Some code cleanup in date.c. + * src/register/QuickFill.c (qfInsertTextRec): When inserting new strings, don't replace older strings that are prefixes of the new string. diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index fff95dfbc8..bc07687282 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -1865,6 +1865,22 @@ xaccTransSetDateTS (Transaction *trans, const Timespec *ts) trans->date_posted.tv_nsec = ts->tv_nsec; } +char * +xaccTransGetDateStr (Transaction *trans) +{ + char buf [MAX_DATE_LENGTH]; + struct tm *date; + time_t secs; + + secs = xaccTransGetDate (trans); + + date = localtime (&secs); + + printDate(buf, date->tm_mday, date->tm_mon+1, date->tm_year +1900); + + return strdup (buf); +} + void xaccTransSetDateEnteredTS (Transaction *trans, const Timespec *ts) { diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h index dbe2ddd0de..c6d8bfdb96 100644 --- a/src/engine/Transaction.h +++ b/src/engine/Transaction.h @@ -32,6 +32,7 @@ #include "gnc-common.h" #include "kvp_frame.h" #include "GNCId.h" +#include "date.h" /* Values for the reconciled field in Transaction: */ @@ -58,22 +59,6 @@ typedef struct _account_group AccountGroup; typedef struct _split Split; typedef struct _transaction Transaction; -/* struct timespec64 is just like timespec except that we use - * a 64-bit signed int to store the seconds. This should adequately - * cover dates in the distant future as well as the distant past, as long - * as they're not more than a couple dozen times the age of the universe. - * Note that both gcc and the IBM Toronto xlC compiler (aka CSet, - * VisualAge, etc) correctly handle long long as a 64 bit quantity, - * even on the 32-bit Intel x86 and PowerPC architectures. I'm assuming - * that all the other modern compilers are clean on this issue too ... - */ -#ifndef SWIG /* swig 1.1p5 can't hack the long long type */ -struct timespec64 { - long long int tv_sec; - long int tv_nsec; -}; -#endif /* SWIG */ -typedef struct timespec64 Timespec; /** PROTOTYPES ******************************************************/ @@ -166,15 +151,14 @@ Transaction * xaccTransLookup (const GUID *guid); * strings, numbers, and structures which aren't "official" members * of the transaction structure. */ -kvp_value * xaccTransGetSlot(Transaction * trans, const char * key); -void xaccTransSetSlot(Transaction * trans, const char * key, - const kvp_value * value); +kvp_value * xaccTransGetSlot(Transaction * trans, const char * key); +void xaccTransSetSlot(Transaction * trans, const char * key, + const kvp_value * value); /* Convert a day, month, and year to a Timespec */ Timespec gnc_dmy2timespec(int day, int month, int year); -/* - * The xaccTransSetDateSecs() method will modify the posted date +/* The xaccTransSetDateSecs() method will modify the posted date * of the transaction. (Footnote: this shouldn't matter to a user, * but anyone modifying the engine should understand that when * xaccTransCommitEdit() is called, the date order of each of the @@ -264,7 +248,15 @@ long long xaccTransGetDateL (Transaction *); void xaccTransGetDateTS (Transaction *, Timespec *); void xaccTransGetDateEnteredTS (Transaction *, Timespec *); -/* return the number of splits */ +/* The xaccTransGetDateStr() method will return a malloc'ed string + * representing the posted date of the transaction, or NULL if + * the argument is NULL. + */ +char * xaccTransGetDateStr (Transaction *trans); + +/* The xaccTransCountSplits() method returns the number of splits + * in a transaction. + */ int xaccTransCountSplits (Transaction *trans); diff --git a/src/engine/date.c b/src/engine/date.c index 1019f810f0..349e7797d1 100644 --- a/src/engine/date.c +++ b/src/engine/date.c @@ -133,6 +133,7 @@ void printDateSecs (char * buff, time_t t) { struct tm *theTime; + if (!buff) return; theTime = localtime(&t); @@ -150,10 +151,10 @@ xaccPrintDateSecs (time_t t) return strdup (buff); } -char * +const char * gnc_print_date(Timespec ts) { - static char buff[256]; + static char buff[MAX_DATE_LENGTH]; time_t t; t = ts.tv_sec + (ts.tv_nsec / 1000000000.0); @@ -186,11 +187,13 @@ scanDate(const char *buff, int *day, int *month, int *year) struct tm *now; if (!buff) return; - dupe = strdup (buff); + + dupe = g_strdup (buff); + tmp = dupe; - first_field = 0x0; - second_field = 0x0; - third_field = 0x0; + first_field = NULL; + second_field = NULL; + third_field = NULL; /* use strtok to find delimiters */ if (tmp) { @@ -246,13 +249,12 @@ scanDate(const char *buff, int *day, int *month, int *year) break; } - free (dupe); + g_free (dupe); /* if the year entered is smaller than 100, assume we mean the current century (and are not revising some roman emperor's books) */ - if(iyear<100) { + if (iyear < 100) iyear += ((int) ((now->tm_year+1950-iyear)/100)) * 100; - } if (year) *year=iyear; if (month) *month=imonth; @@ -272,6 +274,7 @@ scanDate(const char *buff, int *day, int *month, int *year) char dateSeparator() { char separator; + switch(dateFormat) { case DATE_FORMAT_CE: @@ -286,39 +289,13 @@ char dateSeparator() separator='/'; break; } + return separator; } /********************************************************************\ \********************************************************************/ -char * -xaccTransGetDateStr (Transaction *trans) -{ - char buf [MAX_DATE_LENGTH]; - time_t secs; - struct tm *date; - - secs = xaccTransGetDate (trans); - - date = localtime (&secs); - - printDate(buf, date->tm_mday, date->tm_mon+1, date->tm_year +1900); - return strdup (buf); -} - -void -xaccTransSetDateStr (Transaction *trans, char *str) -{ - int day, month, year; - - /* hack alert -- the date string should be parsed for time values */ - /* cvs has some cool date parsing/guessing code .. maybe steal - * that code from there ... */ - scanDate(str, &day, &month, &year); - xaccTransSetDate (trans, day, month, year); -} - time_t xaccDMYToSec (int day, int month, int year) { diff --git a/src/engine/date.h b/src/engine/date.h index 223bd67e8f..cd1fc9ab55 100644 --- a/src/engine/date.h +++ b/src/engine/date.h @@ -1,6 +1,6 @@ /********************************************************************\ * date.h -- utility functions to handle the date (adjusting, get * - * current date, etc.) for xacc (X-Accountant) * + * current date, etc.) for GnuCash * * Copyright (C) 1997 Robin D. Clark (rclark@cs.hmc.edu) * * Copyright (C) 1998, 1999, 2000 Linas Vepstas * * * @@ -22,14 +22,60 @@ * Boston, MA 02111-1307, USA gnu@gnu.org * \********************************************************************/ -/* - * hack alert -- the scan and print routines should probably be moved - * to somewhere else ... the engine really isn't involved with things - * like printing formats. This is needed mostl;y by the GUI and so on. - * If a file-io thing needs date handling, it should do it itself, instead - * of depending on the routines here ... - */ +/* hack alert -- the scan and print routines should probably be moved + * to somewhere else. The engine really isn't involved with things + * like printing formats. This is needed mostly by the GUI and so on. + * If a file-io thing needs date handling, it should do it itself, + * instead of depending on the routines here. */ +#ifndef __XACC_DATE_H__ +#define __XACC_DATE_H__ + +#include "config.h" + + +/** Constants *******************************************************/ + +typedef enum +{ + DATE_FORMAT_US, /* United states: mm/dd/yyyy */ + DATE_FORMAT_UK, /* Britain: dd/mm/yyyy */ + DATE_FORMAT_CE, /* Continental Europe: dd.mm.yyyy */ + DATE_FORMAT_ISO, /* ISO: yyyy-mm-dd */ + DATE_FORMAT_LOCALE /* Take from locale information */ +} DateFormat; + +#define DATE_FORMAT_FIRST DATE_FORMAT_US +#define DATE_FORMAT_LAST DATE_FORMAT_LOCALE + +/* the maximum length of a string created by the date printers */ +#define MAX_DATE_LENGTH 11 + + +/** Datatypes *******************************************************/ + +/* struct timespec64 is just like timespec except that we use a 64-bit + * signed int to store the seconds. This should adequately cover + * dates in the distant future as well as the distant past, as long as + * they're not more than a couple dozen times the age of the universe. + * Note that both gcc and the IBM Toronto xlC compiler (aka CSet, + * VisualAge, etc) correctly handle long long as a 64 bit quantity, + * even on the 32-bit Intel x86 and PowerPC architectures. I'm + * assuming that all the other modern compilers are clean on this + * issue too. */ +#ifndef SWIG /* swig 1.1p5 can't hack the long long type */ +struct timespec64 +{ + long long int tv_sec; + long int tv_nsec; +}; +#endif /* SWIG */ + +typedef struct timespec64 Timespec; + + +/** Prototypes ******************************************************/ +void setDateFormat(DateFormat df); /** * printDate @@ -46,6 +92,11 @@ * * Globals: global dateFormat value */ +void printDate (char * buff, int day, int month, int year); +void printDateSecs (char * buff, time_t secs); + +char * xaccPrintDateSecs (time_t secs); +const char * gnc_print_date(Timespec ts); /** * scanDate @@ -61,6 +112,8 @@ * * Globals: global dateFormat value */ +void scanDate (const char *buff, int *day, int *monty, int *year); + /** * dateSeparator * Return the field separator for the current date format @@ -71,42 +124,8 @@ * * Globals: global dateFormat value */ - - -#ifndef __XACC_DATE_H__ -#define __XACC_DATE_H__ - -#include "config.h" -#include "Transaction.h" - -typedef enum -{ - DATE_FORMAT_US, /* United states: mm/dd/yyyy */ - DATE_FORMAT_UK, /* Britain: dd/mm/yyyy */ - DATE_FORMAT_CE, /* Continental Europe: dd.mm.yyyy */ - DATE_FORMAT_ISO, /* ISO: yyyy-mm-dd */ - DATE_FORMAT_LOCALE /* Take from locale information */ -} DateFormat; - -#define DATE_FORMAT_FIRST DATE_FORMAT_US -#define DATE_FORMAT_LAST DATE_FORMAT_LOCALE -/* the maximum length of a string created by sprtDate() */ -#define MAX_DATE_LENGTH 11 - -/** PROTOTYPES ******************************************************/ -void setDateFormat(DateFormat df); -void printDate (char * buff, int day, int month, int year); -void printDateSecs (char * buff, time_t secs); - -char * xaccPrintDateSecs (time_t secs); -char * gnc_print_date(Timespec ts); - -void scanDate (const char *buff, int *day, int *monty, int *year); char dateSeparator(void); -char * xaccTransGetDateStr (Transaction *trans); -void xaccTransSetDateStr (Transaction *trans, char *str); - time_t xaccDMYToSec (int day, int month, int year); time_t xaccScanDateS (const char *buff); diff --git a/src/engine/util.c b/src/engine/util.c index 11da2955c5..43882f14a6 100644 --- a/src/engine/util.c +++ b/src/engine/util.c @@ -43,7 +43,7 @@ char * stpcpy (char *dest, const char *src); /** GLOBALS *********************************************************/ -gncLogLevel loglevel[MOD_NUM] = +gncLogLevel loglevel[MOD_LAST + 1] = { GNC_LOG_NOTHING, /* DUMMY */ GNC_LOG_WARNING, /* ENGINE */ @@ -75,7 +75,7 @@ gnc_set_log_level_global(gncLogLevel level) { gncModuleType module; - for (module = GNC_LOG_NOTHING; module < MOD_NUM; module++) + for (module = GNC_LOG_NOTHING; module <= MOD_LAST; module++) loglevel[module] = level; } @@ -446,7 +446,7 @@ gnc_localeconv() return &lc; } -char * +const char * gnc_locale_default_currency() { static char currency[4]; @@ -758,7 +758,7 @@ xaccSPrintAmount (char * bufp, double val, GNCPrintAmountFlags flags, min_trailing_zeros, curr_code); } -char * +const char * xaccPrintAmount (double val, GNCPrintAmountFlags flags, const char *curr_code) { /* hack alert -- this is not thread safe ... */ @@ -770,7 +770,7 @@ xaccPrintAmount (double val, GNCPrintAmountFlags flags, const char *curr_code) return buf; } -char * +const char * xaccPrintAmountArgs (double val, gboolean print_currency_symbol, gboolean print_separators, gboolean is_shares_value, const char *curr_code) diff --git a/src/engine/util.h b/src/engine/util.h index d6f870efb8..9cb9f2f3d9 100644 --- a/src/engine/util.h +++ b/src/engine/util.h @@ -58,8 +58,7 @@ typedef enum MOD_GUILE = 9, MOD_BACKEND = 10, MOD_QUERY = 11, - MOD_LAST = 11, - MOD_NUM = MOD_LAST + 1 + MOD_LAST = 11 } gncModuleType; typedef enum @@ -72,7 +71,7 @@ typedef enum GNC_LOG_EVERYTHING = 5 } gncLogLevel; -extern gncLogLevel loglevel[MOD_NUM]; +extern gncLogLevel loglevel[MOD_LAST + 1]; #define LERR (1 <= loglevel[module]) #define LWARN (2 <= loglevel[module]) @@ -200,7 +199,7 @@ gboolean gnc_strisnum(const char *s); struct lconv * gnc_localeconv(); /* Returns the 3 character currency code of the current locale. */ -char * gnc_locale_default_currency(); +const char * gnc_locale_default_currency(); /* @@ -248,8 +247,8 @@ char * gnc_locale_default_currency(); typedef unsigned int GNCPrintAmountFlags; -char * xaccPrintAmount (double val, GNCPrintAmountFlags flags, - const char *curr_code); +const char * xaccPrintAmount (double val, GNCPrintAmountFlags flags, + const char *curr_code); int xaccSPrintAmount (char *buf, double val, GNCPrintAmountFlags flags, const char *curr_code); int xaccSPrintAmountGeneral (char * bufp, double val, @@ -257,11 +256,11 @@ int xaccSPrintAmountGeneral (char * bufp, double val, int precision, int min_trailing_zeros, const char *curr_sym); -char * xaccPrintAmountArgs (double val, - gboolean print_currency_symbol, - gboolean print_separators, - gboolean is_shares_value, - const char *curr_code); +const char * xaccPrintAmountArgs (double val, + gboolean print_currency_symbol, + gboolean print_separators, + gboolean is_shares_value, + const char *curr_code); /* Parse i18n amount strings */ double xaccParseAmount (const char * instr, gboolean monetary); diff --git a/src/gnome/dialog-transfer.c b/src/gnome/dialog-transfer.c index 7bee83ac01..c5c51db85f 100644 --- a/src/gnome/dialog-transfer.c +++ b/src/gnome/dialog-transfer.c @@ -144,9 +144,9 @@ gnc_xfer_update_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data) GtkEntry *entry = GTK_ENTRY(widget); XferDialog *xferData = data; Account *account; - gchar *new_string; + const char *new_string; const char *currency; - gchar *string; + const char *string; double value; account = gnc_account_tree_get_current_account(xferData->from); @@ -254,7 +254,7 @@ gnc_xfer_dialog_set_amount(XferDialog *xferData, double amount) { Account *account; const char *currency; - gchar *string; + const char *string; if (xferData == NULL) return; diff --git a/src/gnome/reconcile-list.c b/src/gnome/reconcile-list.c index ac8819fead..3885993396 100644 --- a/src/gnome/reconcile-list.c +++ b/src/gnome/reconcile-list.c @@ -573,7 +573,7 @@ gnc_reconcile_list_set_sort_order(GNCReconcileList *list, sort_type_t key) static void gnc_reconcile_list_fill(GNCReconcileList *list) { - gchar *strings[list->num_columns + 1]; + const gchar *strings[list->num_columns + 1]; GNCPrintAmountFlags flags = PRTSEP; GNCAccountType account_type; gboolean reconciled; @@ -600,6 +600,8 @@ gnc_reconcile_list_fill(GNCReconcileList *list) for ( ; *splits != NULL; splits++) { + Timespec ts; + split = *splits; recn = xaccSplitGetReconcile(split); @@ -618,16 +620,18 @@ gnc_reconcile_list_fill(GNCReconcileList *list) trans = xaccSplitGetParent(split); - strings[0] = xaccTransGetDateStr(trans); - strings[1] = (char *) xaccTransGetNum(trans); - strings[2] = (char *) xaccTransGetDescription(trans); + xaccTransGetDateTS(trans, &ts); + + strings[0] = gnc_print_date(ts); + strings[1] = xaccTransGetNum(trans); + strings[2] = xaccTransGetDescription(trans); strings[3] = xaccPrintAmount(DABS(amount), flags, currency); reconciled = g_hash_table_lookup(list->reconciled, split) != NULL; recn = reconciled ? YREC : recn; - strings[4] = (char *) gnc_get_reconcile_str(recn); + strings[4] = gnc_get_reconcile_str(recn); - row = gtk_clist_append(GTK_CLIST(list), strings); + row = gtk_clist_append(GTK_CLIST(list), (gchar **) strings); gtk_clist_set_row_data(GTK_CLIST(list), row, split); gnc_reconcile_list_set_row_style(list, row, reconciled); diff --git a/src/gnome/window-adjust.c b/src/gnome/window-adjust.c index 9143d28165..5c91eee3d8 100644 --- a/src/gnome/window-adjust.c +++ b/src/gnome/window-adjust.c @@ -157,9 +157,9 @@ gnc_adjust_update_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data) { GtkEntry *entry = GTK_ENTRY(widget); Account *account = data; - gchar *new_string; + const char *new_string; const char *currency; - gchar *string; + const char *string; double value; string = gtk_entry_get_text(entry); @@ -251,8 +251,9 @@ adjBWindow(Account *account) GtkWidget *hbox, *vbox; GtkWidget *amount, *date; GtkWidget *label, *entry; + const char *amount_str; const char *currency; - gchar *string; + char *string; tooltips = gtk_tooltips_new(); @@ -296,8 +297,8 @@ adjBWindow(Account *account) gtk_tooltips_set_tip(tooltips, amount, TOOLTIP_ADJUST_AMOUNT, NULL); currency = xaccAccountGetCurrency(account); - string = xaccPrintAmount(0.0, PRTSEP, currency); - gtk_entry_set_text(GTK_ENTRY(amount), string); + amount_str = xaccPrintAmount(0.0, PRTSEP, currency); + gtk_entry_set_text(GTK_ENTRY(amount), amount_str); gtk_entry_select_region(GTK_ENTRY(amount), 0, -1); gtk_signal_connect(GTK_OBJECT(amount), "focus-out-event", diff --git a/src/gnome/window-reconcile.c b/src/gnome/window-reconcile.c index d625da38de..120e6d50d0 100644 --- a/src/gnome/window-reconcile.c +++ b/src/gnome/window-reconcile.c @@ -171,7 +171,7 @@ recnRefresh(Account *account) static double recnRecalculateBalance(RecnWindow *recnData) { - char *amount; + const char *amount; const char *currency; double debit; double credit; @@ -261,8 +261,8 @@ gnc_start_recn_update_cb(GtkWidget *widget, GdkEventFocus *event, Account *account = data; int account_type; const char *currency; - gchar *new_string; - gchar *string; + const char *new_string; + const char *string; double value; flags = PRTSYM | PRTSEP; @@ -307,11 +307,12 @@ startRecnWindow(GtkWidget *parent, Account *account, double *new_ending, time_t *statement_date) { GtkWidget *dialog, *end_value, *date_value; - char *amount, *title; - const char *currency; GNCAccountType account_type; GNCPrintAmountFlags flags; + const char *currency; + const char *amount; double dendBalance; + char *title; int result; flags = PRTSYM | PRTSEP; diff --git a/src/register/datecell.h b/src/register/datecell.h index f80e938a6f..74cb0dfad6 100644 --- a/src/register/datecell.h +++ b/src/register/datecell.h @@ -95,7 +95,7 @@ #include #include "basiccell.h" -#include "Transaction.h" /* This is where Timespec is declared. Why? */ +#include "date.h" typedef struct _DateCell {