GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Enumerations | Functions | Variables
gnc-csv-model.h File Reference

CSV import GUI. More...

#include "config.h"
#include "Account.h"
#include "Transaction.h"
#include "stf/stf-parse.h"

Go to the source code of this file.

Data Structures

struct  GncCsvStr
 
struct  GncCsvTransLine
 
struct  GncCsvParseData
 

Enumerations

enum  GncCsvColumnType {
  GNC_CSV_NONE, GNC_CSV_DATE, GNC_CSV_NUM, GNC_CSV_DESCRIPTION,
  GNC_CSV_NOTES, GNC_CSV_ACCOUNT, GNC_CSV_DEPOSIT, GNC_CSV_WITHDRAWAL,
  GNC_CSV_BALANCE, GNC_CSV_NUM_COL_TYPES
}
 
enum  GncCsvErrorType { GNC_CSV_FILE_OPEN_ERR, GNC_CSV_ENCODING_ERR }
 

Functions

GncCsvParseDatagnc_csv_new_parse_data (void)
 
void gnc_csv_parse_data_free (GncCsvParseData *parse_data)
 
int gnc_csv_load_file (GncCsvParseData *parse_data, const char *filename, GError **error)
 
int gnc_csv_convert_encoding (GncCsvParseData *parse_data, const char *encoding, GError **error)
 
int gnc_csv_parse (GncCsvParseData *parse_data, gboolean guessColTypes, GError **error)
 
int gnc_csv_parse_to_trans (GncCsvParseData *parse_data, Account *account, gboolean redo_errors)
 
time64 parse_date (const char *date_str, int format)
 

Variables

const int num_currency_formats
 
const gchar * currency_format_user []
 
const int num_date_formats
 
const gchar * date_format_user []
 
gchar * gnc_csv_column_type_strs []
 

Detailed Description

CSV import GUI.

gnc-csv-model.h

Author
Copyright (c) 2007 Benny Sperisen lasin.nosp@m.di@g.nosp@m.mail..nosp@m.com

Definition in file gnc-csv-model.h.

Enumeration Type Documentation

Enumeration for column types. These are the different types of columns that can exist in a CSV/Fixed-Width file. There should be no two columns with the same type except for the GNC_CSV_NONE type.

Definition at line 41 of file gnc-csv-model.h.

41  {GNC_CSV_NONE,
42  GNC_CSV_DATE,
43  GNC_CSV_NUM,
44  GNC_CSV_DESCRIPTION,
45  GNC_CSV_NOTES,
46  GNC_CSV_ACCOUNT,
47  GNC_CSV_DEPOSIT,
48  GNC_CSV_WITHDRAWAL,
49  GNC_CSV_BALANCE,
50  GNC_CSV_NUM_COL_TYPES
51  };

Enumeration for error types. These are the different types of errors that various functions used for the CSV/Fixed-Width importer can have.

Definition at line 56 of file gnc-csv-model.h.

56  {GNC_CSV_FILE_OPEN_ERR,
57  GNC_CSV_ENCODING_ERR
58  };

Function Documentation

int gnc_csv_convert_encoding ( GncCsvParseData parse_data,
const char *  encoding,
GError **  error 
)

Converts raw file data using a new encoding. This function must be called after gnc_csv_load_file only if gnc_csv_load_file guessed the wrong encoding.

Parameters
parse_dataData that is being parsed
encodingEncoding that data should be translated using
errorWill point to an error on failure
Returns
0 on success, 1 on failure

Definition at line 403 of file gnc-csv-model.c.

