more improvements to the quicken file parsing code

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@166 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1997-11-27 10:54:21 +00:00
parent a065747f21
commit 19e97d3486
2 changed files with 193 additions and 46 deletions

View File

@ -49,6 +49,8 @@ actionBox (Widget parent)
AddPopBoxMenuItem (popGUI, "STCG");
AddPopBoxMenuItem (popGUI, "Dist");
AddPopBoxMenuItem (popGUI, "Split");
AddPopBoxMenuItem (popGUI, "Deposit");
AddPopBoxMenuItem (popGUI, "Withdraw");
return popGUI;
}

View File

@ -220,7 +220,7 @@ void xaccParseQIFDate (Date * dat, char * str)
/********************************************************************\
* xaccParseQIFAmount *
* parses dollar ammount of the form DDD.CC *
* parses dollar ammount of the form DDD,DDD,DDD.CC *
* *
* Args: str -- pointer to string rep of sum *
* Return: int -- in pennies *
@ -229,9 +229,9 @@ void xaccParseQIFDate (Date * dat, char * str)
double xaccParseQIFAmount (char * str)
{
char * tok;
double dollars = 0;
double dollars = 0.0;
if (!str) return 0;
if (!str) return 0.0;
tok = strchr (str, ',');
if (tok) {
@ -249,19 +249,105 @@ double xaccParseQIFAmount (char * str)
}
tok = strchr (str, '.');
if (!tok) return 0;
if (tok) {
*tok = 0x0;
dollars += ((double) (atoi (str)));
str = tok+sizeof(char);
tok = strchr (str, '\r');
if (!tok) return dollars;
*tok = 0x0;
dollars += 0.01 * ((double) atoi (str));
return dollars;
} else {
tok = strchr (str, '\r');
if (tok) {
*tok = 0x0;
dollars += ((double) (atoi (str)));
return dollars;
} else {
return 0.0;
}
}
return dollars;
}
/********************************************************************\
\********************************************************************/
Account *
xaccGetXferQIFAccount (Account *acc, char *qifline)
{
Account *xfer_acc;
AccountGroup *rootgrp;
char * tmp;
/* remove square brackets from name, remove carriage return ... */
qifline = &qifline[1];
if ('[' == qifline[0]) {
qifline = &qifline[1];
tmp = strchr (qifline, ']');
if (tmp) *tmp = 0x0;
}
tmp = strchr (qifline, '\r');
if(tmp) *tmp = 0x0;
tmp = strchr (qifline, '\n');
if(tmp) *tmp = 0x0;
/* see if the account exists */
rootgrp = xaccGetRootGroupOfAcct (acc);
xfer_acc = xaccGetAccountFromName (rootgrp, qifline);
/* if not, create it */
if (!xfer_acc) {
xfer_acc = mallocAccount ();
xfer_acc->accountName = XtNewString (qifline);
xfer_acc->type = BANK;
insertAccount (rootgrp, xfer_acc);
}
return xfer_acc;
}
/********************************************************************\
\********************************************************************/
Account *
xaccGetSecurityQIFAccount (Account *acc, char *qifline)
{
Account *xfer_acc;
AccountGroup *rootgrp;
char * tmp;
/* remove square brackets from name, remove carriage return ... */
qifline = &qifline[1];
if ('[' == qifline[0]) {
qifline = &qifline[1];
tmp = strchr (qifline, ']');
if (tmp) *tmp = 0x0;
}
tmp = strchr (qifline, '\r');
if(tmp) *tmp = 0x0;
tmp = strchr (qifline, '\n');
if(tmp) *tmp = 0x0;
/* see if the account exists */
rootgrp = xaccGetRootGroupOfAcct (acc);
xfer_acc = xaccGetAccountFromName (rootgrp, qifline);
/* if not, create it */
if (!xfer_acc) {
xfer_acc = mallocAccount ();
xfer_acc->accountName = XtNewString (qifline);
xfer_acc->type = STOCK;
xaccInsertSubAccount (acc, xfer_acc);
}
return xfer_acc;
}
/********************************************************************\
* xaccReadQIFTransaction *
* reads in transaction *
@ -274,11 +360,20 @@ double xaccParseQIFAmount (char * str)
* Return: first new line after end of transaction *
\********************************************************************/
#define XACC_ACTION(q,x) \
if (!strncmp (&qifline[1], q, strlen(q))) { \
trans->action = XtNewString(x); \
} else
char * xaccReadQIFTransaction (int fd, Account *acc)
{
Transaction *trans;
char * qifline;
int isneg = 0;
int got_quantity = 0;
int do_security = 0;
Account *sub_acc = 0x0;
if (!acc) return NULL;
trans = (Transaction *)_malloc(sizeof(Transaction));
@ -313,70 +408,103 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
/* scan for transaction date, description, type */
while (qifline) {
if ('M' == qifline [0]) { /* M == memo field */
/* M == memo field */
if ('M' == qifline [0]) {
XACC_PREP_STRING (trans->memo);
} else
if ('P' == qifline [0]) { /* P == Payee, for Bank accounts */
/* P == Payee, for Bank accounts */
if ('P' == qifline [0]) {
XACC_PREP_STRING (trans->description);
} else
if ('Y' == qifline [0]) { /* Y == Name of Security */
/* Y == Name of Security */
if ('Y' == qifline [0]) {
XACC_PREP_STRING (trans->description);
if (do_security) {
/* locate or create the sub-account account */
sub_acc = xaccGetSecurityQIFAccount (acc, qifline);
/* now, insert the transaction into the
* main (not sub) account as a debit. The
* main account will be debited, the
* subaccount credited */
trans->debit = (struct _account *) acc;
insertTransaction (acc, trans);
}
} else
/* N == check numbers for Banks, but Action for portfolios */
if ('N' == qifline [0]) {
XACC_PREP_STRING (trans->num);
if (!strncmp (qifline, "NSell", 5)) isneg = 1;
if (!strncmp (qifline, "NSell", 5)) do_security = 1;
if (!strncmp (qifline, "NBuy", 4)) do_security = 1;
/* if a recognized action, convert to our cannonical names */
XACC_ACTION ("Buy", "Buy")
XACC_ACTION ("Sell", "Sell")
XACC_ACTION ("Div", "Div")
XACC_ACTION ("CGLong", "LTCG")
XACC_ACTION ("CGShort", "STCG")
XACC_ACTION ("IntInc", "Int")
XACC_ACTION ("DEP", "Deposit")
XACC_ACTION ("XIn", "Deposit")
XACC_ACTION ("XOut", "Withdraw")
{
XACC_PREP_STRING (trans->num);
}
} else
if ('D' == qifline [0]) { /* D == date */
xaccParseQIFDate (&(trans->date), &qifline[1]);
} else
if ('T' == qifline [0]) { /* T == total */
trans -> damount = xaccParseQIFAmount (&qifline[1]); /* amount is double */
/* ignore T for stock transactions, since T is a dollar amount */
if (0 == got_quantity) {
trans -> damount = xaccParseQIFAmount (&qifline[1]);
if (isneg) trans -> damount = - (trans->damount);
}
} else
if ('I' == qifline [0]) { /* I == share price */
trans -> share_price = xaccParseQIFAmount (&qifline[1]); /* amount is double */
trans -> share_price = xaccParseQIFAmount (&qifline[1]);
} else
if ('Q' == qifline [0]) { /* Q == number of shares */
/* hack alert */
trans -> damount = xaccParseQIFAmount (&qifline[1]);
if (isneg) trans -> damount = - (trans->damount);
got_quantity = 1;
} else
if ('L' == qifline [0]) { /* L == name of acount from which transfer occured */
Account *xfer_acc;
AccountGroup *rootgrp;
char * tmp;
/* remove square brackets from name, remove carriage return ... */
qifline = &qifline[1];
if ('[' == qifline[0]) {
qifline = &qifline[1];
tmp = strchr (qifline, ']');
if (tmp) *tmp = 0x0;
}
tmp = strchr (qifline, '\r');
if(tmp) *tmp = 0x0;
tmp = strchr (qifline, '\n');
if(tmp) *tmp = 0x0;
/* see if the account exists */
rootgrp = xaccGetRootGroupOfAcct (acc);
xfer_acc = xaccGetAccountFromName (rootgrp, qifline);
/* if not, create it */
if (!xfer_acc) {
xfer_acc = mallocAccount ();
xfer_acc->accountName = XtNewString (qifline);
xfer_acc->type = BANK;
insertAccount (rootgrp, xfer_acc);
}
/* locate the transfer account */
xfer_acc = xaccGetXferQIFAccount (acc, qifline);
/* now, insert the transaction into the transfer account */
trans->debit = (struct _account *) xfer_acc;
insertTransaction (xfer_acc, trans);
} else
if ('$' == qifline [0]) { /* $ == dollar amount -- always preceeded by 'L' */
/* hack alert */
/* $ == dollar amount -- always preceeded by 'L' */
if ('$' == qifline [0]) {
/* Currently, it appears that the $ amount is a redundant
* number that we can safely ignore. If we wanted to get
* fancy, we could use it to double-check the above work,
* since it appears to always appear the last entry in the
* transaction. */
double got, wanted;
wanted = xaccParseQIFAmount (&qifline[1]);
got = (trans->damount) * (trans->share_price);
if (isneg) got = -got;
if (wanted != got) {
printf ("QIF Parse Error: wanted %f got %f \n", wanted, got);
}
} else
if ('O' == qifline [0]) { /* O == round-off error ??? */
/* hack alert */
} else
@ -393,6 +521,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
xaccRemoveTransaction ((Account *) trans->debit, trans);
xaccRemoveTransaction ((Account *) trans->credit, trans);
freeTransaction (trans);
return qifline;
}
XACC_PREP_NULL_STRING (trans->num);
@ -400,6 +529,10 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
XACC_PREP_NULL_STRING (trans->description);
XACC_PREP_NULL_STRING (trans->action);
/* if a transaction (e.g. security) belongs
* in a subaccount, hnalde it now */
if (sub_acc) acc = sub_acc;
trans->credit = (struct _account *) acc;
insertTransaction( acc, trans );
@ -484,6 +617,18 @@ xaccReadQIFData( char *datafile )
continue;
} else
if (!strcmp (qifline, "!Type:Invst\r\n")) {
Account *acc = mallocAccount();
DEBUG ("got Invst\n");
acc->type = BANK;
acc->accountName = XtNewString ("Quicken Investment Account");
insertAccount( grp, acc );
qifline = xaccReadQIFTransList (fd, acc);
continue;
} else
if (!strcmp (qifline, "!Option:AutoSwitch\r\n")) {
DEBUG ("got autoswitch on\n");
skip = 1;