gnucash/libgnucash/backend/xml/io-example-account.cpp
Geert Janssens 1238b9d8cd Prevent gcc from searching config.h in the current directory
This will avoid a ninja-build from picking up a config.h generated by the autotools build
(in the root build directory). Picking up the wrong config.h may lead to all kinds of
subtle issues if the autotools run was done with different options than the cmake run.
2017-10-26 14:05:17 +02:00

515 lines
13 KiB
C++

/********************************************************************\
* io-example-account.c -- implementation for example accounts *
* *
* Copyright (C) 2001 James LewisMoss <dres@debian.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
* *
\********************************************************************/
extern "C"
{
#include <config.h>
#include <platform.h>
#if PLATFORM(WINDOWS)
#include <windows.h>
#endif
#include <sys/types.h>
#include <ctype.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
#include <string.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include "gnc-engine.h"
#include "Scrub.h"
#include "TransLog.h"
#include "platform.h"
#if COMPILER(MSVC)
# define g_fopen fopen
#endif
}
#include "sixtp.h"
#include "gnc-xml.h"
#include "io-example-account.h"
#include "io-gncxml-gen.h"
#include "io-utils.h"
#include "sixtp-dom-generators.h"
#include "sixtp-dom-parsers.h"
#include "sixtp-parsers.h"
static QofLogModule log_module = GNC_MOD_IO;
#define GNC_ACCOUNT_STRING "gnc-account-example"
#define GNC_ACCOUNT_SHORT "gnc-act:short-description"
#define GNC_ACCOUNT_LONG "gnc-act:long-description"
#define GNC_ACCOUNT_TITLE "gnc-act:title"
#define GNC_ACCOUNT_EXCLUDEP "gnc-act:exclude-from-select-all"
#define GNC_ACCOUNT_SELECTED "gnc-act:start-selected"
void
gnc_destroy_example_account (GncExampleAccount* gea)
{
if (gea->title != NULL)
{
g_free (gea->title);
gea->title = NULL;
}
if (gea->filename != NULL)
{
g_free (gea->filename);
gea->filename = NULL;
}
if (gea->root != NULL)
{
xaccAccountBeginEdit (gea->root);
xaccAccountDestroy (gea->root);
gea->root = NULL;
}
if (gea->short_description != NULL)
{
g_free (gea->short_description);
gea->short_description = NULL;
}
if (gea->long_description != NULL)
{
g_free (gea->long_description);
gea->long_description = NULL;
}
if (gea->book != NULL)
{
qof_book_destroy (gea->book);
gea->book = NULL;
}
g_free (gea);
}
static void
clear_up_account_commodity (
gnc_commodity_table* tbl, Account* act,
gnc_commodity * (*getter) (const Account* account),
void (*setter) (Account* account, gnc_commodity* comm))
{
gnc_commodity* gcom;
gnc_commodity* com = getter (act);
if (!com)
{
return;
}
g_return_if_fail (tbl != NULL);
gcom = gnc_commodity_table_lookup (tbl,
gnc_commodity_get_namespace (com),
gnc_commodity_get_mnemonic (com));
if (gcom == com)
{
return;
}
else if (!gcom)
{
PWARN ("unable to find global commodity for %s adding new",
gnc_commodity_get_unique_name (com));
gnc_commodity_table_insert (tbl, com);
}
else
{
setter (act, gcom);
gnc_commodity_destroy (com);
}
}
static void
add_account_local (GncExampleAccount* gea, Account* act)
{
gnc_commodity_table* table;
table = gnc_commodity_table_get_table (gea->book);
clear_up_account_commodity (table, act,
xaccAccountGetCommodity,
xaccAccountSetCommodity);
xaccAccountScrubCommodity (act);
if (xaccAccountGetType (act) == ACCT_TYPE_ROOT)
{
gea->root = act;
}
else if (!gnc_account_get_parent (act))
{
if (!gea->root)
{
g_warning ("The example account file should declared a ROOT "
"account before declaring any other accounts.");
gea->root = gnc_book_get_root_account (gea->book);
}
gnc_account_append_child (gea->root, act);
}
}
static gboolean
generic_callback (const char* tag, gpointer globaldata, gpointer data)
{
GncExampleAccount* gea = (GncExampleAccount*)globaldata;
if (g_strcmp0 (tag, "gnc:account") == 0)
{
add_account_local (gea, (Account*)data);
}
return TRUE;
}
static char*
squash_extra_whitespace (char* text)
{
int spot;
int length = strlen (text);
for (spot = 1; spot < length; spot++)
{
if (isspace (text[spot]) && isspace (text[spot - 1]))
{
memmove (text + spot, text + spot + 1, length - spot + 1);
length--;
}
else
{
spot++;
}
}
return text;
}
static char*
grab_clean_string (xmlNodePtr tree)
{
return squash_extra_whitespace (g_strstrip (dom_tree_to_text (tree)));
}
static gboolean
gnc_short_descrip_end_handler (gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
gpointer parent_data, gpointer global_data,
gpointer* result, const gchar* tag)
{
GncExampleAccount* gea =
(GncExampleAccount*) ((gxpf_data*)global_data)->parsedata;
gea->short_description = grab_clean_string ((xmlNodePtr)data_for_children);
return TRUE;
}
static sixtp*
gnc_short_descrip_sixtp_parser_create (void)
{
return sixtp_dom_parser_new (gnc_short_descrip_end_handler, NULL, NULL);
}
static gboolean
gnc_long_descrip_end_handler (gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
gpointer parent_data, gpointer global_data,
gpointer* result, const gchar* tag)
{
GncExampleAccount* gea =
(GncExampleAccount*) ((gxpf_data*)global_data)->parsedata;
gea->long_description = grab_clean_string ((xmlNodePtr)data_for_children);
return TRUE;
}
static sixtp*
gnc_long_descrip_sixtp_parser_create (void)
{
return sixtp_dom_parser_new (gnc_long_descrip_end_handler, NULL, NULL);
}
static gboolean
gnc_excludep_end_handler (gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
gpointer parent_data, gpointer global_data,
gpointer* result, const gchar* tag)
{
GncExampleAccount* gea =
(GncExampleAccount*) ((gxpf_data*)global_data)->parsedata;
gint64 val = 0;
dom_tree_to_integer ((xmlNodePtr)data_for_children, &val);
gea->exclude_from_select_all = (val ? TRUE : FALSE);
return TRUE;
}
static sixtp*
gnc_excludep_sixtp_parser_create (void)
{
return sixtp_dom_parser_new (gnc_excludep_end_handler, NULL, NULL);
}
static gboolean
gnc_selected_end_handler (gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
gpointer parent_data, gpointer global_data,
gpointer* result, const gchar* tag)
{
GncExampleAccount* gea =
(GncExampleAccount*) ((gxpf_data*)global_data)->parsedata;
gint64 val = 0;
dom_tree_to_integer ((xmlNodePtr)data_for_children, &val);
gea->start_selected = (val ? TRUE : FALSE);
return TRUE;
}
static sixtp*
gnc_selected_sixtp_parser_create (void)
{
return sixtp_dom_parser_new (gnc_selected_end_handler, NULL, NULL);
}
static gboolean
gnc_title_end_handler (gpointer data_for_children,
GSList* data_from_children, GSList* sibling_data,
gpointer parent_data, gpointer global_data,
gpointer* result, const gchar* tag)
{
GncExampleAccount* gea =
(GncExampleAccount*) ((gxpf_data*)global_data)->parsedata;
gea->title = grab_clean_string ((xmlNodePtr)data_for_children);
return TRUE;
}
static sixtp*
gnc_titse_sixtp_parser_create (void)
{
return sixtp_dom_parser_new (gnc_title_end_handler, NULL, NULL);
}
GncExampleAccount*
gnc_read_example_account (const gchar* filename)
{
GncExampleAccount* gea;
sixtp* top_parser;
sixtp* main_parser;
g_return_val_if_fail (filename != NULL, NULL);
gea = g_new0 (GncExampleAccount, 1);
gea->book = qof_book_new ();
gea->filename = g_strdup (filename);
top_parser = sixtp_new ();
main_parser = sixtp_new ();
if (!sixtp_add_some_sub_parsers (
top_parser, TRUE,
GNC_ACCOUNT_STRING, main_parser,
NULL, NULL))
{
gnc_destroy_example_account (gea);
return FALSE;
}
if (!sixtp_add_some_sub_parsers (
main_parser, TRUE,
GNC_ACCOUNT_TITLE, gnc_titse_sixtp_parser_create (),
GNC_ACCOUNT_SHORT, gnc_short_descrip_sixtp_parser_create (),
GNC_ACCOUNT_LONG, gnc_long_descrip_sixtp_parser_create (),
GNC_ACCOUNT_EXCLUDEP, gnc_excludep_sixtp_parser_create (),
GNC_ACCOUNT_SELECTED, gnc_selected_sixtp_parser_create (),
"gnc:account", gnc_account_sixtp_parser_create (),
NULL, NULL))
{
gnc_destroy_example_account (gea);
return FALSE;
}
if (!gnc_xml_parse_file (top_parser, filename,
generic_callback, gea, gea->book))
{
sixtp_destroy (top_parser);
xaccLogEnable ();
gnc_destroy_example_account (gea);
return FALSE;
}
return gea;
}
static void
write_string_part (FILE* out, const char* tag, const char* data)
{
xmlNodePtr node;
node = text_to_dom_tree (tag, data);
xmlElemDump (out, NULL, node);
fprintf (out, "\n");
xmlFreeNode (node);
}
static void
write_bool_part (FILE* out, const char* tag, gboolean data)
{
xmlNodePtr node;
node = int_to_dom_tree (tag, data);
xmlElemDump (out, NULL, node);
fprintf (out, "\n");
xmlFreeNode (node);
}
gboolean
gnc_write_example_account (GncExampleAccount* gea, const gchar* filename)
{
FILE* out;
sixtp_gdv2 data = { 0 };;
out = g_fopen (filename, "w");
if (out == NULL)
{
return FALSE;
}
fprintf (out, "<?xml version=\"1.0\"?>\n");
fprintf (out, "<" GNC_ACCOUNT_STRING ">\n");
write_string_part (out, GNC_ACCOUNT_TITLE, gea->title);
write_string_part (out, GNC_ACCOUNT_SHORT, gea->short_description);
write_string_part (out, GNC_ACCOUNT_LONG, gea->long_description);
write_bool_part (out, GNC_ACCOUNT_EXCLUDEP, gea->exclude_from_select_all);
write_account_tree (out, gea->root, &data);
fprintf (out, "</" GNC_ACCOUNT_STRING ">\n\n");
write_emacs_trailer (out);
fclose (out);
return TRUE;
}
/***********************************************************************/
static void
slist_destroy_example_account (gpointer data, gpointer user_data)
{
if (data != NULL)
{
gnc_destroy_example_account ((GncExampleAccount*)data);
}
else
{
PWARN ("GncExampleAccount pointer in slist was NULL");
}
}
void
gnc_free_example_account_list (GSList* list)
{
g_slist_foreach (list, slist_destroy_example_account, NULL);
g_slist_free (list);
}
GSList*
gnc_load_example_account_list (const char* dirname)
{
GSList* ret;
GDir* dir;
const gchar* direntry;
dir = g_dir_open (dirname, 0, NULL);
if (dir == NULL)
{
return NULL;
}
ret = NULL;
for (direntry = g_dir_read_name (dir); direntry != NULL;
direntry = g_dir_read_name (dir))
{
gchar* filename;
GncExampleAccount* gea;
if (!g_str_has_suffix (direntry, "xea"))
continue;
filename = g_build_filename (dirname, direntry, (gchar*) NULL);
if (!g_file_test (filename, G_FILE_TEST_IS_DIR))
{
gea = gnc_read_example_account (filename);
if (gea == NULL)
{
g_free (filename);
gnc_free_example_account_list (ret);
g_dir_close (dir);
return NULL;
}
ret = g_slist_append (ret, gea);
}
g_free (filename);
}
g_dir_close (dir);
return ret;
}
/***********************************************************************/
/*
gboolean
gnc_is_example_account_xml(const gchar *name)
{
return gnc_is_our_xml_file(name, GNC_ACCOUNT_STRING, NULL);
} */