405 {
406  gsize bytes_read, bytes_written;
407 
408  /* If parse_data->file_str has already been initialized it must be
409  * freed first. (This should always be the case, since
410  * gnc_csv_load_file should always be called before this
411  * function.) */
412  if (parse_data->file_str.begin != NULL)
413  g_free(parse_data->file_str.begin);
414 
415  /* Do the actual translation to UTF-8. */
416  parse_data->file_str.begin = g_convert (parse_data->raw_str.begin,
417  parse_data->raw_str.end - parse_data->raw_str.begin,
418  "UTF-8", encoding, &bytes_read, &bytes_written,
419  error);
420  /* Handle errors that occur. */
421  if (parse_data->file_str.begin == NULL)
422  return 1;
423 
424  /* On success, save the ending pointer of the translated data and
425  * the encoding type and return 0. */
426  parse_data->file_str.end = parse_data->file_str.begin + bytes_written;
427  parse_data->encoding = (gchar*)encoding;
428  return 0;
429 }
GncCsvStr file_str
GncCsvStr raw_str
int gnc_csv_load_file ( GncCsvParseData parse_data,
const char *  filename,
GError **  error 
)

Loads a file into a GncCsvParseData. This is the first function that must be called after createing a new GncCsvParseData. If this fails because the file couldn't be opened, no more functions can be called on the parse data until this succeeds (or until it fails because of an encoding guess error). If it fails because the encoding could not be guessed, gnc_csv_convert_encoding must be called until it succeeds.

Parameters
parse_dataData that is being parsed
filenameName of the file that should be opened
errorWill contain an error if there is a failure
Returns
0 on success, 1 on failure

Definition at line 443 of file gnc-csv-model.c.

445 {
446  const char* guess_enc = NULL;
447 
448  /* Get the raw data first and handle an error if one occurs. */
449  parse_data->raw_mapping = g_mapped_file_new (filename, FALSE, error);
450  if (parse_data->raw_mapping == NULL)
451  {
452  /* TODO Handle file opening errors more specifically,
453  * e.g. inexistent file versus no read permission. */
454  parse_data->raw_str.begin = NULL;
455  g_clear_error (error);
456  g_set_error (error, 0, GNC_CSV_FILE_OPEN_ERR, "%s", _("File opening failed."));
457  return 1;
458  }
459 
460  /* Copy the mapping's contents into parse-data->raw_str. */
461  parse_data->raw_str.begin = g_mapped_file_get_contents (parse_data->raw_mapping);
462  parse_data->raw_str.end = parse_data->raw_str.begin + g_mapped_file_get_length (parse_data->raw_mapping);
463 
464  /* Make a guess at the encoding of the data. */
465  if (!g_mapped_file_get_length (parse_data->raw_mapping) == 0)
466  guess_enc = go_guess_encoding ((const char*)(parse_data->raw_str.begin),
467  (size_t)(parse_data->raw_str.end - parse_data->raw_str.begin),
468  "UTF-8", NULL);
469  if (guess_enc == NULL)
470  {
471  g_set_error (error, 0, GNC_CSV_ENCODING_ERR, "%s", _("Unknown encoding."));
472  return 1;
473  }
474  /* Convert using the guessed encoding into parse_data->file_str and
475  * handle any errors that occur. */
476  gnc_csv_convert_encoding (parse_data, guess_enc, error);
477  if (parse_data->file_str.begin == NULL)
478  {
479  g_set_error (error, 0, GNC_CSV_ENCODING_ERR, "%s", _("Unknown encoding."));
480  return 1;
481  }
482  else
483  return 0;
484 }
GMappedFile * raw_mapping
int gnc_csv_convert_encoding(GncCsvParseData *parse_data, const char *encoding, GError **error)
GncCsvStr file_str
GncCsvStr raw_str
GncCsvParseData* gnc_csv_new_parse_data ( void  )

Constructor for GncCsvParseData.

Returns
Pointer to a new GncCSvParseData

Definition at line 324 of file gnc-csv-model.c.

