35 #include "qif-import-p.h"
36 #include "qif-objects-p.h"
37 #include "qif-defaults.h"
44 #define qif_object_new(t,typ,dest) ({ \
45 obj = (QifObject) g_new0(t, 1); \
47 obj->destroy = dest; \
55 #define qif_save_str(var) { \
57 PERR("duplicate found at line %d: %s", line->lineno, line->line); \
72 g_free(acct->limitstr);
73 g_free(acct->budgetstr);
84 obj = qif_object_new(
struct _QifAccount, QIF_O_ACCOUNT, qif_account_destroy);
87 acct->type_list = qif_parse_acct_type(
"bank", -1);
89 acct->limit = gnc_numeric_zero();
90 acct->budget = gnc_numeric_zero();
104 (
QifAccount)qif_object_map_lookup(ctx, acct->obj.type, acct->name);
108 qif_object_map_insert(ctx, acct->obj.type, (
QifObject)acct);
114 if (!acct2->desc && acct->desc)
115 acct2->desc = g_strdup(acct->desc);
117 if (!acct2->type_list && acct->type_list)
118 acct2->type_list = acct->type_list;
120 if (!acct2->limitstr && acct->limitstr)
122 acct2->limitstr = g_strdup(acct->limitstr);
123 acct2->limit = acct->limit;
126 if (!acct2->budgetstr && acct->budgetstr)
128 acct2->budgetstr = g_strdup(acct->budgetstr);
129 acct2->budget = acct->budget;
136 qif_account_parse(
QifContext ctx, GList *record)
141 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
142 g_return_val_if_fail(record, QIF_E_BADSTATE);
144 acct = qif_account_new();
146 for (; record; record = record->next)
153 qif_save_str(acct->name);
156 qif_save_str(acct->desc);
159 acct->type_list = qif_parse_acct_type(line->line, line->lineno);
162 qif_save_str(acct->limitstr);
165 qif_save_str(acct->budgetstr);
168 PERR(
"Unknown QIF account data at line %d: %s", line->lineno, line->line);
173 temp = qif_account_merge(ctx, acct);
174 if (! (ctx->parse_flags & QIF_F_IGNORE_ACCOUNTS))
175 ctx->current_acct = temp;
190 g_free(cat->taxclass);
191 g_free(cat->budgetstr);
202 obj = qif_object_new(
struct _QifCategory, QIF_O_CATEGORY, qif_cat_destroy);
204 cat->budget = gnc_numeric_zero();
219 (
QifCategory)qif_object_map_lookup(ctx, cat->obj.type, cat->name);
223 qif_object_map_insert(ctx, cat->obj.type, (
QifObject)cat);
229 if (!cat2->desc && cat->desc)
230 cat2->desc = g_strdup(cat->desc);
232 if (!cat2->taxclass && cat->taxclass)
233 cat2->taxclass = g_strdup(cat->taxclass);
235 cat2->taxable = (cat2->taxable || cat->taxable);
236 cat2->expense = (cat2->expense || cat->expense);
237 cat2->income = (cat2->income || cat->income);
239 if (!cat2->budgetstr && cat->budgetstr)
241 cat2->budgetstr = g_strdup(cat->budgetstr);
242 cat2->budget = cat->budget;
254 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
255 g_return_val_if_fail(record, QIF_E_BADSTATE);
259 for (; record; record = record->next)
266 qif_save_str(cat->name);
269 qif_save_str(cat->desc);
282 qif_save_str(cat->taxclass);
285 qif_save_str(cat->budgetstr);
288 PERR(
"Unknown QIF category data at line %d: %s", line->lineno, line->line);
292 if (qif_cat_merge(ctx, cat) != cat)
304 g_free(qclass->name);
305 g_free(qclass->desc);
306 g_free(qclass->taxdesig);
316 obj = qif_object_new(
struct _QifClass, QIF_O_CLASS, qif_class_destroy);
330 (
QifClass)qif_object_map_lookup(ctx, qclass->obj.type, qclass->name);
334 qif_object_map_insert(ctx, qclass->obj.type, (
QifObject)qclass);
340 if (!qclass2->desc && qclass->desc)
341 qclass2->desc = g_strdup(qclass->desc);
343 if (!qclass2->taxdesig && qclass->taxdesig)
344 qclass2->taxdesig = g_strdup(qclass->taxdesig);
350 qif_class_parse(
QifContext ctx, GList *record)
355 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
356 g_return_val_if_fail(record, QIF_E_BADSTATE);
358 qclass = qif_class_new();
360 for (; record; record = record->next)
367 qif_save_str(qclass->name);
370 qif_save_str(qclass->desc);
373 qif_save_str(qclass->taxdesig);
376 PERR(
"Unknown QIF class data at line %d: %s", line->lineno, line->line);
380 if (qif_class_merge(ctx, qclass) != qclass)
392 g_free(security->name);
393 g_free(security->symbol);
394 g_free(security->type);
404 obj = qif_object_new(
struct _QifSecurity, QIF_O_SECURITY, qif_security_destroy);
418 (
QifSecurity)qif_object_map_lookup(ctx, security->obj.type, security->name);
422 qif_object_map_insert(ctx, security->obj.type, (
QifObject)security);
428 if (!security2->symbol && security->symbol)
429 security2->symbol = g_strdup(security->symbol);
431 if (!security2->type && security->type)
432 security2->type = g_strdup(security->type);
438 qif_security_parse(
QifContext ctx, GList *record)
443 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
444 g_return_val_if_fail(record, QIF_E_BADSTATE);
446 security = qif_security_new();
448 for (; record; record = record->next)
455 qif_save_str(security->name);
458 qif_save_str(security->symbol);
461 qif_save_str(security->type);
464 PERR(
"Unknown QIF security data at line %d: %s", line->lineno, line->line);
468 if (qif_security_merge(ctx, security) != security)
469 qif_security_destroy((
QifObject)security);
482 split->amount = gnc_numeric_zero();
483 split->value = gnc_numeric_zero();
494 g_free(split->catstr);
495 g_free(split->amountstr);
505 memcpy(s, split,
sizeof(*s));
506 if (s->memo) s->memo = g_strdup(s->memo);
507 if (s->amountstr) s->amountstr = g_strdup(s->amountstr);
508 if (s->catstr) s->memo = g_strdup(s->catstr);
522 char *cat_class = NULL;
523 char *miscx_cat = NULL;
524 char *miscx_class = NULL;
526 gboolean miscx_is_acct;
528 static GList *types = NULL;
530 g_return_if_fail(ctx);
531 g_return_if_fail(split);
532 g_return_if_fail(split->cat.cat == NULL && split->cat_class == NULL);
534 if (qif_parse_split_category(split->catstr,
535 &cat, &split->cat_is_acct, &cat_class,
536 &miscx_cat, &miscx_is_acct, &miscx_class))
540 if (split->cat_is_acct)
543 types = qif_parse_acct_type(
"__any_bank__", -1);
545 split->cat.acct = find_or_make_acct(ctx, cat, types);
549 split->cat.cat = find_or_make_cat(ctx, cat);
552 split->cat_class = find_or_make_class(ctx, cat_class);
562 PERR(
"Problem parsing split category: %s", split->catstr);
572 g_free(txn->datestr);
574 g_free(txn->address);
578 qif_txn_invst_destroy(txn->invst_info);
580 for (node = txn->splits; node; node = node->next)
583 if (split == txn->default_split)
584 txn->default_split = NULL;
585 if (split == txn->current_split)
586 txn->current_split = NULL;
588 qif_split_destroy(split);
591 g_list_free(txn->splits);
592 qif_split_destroy(txn->default_split);
593 qif_split_destroy(txn->current_split);
604 obj = qif_object_new(
struct _QifTxn,
"qif-txn", qif_txn_destroy);
606 txn->default_split = qif_split_new();
614 qif_clear_flag(ctx->parse_flags, QIF_F_IGNORE_ACCOUNTS);
615 ctx->parse_state = NULL;
619 qif_is_bad_numeric_string(
const char* line)
621 return (strncmp(line,
"...", 3) == 0);
647 QifSplit split = txn->default_split;
650 g_return_if_fail(txn->invst_info == NULL);
652 if ((!cur_acct && txn->payee &&
653 (!strcasecmp(txn->payee,
"Opening Balance") ||
654 !strcasecmp(txn->payee,
"Initial Balance")) && split->cat_is_acct) ||
656 ((split->cat_is_acct && !strcasecmp(split->cat.acct->name, cur_acct->name))
658 (!split->cat_is_acct && !strcasecmp(split->cat.cat->name, cur_acct->name))))
666 if (split->cat_is_acct)
667 cur_acct = split->cat.acct;
670 g_assert(split->cat.cat);
671 cur_acct = find_or_make_acct(ctx, g_strdup(split->cat.cat->name),
672 qif_parse_acct_type_guess(txn->txn_type));
673 split->cat_is_acct = TRUE;
675 split->cat.acct = qif_default_equity_acct(ctx);
686 ctx->opening_bal_acct = cur_acct;
687 ctx->current_acct = cur_acct;
690 qif_set_flag(ctx->parse_flags, QIF_F_TXN_NEEDS_ACCT);
706 g_return_if_fail(txn);
709 if (!txn->current_split)
return;
712 for (node = txn->splits; node; node = node->next)
720 for (node = txn->splits; node; node = node->next)
735 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
736 g_return_val_if_fail(record, QIF_E_BADSTATE);
739 txn->txn_type = ctx->parse_type;
741 for (; record; record = record->next)
748 qif_save_str(txn->datestr);
751 qif_save_str(txn->payee);
757 char *tmp = txn->address;
758 txn->address = g_strconcat(tmp,
"\n", line->line, NULL);
762 qif_save_str(txn->address);
765 qif_save_str(txn->num);
768 txn->cleared = qif_parse_cleared(line);
771 if (!txn->current_split) qif_save_str(txn->default_split->catstr);
774 if (!txn->current_split) qif_save_str(txn->default_split->memo);
777 if (!txn->current_split && !qif_is_bad_numeric_string(line->line))
778 qif_save_str(txn->default_split->amountstr);
784 txn->current_split = qif_split_new();
785 txn->splits = g_list_prepend(txn->splits, txn->current_split);
786 qif_save_str(txn->current_split->catstr);
789 if (txn->current_split)
790 qif_save_str(txn->current_split->memo);
793 if (txn->current_split && !qif_is_bad_numeric_string(line->line))
794 qif_save_str(txn->current_split->amountstr);
797 PERR(
"Unknown QIF transaction data at line %d: %s", line->lineno, line->line);
807 for (node = txn->splits; node; node = node->next)
811 qif_split_parse_category(ctx, split);
814 if (txn->default_split->catstr)
815 qif_split_parse_category(ctx, txn->default_split);
818 if (!ctx->current_acct)
819 qif_process_opening_balance_txn(ctx, txn);
822 txn->from_acct = ctx->current_acct;
825 ctx->parse_state = g_list_prepend(ctx->parse_state, txn);
837 qif_txn_setup_splits(
QifTxn txn)
846 qif_txn_fix_amounts(txn, txn->default_split->amount);
849 total = gnc_numeric_zero();
850 for (node = txn->splits; node; node = node->next)
853 split->value = split->amount;
868 split = txn->default_split;
869 this_split = qif_split_copy(split);
870 txn->default_split = this_split;
874 split->value = split->amount;
875 txn->splits = g_list_prepend(txn->splits, split);
879 txn->default_split->value = txn->default_split->amount;
890 gboolean txn_needs_acct;
892 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
895 if (!ctx->parse_state)
return QIF_E_OK;
901 txn_needs_acct = (ctx->parse_flags & QIF_F_TXN_NEEDS_ACCT);
904 ctx->parse_state = g_list_reverse(ctx->parse_state);
906 for (node = ctx->parse_state; node; node = node->next)
911 if (txn_needs_acct && ctx->opening_bal_acct && !txn->from_acct)
912 txn->from_acct = ctx->opening_bal_acct;
915 qif_object_list_insert(ctx, (
QifObject)txn);
918 if (txn_needs_acct && ctx->opening_bal_acct)
919 qif_clear_flag(ctx->parse_flags, QIF_F_TXN_NEEDS_ACCT);
922 g_list_free(ctx->parse_state);
923 ctx->parse_state = NULL;
930 qif_invst_txn_new(
void)
934 itxn->amount = gnc_numeric_zero();
935 itxn->d_amount = gnc_numeric_zero();
936 itxn->price = gnc_numeric_zero();
937 itxn->shares = gnc_numeric_zero();
938 itxn->commission = gnc_numeric_zero();
948 g_free(itxn->amountstr);
949 g_free(itxn->d_amountstr);
950 g_free(itxn->pricestr);
951 g_free(itxn->sharesstr);
952 g_free(itxn->commissionstr);
953 g_free(itxn->security);
955 g_free(itxn->catstr);
961 qif_txn_invst_parse(
QifContext ctx, GList *record)
967 g_return_val_if_fail(ctx, QIF_E_INTERNAL);
968 g_return_val_if_fail(record, QIF_E_BADSTATE);
971 txn->txn_type = ctx->parse_type;
972 itxn = qif_invst_txn_new();
973 txn->invst_info = itxn;
975 for (; record; record = record->next)
982 qif_save_str(txn->datestr);
985 qif_save_str(txn->payee);
988 itxn->action = qif_parse_action(line);
991 txn->cleared = qif_parse_cleared(line);
994 if (!txn->current_split)
995 qif_save_str(txn->default_split->memo);
998 if (!qif_is_bad_numeric_string(line->line))
999 qif_save_str(itxn->amountstr);
1002 if (!qif_is_bad_numeric_string(line->line))
1003 qif_save_str(itxn->d_amountstr);
1006 qif_save_str(itxn->pricestr);
1009 qif_save_str(itxn->sharesstr);
1012 qif_save_str(itxn->security);
1015 qif_save_str(itxn->commissionstr);
1018 qif_save_str(itxn->catstr);
1021 PERR(
"Unknown QIF Investment transaction data at line %d: %s",
1022 line->lineno, line->line);
1027 if (txn->datestr && itxn->action != QIF_A_NONE)
1031 if (!itxn->security)
1032 itxn->security = g_strdup(
"");
1037 if (ctx->current_acct)
1038 txn->from_acct = ctx->current_acct;
1040 qif_set_flag(ctx->parse_flags, QIF_F_ITXN_NEEDS_ACCT);
1043 ctx->parse_state = g_list_prepend(ctx->parse_state, txn);
1060 QifSplit near_split, far_split, comm_split;
1064 char *cat_class = NULL;
1065 gboolean cat_is_acct = FALSE;
1067 char *miscx_class = NULL;
1068 gboolean miscx_is_acct = FALSE;
1071 static GList *bank_list = NULL;
1075 g_return_if_fail(ctx);
1076 g_return_if_fail(txn);
1077 g_return_if_fail(txn->invst_info);
1079 itxn = txn->invst_info;
1085 if (!itxn->amountstr && itxn->d_amountstr)
1086 itxn->amount = itxn->d_amount;
1089 near_split = txn->default_split;
1090 far_split = qif_split_new();
1091 from_acct = txn->from_acct;
1094 if (!qif_parse_split_category(itxn->catstr,
1095 &cat, &cat_is_acct, &cat_class,
1096 &miscx, &miscx_is_acct, &miscx_class))
1097 PERR(
"Failure parsing category: %s", itxn->catstr);
1100 if (bank_list == NULL)
1101 bank_list = qif_parse_acct_type(
"__any_bank__", -1);
1105 switch (itxn->action)
1109 case QIF_A_REINVDIV:
1110 case QIF_A_REINVINT:
1119 case QIF_A_STKSPLIT:
1120 txn->from_acct = qif_default_stock_acct(ctx, itxn->security);
1134 txn->from_acct = from_acct;
1139 case QIF_A_CGSHORTX:
1142 case QIF_A_MARGINTX:
1143 case QIF_A_RTRNCAPX:
1144 txn->from_acct = find_or_make_acct(ctx, cat, bank_list);
1148 case QIF_A_MISCEXPX:
1149 case QIF_A_MISCINCX:
1150 txn->from_acct = find_or_make_acct(ctx, miscx, bank_list);
1155 PERR(
"Unhandled Action: %d", itxn->action);
1161 itxn->far_cat_is_acct = TRUE;
1162 switch (itxn->action)
1166 itxn->far_cat.acct = from_acct;
1171 case QIF_A_MISCEXPX:
1173 case QIF_A_MISCINCX:
1177 itxn->far_cat.cat = find_or_make_cat(ctx, cat);
1178 itxn->far_cat_is_acct = FALSE;
1185 itxn->far_cat.acct = qif_default_cglong_acct(ctx, itxn->security);
1191 itxn->far_cat.acct = qif_default_cgmid_acct(ctx, itxn->security);
1195 case QIF_A_CGSHORTX:
1198 itxn->far_cat.acct = qif_default_cgshort_acct(ctx, itxn->security);
1203 case QIF_A_REINVDIV:
1204 itxn->far_cat.acct = qif_default_dividend_acct(ctx, itxn->security);
1209 case QIF_A_REINVINT:
1210 itxn->far_cat.acct = qif_default_interest_acct(ctx, itxn->security);
1214 case QIF_A_MARGINTX:
1215 itxn->far_cat.acct = qif_default_margin_interest_acct(ctx);
1219 case QIF_A_RTRNCAPX:
1220 itxn->far_cat.acct = qif_default_capital_return_acct(ctx, itxn->security);
1225 itxn->far_cat.acct = qif_default_equity_holding(ctx, itxn->security);
1228 case QIF_A_STKSPLIT:
1229 itxn->far_cat.acct = qif_default_stock_acct(ctx, itxn->security);
1237 if (!itxn->far_cat.obj)
1238 itxn->far_cat_is_acct = FALSE;
1245 switch (itxn->action)
1249 case QIF_A_REINVDIV:
1250 case QIF_A_REINVINT:
1256 near_split->amount = itxn->shares;
1257 near_split->value = split_value;
1266 far_split->amount = far_split->value = itxn->amount;
1274 case QIF_A_CGSHORTX:
1280 case QIF_A_MISCINCX:
1282 case QIF_A_RTRNCAPX:
1284 near_split->amount = near_split->value = itxn->amount;
1289 case QIF_A_MARGINTX:
1291 case QIF_A_MISCEXPX:
1293 near_split->amount = near_split->value =
gnc_numeric_neg(itxn->amount);
1294 far_split->amount = far_split->value = itxn->amount;
1297 case QIF_A_STKSPLIT:
1304 far_split->value = split_value;
1327 far_split->cat.obj = itxn->far_cat.obj;
1328 if (itxn->far_cat_is_acct)
1329 far_split->cat_is_acct = TRUE;
1332 if (itxn->commissionstr)
1334 comm_split = qif_split_new();
1335 comm_split->cat.acct = qif_default_commission_acct(ctx);
1336 comm_split->cat_is_acct = TRUE;
1337 comm_split->amount = itxn->commission;
1338 comm_split->value = itxn->commission;
1340 txn->splits = g_list_prepend(txn->splits, comm_split);
1344 txn->splits = g_list_prepend(txn->splits, far_split);
1350 g_free(miscx_class);
1358 qif_set_flag(ctx->parse_flags, QIF_F_IGNORE_ACCOUNTS);
1364 qif_clear_flag(ctx->parse_flags, QIF_F_IGNORE_ACCOUNTS);
1372 find_or_make_acct(
QifContext ctx,
char *name, GList *types)
1376 res = (
QifAccount)qif_object_map_lookup(ctx, QIF_O_ACCOUNT, name);
1381 res = qif_account_new();
1383 res->type_list = types;
1385 qif_object_map_insert(ctx, name, (
QifObject)res);
1396 res = (
QifCategory)qif_object_map_lookup(ctx, QIF_O_CATEGORY, name);
1401 res = qif_cat_new();
1405 qif_object_map_insert(ctx, name, (
QifObject)res);
1412 find_or_make_class(
QifContext ctx,
char *name)
1416 res = (
QifClass)qif_object_map_lookup(ctx, QIF_O_CLASS, name);
1421 res = qif_class_new();
1423 qif_object_map_insert(ctx, name, (
QifObject)res);
1434 qif_object_init(
void)
1443 { QIF_TYPE_BANK, { qif_txn_init, qif_txn_parse, qif_txn_end_acct } },
1444 { QIF_TYPE_CASH, { qif_txn_init, qif_txn_parse, qif_txn_end_acct } },
1445 { QIF_TYPE_CCARD, { qif_txn_init, qif_txn_parse, qif_txn_end_acct } },
1446 { QIF_TYPE_INVST, { qif_txn_init, qif_txn_invst_parse, qif_txn_end_acct } },
1447 { QIF_TYPE_PORT, { qif_txn_init, qif_txn_invst_parse, qif_txn_end_acct } },
1448 { QIF_TYPE_OTH_A, { qif_txn_init, qif_txn_parse, qif_txn_end_acct } },
1449 { QIF_TYPE_OTH_L, { qif_txn_init, qif_txn_parse, qif_txn_end_acct } },
1450 { QIF_TYPE_CLASS, { NULL, qif_class_parse, NULL } },
1451 { QIF_TYPE_CAT, { NULL, qif_cat_parse, NULL } },
1452 { QIF_TYPE_SECURITY, { NULL, qif_security_parse, NULL } },
1453 { QIF_ACCOUNT, { NULL, qif_account_parse, NULL } },
1454 { QIF_AUTOSWITCH, { qif_autoswitch_set, NULL, NULL } },
1455 { QIF_CLEAR_AUTOSWITCH, { qif_autoswitch_clear, NULL, NULL } },
1456 { 0, {NULL, NULL, NULL} }
1459 for (i = 0; handlers[i].type > 0; i++)
1461 if (handlers[i].type <= 0)
1463 PERR(
"Invalid type?!? (%d @ %d)", handlers[i].type, i);
1466 qif_register_handler(handlers[i].type, &(handlers[i].handler));
gnc_numeric gnc_numeric_neg(gnc_numeric a)
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gboolean gnc_numeric_zero_p(gnc_numeric a)
#define PERR(format, args...)
Account handling public routines.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
All type declarations for the whole Gnucash engine.
const gchar * QofLogModule