325 {
326  GncCsvParseData* parse_data = g_new(GncCsvParseData, 1);
327  parse_data->encoding = "UTF-8";
328  /* All of the data pointers are initially NULL. This is so that, if
329  * gnc_csv_parse_data_free is called before all of the data is
330  * initialized, only the data that needs to be freed is freed. */
331  parse_data->raw_str.begin = parse_data->raw_str.end
332  = parse_data->file_str.begin = parse_data->file_str.end = NULL;
333  parse_data->orig_lines = NULL;
334  parse_data->orig_row_lengths = NULL;
335  parse_data->column_types = NULL;
336  parse_data->error_lines = parse_data->transactions = NULL;
337  parse_data->options = default_parse_options();
338  parse_data->date_format = -1;
339  parse_data->currency_format = 0;
340  parse_data->chunk = g_string_chunk_new(100 * 1024);
341  parse_data->start_row = 0;
342  parse_data->end_row = 1000;
343  parse_data->skip_rows = FALSE;
344  return parse_data;
345 }
GPtrArray * orig_lines
GArray * orig_row_lengths
GncCsvStr file_str
StfParseOptions_t * options
GList * transactions
GStringChunk * chunk
GArray * column_types
gboolean skip_rows
GncCsvStr raw_str
int gnc_csv_parse ( GncCsvParseData parse_data,
gboolean  guessColTypes,
GError **  error 
)

Parses a file into cells. This requires having an encoding that works (see gnc_csv_convert_encoding). parse_data->options should be set according to how the user wants before calling this function. (Note: this function must be called with guessColTypes as TRUE before it is ever called with it as FALSE.) (Note: if guessColTypes is TRUE, all the column types will be GNC_CSV_NONE right now.)

Parameters
parse_dataData that is being parsed
guessColTypesTRUE to guess what the types of columns are based on the cell contents
errorWill contain an error if there is a failure
Returns
0 on success, 1 on failure

Definition at line 498 of file gnc-csv-model.c.

499 {
500  /* max_cols is the number of columns in the row with the most columns. */
501  int i, max_cols = 0;
502 
503  if (parse_data->orig_lines != NULL)
504  {
505  stf_parse_general_free (parse_data->orig_lines);
506  }
507 
508  /* If everything is fine ... */
509  if (parse_data->file_str.begin != NULL)
510  {
511  /* Do the actual parsing. */
512  parse_data->orig_lines = stf_parse_general (parse_data->options, parse_data->chunk,
513  parse_data->file_str.begin,
514  parse_data->file_str.end);
515  }
516  /* If we couldn't get the encoding right, we just want an empty array. */
517  else
518  {
519  parse_data->orig_lines = g_ptr_array_new();
520  }
521 
522  /* Record the original row lengths of parse_data->orig_lines. */
523  if (parse_data->orig_row_lengths != NULL)
524  g_array_free (parse_data->orig_row_lengths, FALSE);
525 
526  parse_data->orig_row_lengths =
527  g_array_sized_new (FALSE, FALSE, sizeof(int), parse_data->orig_lines->len);
528 
529  g_array_set_size (parse_data->orig_row_lengths, parse_data->orig_lines->len);
530  parse_data->orig_max_row = 0;
531  for (i = 0; i < parse_data->orig_lines->len; i++)
532  {
533  int length = ((GPtrArray*)parse_data->orig_lines->pdata[i])->len;
534  parse_data->orig_row_lengths->data[i] = length;
535  if (length > parse_data->orig_max_row)
536  parse_data->orig_max_row = length;
537  }
538 
539  /* If it failed, generate an error. */
540  if (parse_data->orig_lines == NULL)
541  {
542  g_set_error (error, 0, 0, "Parsing failed.");
543  return 1;
544  }
545 
546  /* Now that we have data, let's set max_cols. */
547  for (i = 0; i < parse_data->orig_lines->len; i++)
548  {
549  if (max_cols < ((GPtrArray*)(parse_data->orig_lines->pdata[i]))->len)
550  max_cols = ((GPtrArray*)(parse_data->orig_lines->pdata[i]))->len;
551  }
552 
553  if (guessColTypes)
554  {
555  /* Free parse_data->column_types if it's already been created. */
556  if (parse_data->column_types != NULL)
557  g_array_free (parse_data->column_types, TRUE);
558 
559  /* Create parse_data->column_types and fill it with guesses based
560  * on the contents of each column. */
561  parse_data->column_types = g_array_sized_new (FALSE, FALSE, sizeof(int),
562  max_cols);
563  g_array_set_size (parse_data->column_types, max_cols);
564  /* TODO Make it actually guess. */
565  for (i = 0; i < parse_data->column_types->len; i++)
566  {
567  parse_data->column_types->data[i] = GNC_CSV_NONE;
568  }
569  }
570  else
571  {
572  /* If we don't need to guess column types, we will simply set any
573  * new columns that are created that didn't exist before to "None"
574  * since we don't want gibberish to appear. Note:
575  * parse_data->column_types should have already been
576  * initialized, so we don't check for it being NULL. */
577  int i = parse_data->column_types->len;
578  g_array_set_size (parse_data->column_types, max_cols);
579  for (; i < parse_data->column_types->len; i++)
580  {
581  parse_data->column_types->data[i] = GNC_CSV_NONE;
582  }
583  }
584 
585  return 0;
586 }
GPtrArray * orig_lines
GArray * orig_row_lengths
GncCsvStr file_str
StfParseOptions_t * options
GStringChunk * chunk
GArray * column_types
void gnc_csv_parse_data_free ( GncCsvParseData parse_data)

Destructor for GncCsvParseData.

Parameters
parse_dataParse data whose memory will be freed

Definition at line 350 of file gnc-csv-model.c.

351 {
352  /* All non-NULL pointers have been initialized and must be freed. */
353 
354  if (parse_data->raw_mapping != NULL)
355  {
356  g_mapped_file_unref (parse_data->raw_mapping);
357  }
358 
359  if (parse_data->file_str.begin != NULL)
360  g_free (parse_data->file_str.begin);
361 
362  if (parse_data->orig_lines != NULL)
363  stf_parse_general_free (parse_data->orig_lines);
364 
365  if (parse_data->orig_row_lengths != NULL)
366  g_array_free (parse_data->orig_row_lengths, FALSE);
367 
368  if (parse_data->options != NULL)
369  stf_parse_options_free (parse_data->options);
370 
371  if (parse_data->column_types != NULL)
372  g_array_free (parse_data->column_types, TRUE);
373 
374  if (parse_data->error_lines != NULL)
375  g_list_free (parse_data->error_lines);
376 
377  if (parse_data->transactions != NULL)
378  {
379  GList* transactions = parse_data->transactions;
380  /* We have to free the GncCsvTransLine's that are at each node in
381  * the list before freeing the entire list. */
382  do
383  {
384  g_free (transactions->data);
385  transactions = g_list_next (transactions);
386  }
387  while (transactions != NULL);
388  g_list_free (parse_data->transactions);
389  }
390 
391  g_free (parse_data->chunk);
392  g_free (parse_data);
393 }
GMappedFile * raw_mapping
GPtrArray * orig_lines
GArray * orig_row_lengths
GncCsvStr file_str
StfParseOptions_t * options
GList * transactions
GStringChunk * chunk
GArray * column_types
int gnc_csv_parse_to_trans ( GncCsvParseData parse_data,
Account account,
gboolean  redo_errors 
)

Creates a list of transactions from parsed data. Transactions that could be created from rows are placed in parse_data->transactions; rows that fail are placed in parse_data->error_lines. (Note: there is no way for this function to "fail," i.e. it only returns 0, so it may be changed to a void function in the future.)

Parameters
parse_dataData that is being parsed
accountAccount with which transactions are created
redo_errorsTRUE to convert only error data, FALSE for all data
Returns
0 on success, 1 on failure

Definition at line 1015 of file gnc-csv-model.c.

1017 {
1018  gboolean hasBalanceColumn;
1019  int i, j, max_cols = 0;
1020  GArray* column_types = parse_data->column_types;
1021  GList *error_lines = NULL, *begin_error_lines = NULL;
1022 
1023  /* last_transaction points to the last element in
1024  * parse_data->transactions, or NULL if it's empty. */
1025  GList* last_transaction = NULL;
1026 
1027  /* Free parse_data->error_lines and parse_data->transactions if they
1028  * already exist. */
1029  if (redo_errors) /* If we're redoing errors, we save freeing until the end. */
1030  {
1031  begin_error_lines = error_lines = parse_data->error_lines;
1032  }
1033  else
1034  {
1035  if (parse_data->error_lines != NULL)
1036  {
1037  g_list_free(parse_data->error_lines);
1038  }
1039  if (parse_data->transactions != NULL)
1040  {
1041  g_list_free (parse_data->transactions);
1042  }
1043  }
1044  parse_data->error_lines = NULL;
1045 
1046  if (redo_errors) /* If we're looking only at error data ... */
1047  {
1048  if (parse_data->transactions == NULL)
1049  {
1050  last_transaction = NULL;
1051  }
1052  else
1053  {
1054  /* Move last_transaction to the end. */
1055  last_transaction = parse_data->transactions;
1056  while (g_list_next (last_transaction) != NULL)
1057  {
1058  last_transaction = g_list_next (last_transaction);
1059  }
1060  }
1061  /* ... we use only the lines in error_lines. */
1062  if (error_lines == NULL)
1063  i = parse_data->orig_lines->len; /* Don't go into the for loop. */
1064  else
1065  i = GPOINTER_TO_INT(error_lines->data);
1066  }
1067  else /* Otherwise, we look at all the data. */
1068  {
1069  /* The following while-loop effectively behaves like the following for-loop:
1070  * for(i = 0; i < parse_data->orig_lines->len; i++). */
1071  i = parse_data->start_row;
1072  last_transaction = NULL;
1073  }
1074 
1075  /* set parse_data->end_row to number of lines */
1076  if (parse_data->end_row > parse_data->orig_lines->len)
1077  parse_data->end_row = parse_data->orig_lines->len;
1078 
1079  while (i < parse_data->end_row)
1080  {
1081  GPtrArray* line = parse_data->orig_lines->pdata[i];
1082  /* This flag is TRUE if there are any errors in this row. */
1083  gboolean errors = FALSE;
1084  gchar* error_message = NULL;
1085  TransPropertyList* list = trans_property_list_new (account, parse_data->date_format, parse_data->currency_format);
1086  GncCsvTransLine* trans_line = NULL;
1087 
1088  for (j = 0; j < line->len; j++)
1089  {
1090  /* We do nothing in "None" or "Account" columns. */
1091  if ((column_types->data[j] != GNC_CSV_NONE) && (column_types->data[j] != GNC_CSV_ACCOUNT))
1092  {
1093  /* Affect the transaction appropriately. */
1094  TransProperty* property = trans_property_new (column_types->data[j], list);
1095  gboolean succeeded = trans_property_set (property, line->pdata[j]);
1096 
1097  /* TODO Maybe move error handling to within TransPropertyList functions? */
1098  if (succeeded)
1099  {
1100  trans_property_list_add (property);
1101  }
1102  else
1103  {
1104  errors = TRUE;
1105  error_message = g_strdup_printf (_("%s column could not be understood."),
1106  _(gnc_csv_column_type_strs[property->type]));
1107  trans_property_free (property);
1108  break;
1109  }
1110  }
1111  }
1112 
1113  /* If we had success, add the transaction to parse_data->transaction. */
1114  if (!errors)
1115  {
1116  trans_line = trans_property_list_to_trans (list, &error_message);
1117  errors = trans_line == NULL;
1118  }
1119 
1120  trans_property_list_free (list);
1121 
1122  /* If there were errors, add this line to parse_data->error_lines. */
1123  if (errors)
1124  {
1125  parse_data->error_lines = g_list_append (parse_data->error_lines,
1126  GINT_TO_POINTER(i));
1127  /* If there's already an error message, we need to replace it. */
1128  if (line->len > (int)(parse_data->orig_row_lengths->data[i]))
1129  {
1130  g_free(line->pdata[line->len - 1]);
1131  line->pdata[line->len - 1] = error_message;
1132  }
1133  else
1134  {
1135  /* Put the error message at the end of the line. */
1136  g_ptr_array_add (line, error_message);
1137  }
1138  }
1139  else
1140  {
1141  /* If all went well, add this transaction to the list. */
1142  trans_line->line_no = i;
1143 
1144  /* We keep the transactions sorted by date. We start at the end
1145  * of the list and go backward, simply because the file itself
1146  * is probably also sorted by date (but we need to handle the
1147  * exception anyway). */
1148 
1149  /* If we can just put it at the end, do so and increment last_transaction. */
1150  if (last_transaction == NULL ||
1151  xaccTransGetDate (((GncCsvTransLine*)(last_transaction->data))->trans) <= xaccTransGetDate (trans_line->trans))
1152  {
1153  parse_data->transactions = g_list_append (parse_data->transactions, trans_line);
1154  /* If this is the first transaction, we need to get last_transaction on track. */
1155  if (last_transaction == NULL)
1156  last_transaction = parse_data->transactions;
1157  else /* Otherwise, we can just continue. */
1158  last_transaction = g_list_next (last_transaction);
1159  }
1160  /* Otherwise, search backward for the correct spot. */
1161  else
1162  {
1163  GList* insertion_spot = last_transaction;
1164  while (insertion_spot != NULL &&
1165  xaccTransGetDate (((GncCsvTransLine*)(insertion_spot->data))->trans) > xaccTransGetDate (trans_line->trans))
1166  {
1167  insertion_spot = g_list_previous (insertion_spot);
1168  }
1169  /* Move insertion_spot one location forward since we have to
1170  * use the g_list_insert_before function. */
1171  if (insertion_spot == NULL) /* We need to handle the case of inserting at the beginning of the list. */
1172  insertion_spot = parse_data->transactions;
1173  else
1174  insertion_spot = g_list_next (insertion_spot);
1175 
1176  parse_data->transactions = g_list_insert_before (parse_data->transactions, insertion_spot, trans_line);
1177  }
1178  }
1179 
1180  /* Increment to the next row. */
1181  if (redo_errors)
1182  {
1183  /* Move to the next error line in the list. */
1184  error_lines = g_list_next (error_lines);
1185  if (error_lines == NULL)
1186  i = parse_data->orig_lines->len; /* Don't continue the for loop. */
1187  else
1188  i = GPOINTER_TO_INT(error_lines->data);
1189  }
1190  else
1191  {
1192  if (parse_data->skip_rows == FALSE)
1193  i++;
1194  else
1195  i = i + 2;
1196  }
1197  }
1198 
1199  /* If we have a balance column, set the appropriate amounts on the transactions. */
1200  hasBalanceColumn = FALSE;
1201  for (i = 0; i < parse_data->column_types->len; i++)
1202  {
1203  if (parse_data->column_types->data[i] == GNC_CSV_BALANCE)
1204  {
1205  hasBalanceColumn = TRUE;
1206  break;
1207  }
1208  }
1209 
1210  if (hasBalanceColumn)
1211  {
1212  GList* transactions = parse_data->transactions;
1213 
1214  /* balance_offset is how much the balance currently in the account
1215  * differs from what it will be after the transactions are
1216  * imported. This will be sum of all the previous transactions for
1217  * any given transaction. */
1218  gnc_numeric balance_offset = double_to_gnc_numeric (0.0,
1219  xaccAccountGetCommoditySCU (account),
1221  while (transactions != NULL)
1222  {
1223  GncCsvTransLine* trans_line = (GncCsvTransLine*)transactions->data;
1224  if (trans_line->balance_set)
1225  {
1226  time64 date = xaccTransGetDate (trans_line->trans);
1227  /* Find what the balance should be by adding the offset to the actual balance. */
1228  gnc_numeric existing_balance = gnc_numeric_add (balance_offset,
1229  xaccAccountGetBalanceAsOfDate (account, date),
1230  xaccAccountGetCommoditySCU (account),
1232 
1233  /* The amount of the transaction is the difference between the new and existing balance. */
1234  gnc_numeric amount = gnc_numeric_sub (trans_line->balance,
1235  existing_balance,
1236  xaccAccountGetCommoditySCU (account),
1238 
1239  SplitList* splits = xaccTransGetSplitList (trans_line->trans);
1240  while (splits)
1241  {
1242  SplitList* next_splits = g_list_next (splits);
1243  xaccSplitDestroy ((Split*)splits->data);
1244  splits = next_splits;
1245  }
1246 
1247  trans_add_split (trans_line->trans, account,
1248  gnc_account_get_book (account), amount, trans_line->num);
1249  if (trans_line->num)
1250  g_free (trans_line->num);
1251 
1252  /* This new transaction needs to be added to the balance offset. */
1253  balance_offset = gnc_numeric_add (balance_offset,
1254  amount,
1255  xaccAccountGetCommoditySCU (account),
1257  }
1258  transactions = g_list_next (transactions);
1259  }
1260  }
1261 
1262  if (redo_errors) /* Now that we're at the end, we do the freeing. */
1263  {
1264  g_list_free (begin_error_lines);
1265  }
1266 
1267  /* We need to resize parse_data->column_types since errors may have added columns. */
1268  for (i = 0; i < parse_data->orig_lines->len; i++)
1269  {
1270  if (max_cols < ((GPtrArray*)(parse_data->orig_lines->pdata[i]))->len)
1271  max_cols = ((GPtrArray*)(parse_data->orig_lines->pdata[i]))->len;
1272  }
1273  i = parse_data->column_types->len;
1274  parse_data->column_types = g_array_set_size (parse_data->column_types, max_cols);
1275  for (; i < max_cols; i++)
1276  {
1277  parse_data->column_types->data[i] = GNC_CSV_NONE;
1278  }
1279 
1280  return 0;
1281 }
gnc_numeric balance
Definition: gnc-csv-model.h:83
time64 xaccTransGetDate(const Transaction *trans)
Definition: Transaction.c:2215
GPtrArray * orig_lines
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
gboolean xaccSplitDestroy(Split *split)
Definition: Split.c:1492
int xaccAccountGetCommoditySCU(const Account *acc)
Definition: Account.c:2458
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
GArray * orig_row_lengths
gboolean balance_set
Definition: gnc-csv-model.h:84
GList SplitList
Definition: gnc-engine.h:203
gnc_numeric xaccAccountGetBalanceAsOfDate(Account *acc, time64 date)
Definition: Account.c:3288
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
GList * transactions
Definition: SplitP.h:71
gint64 time64
Definition: gnc-date.h:83
GArray * column_types
gboolean skip_rows
SplitList * xaccTransGetSplitList(const Transaction *trans)
Definition: Transaction.c:2164
time64 parse_date ( const char *  date_str,
int  format 
)

Parses a string into a date, given a format. This function requires only knowing the order in which the year, month and day appear. For example, 01-02-2003 will be parsed the same way as 01/02/2003.

Parameters
date_strThe string containing a date being parsed
formatAn index specifying a format in date_format_user
Returns
The parsed value of date_str on success or -1 on failure

Definition at line 313 of file gnc-csv-model.c.

314 {
315  if (strchr (date_format_user[format], 'y'))
316  return parse_date_with_year (date_str, format);
317  else
318  return parse_date_without_year (date_str, format);
319 }