gnucash master: Remove the src/experimental directory for being hopelessly obsolete and probably useless.
John Ralls
jralls at code.gnucash.org
Mon Dec 14 17:25:18 EST 2015
Updated via https://github.com/Gnucash/gnucash/commit/697e746b (commit)
from https://github.com/Gnucash/gnucash/commit/54d087bf (commit)
commit 697e746bc2a9d97d7a495a07b3b28e424aa4c072
Author: John Ralls <jralls at ceridwen.us>
Date: Mon Dec 14 14:25:05 2015 -0800
Remove the src/experimental directory for being hopelessly obsolete and probably useless.
diff --git a/src/experimental/Makefile.am b/src/experimental/Makefile.am
deleted file mode 100644
index a9a44e4..0000000
--- a/src/experimental/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-
-SUBDIRS = cbb gg
-DIST_SUBDIRS = ${SUBDIRS} cgi-bin
-
-EXTRA_DIST = \
- README
diff --git a/src/experimental/README b/src/experimental/README
deleted file mode 100644
index 3d7d7fe..0000000
--- a/src/experimental/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains misc experimental/unfinished/unmaintained/unsupported
-code. The stuff in here is waiting for someone to take it over and do something
-useful with it.
diff --git a/src/experimental/cbb/Makefile.am b/src/experimental/cbb/Makefile.am
deleted file mode 100644
index 9594591..0000000
--- a/src/experimental/cbb/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-
-SUBDIRS = cbb-engine
-
-EXTRA_DIST = \
- cbb-old-to-cbb-alpha \
- cbb-to-xacc
diff --git a/src/experimental/cbb/cbb-engine/CBBlib-auto.pl b/src/experimental/cbb/cbb-engine/CBBlib-auto.pl
deleted file mode 100644
index 250e801..0000000
--- a/src/experimental/cbb/cbb-engine/CBBlib-auto.pl
+++ /dev/null
@@ -1,523 +0,0 @@
-#!/usr/bin/perl -w
-# This code is automatically generated. Do not edit.
-
-
-#### CBBlib::Acct slot methods ###########################
-
-package CBBlib::Acct;
-use strict;
-
-sub make_internals_ {
- return [undef,
- undef,
- undef,
- undef,
- 0,
- 0,
- 0];
-}
-
-sub get_db_ { my $self = shift; return $$self[0]; }
-sub set_db_ { my($self, $val) = @_; $$self[0] = $val; }
-
-sub get_db { my $self = shift; return $$self[0]; }
-
-sub get_name_ { my $self = shift; return $$self[1]; }
-sub set_name_ { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_name { my $self = shift; return $$self[1]; }
-
-sub set_name { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_notes_ { my $self = shift; return $$self[2]; }
-sub set_notes_ { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_notes { my $self = shift; return $$self[2]; }
-
-sub set_notes { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_ledger_ { my $self = shift; return $$self[3]; }
-sub set_ledger_ { my($self, $val) = @_; $$self[3] = $val; }
-
-sub get_ledger_usage_count_ { my $self = shift; return $$self[4]; }
-sub set_ledger_usage_count_ { my($self, $val) = @_; $$self[4] = $val; }
-
-sub get_cleared_balance_ { my $self = shift; return $$self[5]; }
-sub set_cleared_balance_ { my($self, $val) = @_; $$self[5] = $val; }
-
-sub get_cleared_balance { my $self = shift; return $$self[5]; }
-
-sub get_final_balance_ { my $self = shift; return $$self[6]; }
-sub set_final_balance_ { my($self, $val) = @_; $$self[6] = $val; }
-
-sub get_final_balance { my $self = shift; return $$self[6]; }
-
-
-#### CBBlib::Cat slot methods ###########################
-
-package CBBlib::Cat;
-use strict;
-
-sub make_internals_ {
- return [undef,
- undef,
- undef,
- undef,
- 0,
- 0,
- 0];
-}
-
-sub get_db_ { my $self = shift; return $$self[0]; }
-sub set_db_ { my($self, $val) = @_; $$self[0] = $val; }
-
-sub get_db { my $self = shift; return $$self[0]; }
-
-sub get_name_ { my $self = shift; return $$self[1]; }
-sub set_name_ { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_name { my $self = shift; return $$self[1]; }
-
-sub set_name { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_notes_ { my $self = shift; return $$self[2]; }
-sub set_notes_ { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_notes { my $self = shift; return $$self[2]; }
-
-sub set_notes { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_ledger_ { my $self = shift; return $$self[3]; }
-sub set_ledger_ { my($self, $val) = @_; $$self[3] = $val; }
-
-sub get_ledger_usage_count_ { my $self = shift; return $$self[4]; }
-sub set_ledger_usage_count_ { my($self, $val) = @_; $$self[4] = $val; }
-
-sub get_cleared_balance_ { my $self = shift; return $$self[5]; }
-sub set_cleared_balance_ { my($self, $val) = @_; $$self[5] = $val; }
-
-sub get_cleared_balance { my $self = shift; return $$self[5]; }
-
-sub get_final_balance_ { my $self = shift; return $$self[6]; }
-sub set_final_balance_ { my($self, $val) = @_; $$self[6] = $val; }
-
-sub get_final_balance { my $self = shift; return $$self[6]; }
-
-
-#### CBBlib::Txn slot methods #############################
-
-package CBBlib::Txn;
-use strict;
-
-sub make_internals_ {
- return [undef,
- undef,
- undef,
- undef,
- undef,
- undef,
- '',
- []];
-}
-
-sub get_db_ { my $self = shift; return $$self[0]; }
-sub set_db_ { my($self, $val) = @_; $$self[0] = $val; }
-
-sub get_db { my $self = shift; return $$self[0]; }
-
-sub get_clone_ { my $self = shift; return $$self[1]; }
-sub set_clone_ { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_date_ { my $self = shift; return $$self[2]; }
-sub set_date_ { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_date {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_date_();
- } else {
- return $self->get_date_();
- }
-}
-
-sub set_date {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_date_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_date_($val);
- }
-}
-sub get_source_ { my $self = shift; return $$self[3]; }
-sub set_source_ { my($self, $val) = @_; $$self[3] = $val; }
-
-sub get_source { my $self = shift; return $$self[3]; }
-
-sub get_checkno_ { my $self = shift; return $$self[4]; }
-sub set_checkno_ { my($self, $val) = @_; $$self[4] = $val; }
-
-sub get_checkno {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_checkno_();
- } else {
- return $self->get_checkno_();
- }
-}
-
-sub set_checkno {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_checkno_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_checkno_($val);
- }
-}
-sub get_desc_ { my $self = shift; return $$self[5]; }
-sub set_desc_ { my($self, $val) = @_; $$self[5] = $val; }
-
-sub get_desc {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_desc_();
- } else {
- return $self->get_desc_();
- }
-}
-
-sub set_desc {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_desc_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_desc_($val);
- }
-}
-sub get_status_ { my $self = shift; return $$self[6]; }
-sub set_status_ { my($self, $val) = @_; $$self[6] = $val; }
-
-sub get_status {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_status_();
- } else {
- return $self->get_status_();
- }
-}
-
-sub set_status {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_status_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_status_($val);
- }
-}
-sub get_splits_ { my $self = shift; return $$self[7]; }
-sub set_splits_ { my($self, $val) = @_; $$self[7] = $val; }
-
-sub get_splits { my $self = shift; return $$self[7]; }
-
-
-#### CBBlib::Split slot methods ###########################
-
-package CBBlib::Split;
-use strict;
-
-sub make_internals_ {
- return [undef,
- undef,
- undef,
- undef,
- undef,
- undef,
- undef,
- undef,
- ''];
-}
-
-sub get_txn_ { my $self = shift; return $$self[0]; }
-sub set_txn_ { my($self, $val) = @_; $$self[0] = $val; }
-
-sub get_txn { my $self = shift; return $$self[0]; }
-
-sub get_clone_ { my $self = shift; return $$self[1]; }
-sub set_clone_ { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_pos__ { my $self = shift; return $$self[2]; }
-sub set_pos__ { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_pos_ {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_pos__();
- } else {
- return $self->get_pos__();
- }
-}
-
-sub set_pos_ {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_pos__($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_pos__($val);
- }
-}
-sub get_dest_ { my $self = shift; return $$self[3]; }
-sub set_dest_ { my($self, $val) = @_; $$self[3] = $val; }
-
-sub get_dest {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_dest_();
- } else {
- return $self->get_dest_();
- }
-}
-
-sub set_dest {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_dest_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_dest_($val);
- }
-}
-sub get_notes_ { my $self = shift; return $$self[4]; }
-sub set_notes_ { my($self, $val) = @_; $$self[4] = $val; }
-
-sub get_notes {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_notes_();
- } else {
- return $self->get_notes_();
- }
-}
-
-sub set_notes {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_notes_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_notes_($val);
- }
-}
-sub get_debit_ { my $self = shift; return $$self[5]; }
-sub set_debit_ { my($self, $val) = @_; $$self[5] = $val; }
-
-sub get_debit {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_debit_();
- } else {
- return $self->get_debit_();
- }
-}
-
-sub set_debit {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_debit_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_debit_($val);
- }
-}
-sub get_credit_ { my $self = shift; return $$self[6]; }
-sub set_credit_ { my($self, $val) = @_; $$self[6] = $val; }
-
-sub get_credit {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_credit_();
- } else {
- return $self->get_credit_();
- }
-}
-
-sub set_credit {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_credit_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_credit_($val);
- }
-}
-sub get_desc_ { my $self = shift; return $$self[7]; }
-sub set_desc_ { my($self, $val) = @_; $$self[7] = $val; }
-
-sub get_desc {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_desc_();
- } else {
- return $self->get_desc_();
- }
-}
-
-sub set_desc {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_desc_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_desc_($val);
- }
-}
-sub get_status_ { my $self = shift; return $$self[8]; }
-sub set_status_ { my($self, $val) = @_; $$self[8] = $val; }
-
-sub get_status {
- my $self = shift;
- my $clone = $self->get_clone_();
- if($clone) {
- return $clone->get_status_();
- } else {
- return $self->get_status_();
- }
-}
-
-sub set_status {
- my($self, $val) = @_;
-
- my $db = $self->get_db();
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $clone->set_status_($val);
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- } else {
- $self->set_status_($val);
- }
-}
-
-#### CBBlib::Db slot methods ###########################
-
-package CBBlib::Db;
-use strict;
-
-sub make_internals_ {
- return [[],
- [],
- undef,
- [],
- undef,
- 0,
- {}];
-}
-
-sub get_accts_ { my $self = shift; return $$self[0]; }
-sub set_accts_ { my($self, $val) = @_; $$self[0] = $val; }
-
-sub get_accts { my $self = shift; return $$self[0]; }
-
-sub get_cats_ { my $self = shift; return $$self[1]; }
-sub set_cats_ { my($self, $val) = @_; $$self[1] = $val; }
-
-sub get_cats { my $self = shift; return $$self[1]; }
-
-sub get_default_sink_ { my $self = shift; return $$self[2]; }
-sub set_default_sink_ { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_default_sink { my $self = shift; return $$self[2]; }
-
-sub set_default_sink { my($self, $val) = @_; $$self[2] = $val; }
-
-sub get_txns_ { my $self = shift; return $$self[3]; }
-sub set_txns_ { my($self, $val) = @_; $$self[3] = $val; }
-
-sub get_txns { my $self = shift; return $$self[3]; }
-
-sub get_modified_txns_ { my $self = shift; return $$self[4]; }
-sub set_modified_txns_ { my($self, $val) = @_; $$self[4] = $val; }
-
-sub get_modified_txns_level_ { my $self = shift; return $$self[5]; }
-sub set_modified_txns_level_ { my($self, $val) = @_; $$self[5] = $val; }
-
-sub get_callbacks_hash_ { my $self = shift; return $$self[6]; }
-sub set_callbacks_hash_ { my($self, $val) = @_; $$self[6] = $val; }
-
-1;
-__END__
diff --git a/src/experimental/cbb/cbb-engine/CBBlib-auto.plp b/src/experimental/cbb/cbb-engine/CBBlib-auto.plp
deleted file mode 100644
index cb28380..0000000
--- a/src/experimental/cbb/cbb-engine/CBBlib-auto.plp
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/perl -w
-use strict;
-use English;
-
-#sub new {
-# my $class = shift;
-# my ($db, $name, $notes) = @_;
-#
-# my $self = make_internals_();
-#
-# $self->set_db_($db);
-# $self->set_name_($name);
-# $self->set_notes_($notes);
-#
-# bless $self, $class;
-# return $self;
-#}
-
-
-my @acct_slots =
- ({'name'=> 'db', 'options' => ['pub-get']},
- {'name'=> 'name', 'options' => ['pub-get','pub-set']},
- {'name'=> 'notes', 'options' => ['pub-get','pub-set']},
- {'name'=> 'ledger', 'options' => []},
- {'name'=> 'ledger_usage_count', 'init' => 0, 'options' => []},
- {'name'=> 'cleared_balance', 'init' => 0, 'options' => ['pub-get']},
- {'name'=> 'final_balance', 'init' => 0, 'options' => ['pub-get']});
-
-my @cat_slots = @acct_slots;
-
-my @txn_slots =
- ({'name'=> 'db', 'options' => ['pub-get']},
- {'name'=> 'clone', 'options' => []},
- {'name'=> 'date', 'options' => ['modify']},
- {'name'=> 'source', 'options' => ['pub-get']},
- {'name'=> 'checkno', 'options' => ['modify']},
- {'name'=> 'desc', 'options' => ['modify']},
- {'name'=> 'status', 'init' => "''", 'options' => ['modify']},
- {'name'=> 'splits', 'init' => '[]', 'options' => ['pub-get']});
-
-my @split_slots =
- ({'name'=> 'txn', 'options' => ['pub-get']},
- {'name'=> 'clone', 'options' => []},
- {'name'=> 'pos_', 'options' => ['modify']},
- {'name'=> 'dest', 'options' => ['modify']},
- {'name'=> 'notes', 'options' => ['modify']},
- {'name'=> 'debit', 'options' => ['modify']},
- {'name'=> 'credit', 'options' => ['modify']},
- {'name'=> 'desc', 'options' => ['modify']},
- {'name'=> 'status', 'init' => "''", 'options' => ['modify']});
-
-my @db_slots =
- ({'name'=> 'accts', 'init' => '[]', 'options' => ['pub-get']},
- {'name'=> 'cats', 'init' => '[]', 'options' => ['pub-get']},
- {'name'=> 'default_sink', 'options' => ['pub-get', 'pub-set']},
- {'name'=> 'txns', 'init' => '[]', 'options' => ['pub-get']},
- {'name'=> 'modified_txns', 'options' => []},
- {'name'=> 'modified_txns_level', 'init' => 0, 'options' => []},
- #{'name'=> 'modified_txns_serial_num', 'init' => 0, 'options' => []},
- {'name'=> 'callbacks_hash', 'init' => '{}', 'options' => []});
-
-
-print "#!/usr/bin/perl -w\n" .
- "# This code is automatically generated. Do not edit.\n\n";
-
-sub generate_slot_methods {
- my($pkg, @slots) = @_;
-
- print "package $pkg;\n";
- print "use strict;\n\n";
-
- print "sub make_internals_ {\n";
- print " return [";
- my @inits = map {
- my $slot = $_;
- my $init = $$slot{'init'};
- if(defined($init)) {
- $init;
- } else {
- 'undef';
- }
- } @slots;
- print join(",\n ", @inits);
- print "];\n";
- print "}\n\n";
-
- my $index = 0;
- my $slot;
- foreach $slot (@slots) {
- my $option_list = $$slot{'options'};
- my %options;
-
- my $item;
- foreach $item (@$option_list) {
- $options{$item} = 1;
- }
-
- # Everyone gets private getter/setter.
- print 'sub get_' . $$slot{'name'} . '_ ' .
- '{ my $self = shift; return $$self[' . $index . "]; }\n";
- print 'sub set_' . $$slot{'name'} . '_ ' .
- '{ my($self, $val) = @_; $$self[' . $index . '] = $val; }' . "\n\n";
-
- if($options{'pub-get'}) {
- print 'sub get_' . $$slot{'name'} . ' ' .
- '{ my $self = shift; return $$self[' . $index . "]; }\n\n";
- }
- if($options{'pub-set'}) {
- print 'sub set_' . $$slot{'name'} . ' ' .
- '{ my($self, $val) = @_; $$self[' . $index . '] = $val; }' . "\n\n";
- }
-
- # Don't forget to change $txn->add/remove_split in CBBlib.pl too
- # whenever you make changes here.
-
- if($options{'modify'}) {
- print <<EOS;
-sub get_$${slot{name}} {
- my \$self = shift;
- my \$clone = \$self->get_clone_();
- if(\$clone) {
- return \$clone->get_$${slot{name}}_();
- } else {
- return \$self->get_$${slot{name}}_();
- }
-}
-
-sub set_$${slot{name}} {
- my(\$self, \$val) = \@_;
-
- my \$db = \$self->get_db();
- if(\$db) {
- \$db->begin_txn_modifications();
-
- my \$clone = \$self->make_clone_();
- \$clone->set_$${slot{name}}_(\$val);
- \$db->record_txn_modification_(\$self);
- \$db->end_txn_modifications();
- } else {
- \$self->set_$${slot{name}}_(\$val);
- }
-}
-EOS
-
- }
- $index++;
- }
-}
-
-
-print "\n#### CBBlib::Acct slot methods ###########################\n\n";
-generate_slot_methods('CBBlib::Acct', @acct_slots);
-print "\n#### CBBlib::Cat slot methods ###########################\n\n";
-generate_slot_methods('CBBlib::Cat', @cat_slots);
-print "\n#### CBBlib::Txn slot methods #############################\n\n";
-generate_slot_methods('CBBlib::Txn', @txn_slots);
-print "\n#### CBBlib::Split slot methods ###########################\n\n";
-generate_slot_methods('CBBlib::Split', @split_slots);
-print "\n#### CBBlib::Db slot methods ###########################\n\n";
-generate_slot_methods('CBBlib::Db', @db_slots);
-
-print "1;\n__END__\n";
-
-1;
-__END__
diff --git a/src/experimental/cbb/cbb-engine/CBBlib.pl b/src/experimental/cbb/cbb-engine/CBBlib.pl
deleted file mode 100644
index c9aef70..0000000
--- a/src/experimental/cbb/cbb-engine/CBBlib.pl
+++ /dev/null
@@ -1,1739 +0,0 @@
-#!/usr/bin/perl -w
-#use Exporter();
-
-package CBBlib;
-
-use strict;
-use English;
-use IO;
-## @file
-# @brief Belongs to package CBBlib
-#
-#### To do ######################
-#
-# Check remove transactions.
-# Move everything to Cbb package.
-#
-# put warnings into add_txns and remove_txns if attempted when inside
-# begin/end_txn_modifications
-#
-# Check to see that set_db is OK in the face of modifications...
-#
-# update_ledger has to return a sorted list of txn indices for modified txns
-#
-# ledger_add/modify/remove_txns?
-#
-# note_txn_modification
-#
-# Dirty should be set whenever a modification is made.
-# Dirty should be cleared whenever the client tells us we're clear...
-#
-# What about clones and begin/end_modify_txns and no db?
-#
-# check copy_obj, and automate?
-#
-# Need to clone account balances too?
-#
-# Should have list positions in txns?
-#
-# Need to create "Unitemized" category by default.
-#
-# Don't sort modifications by serial number. Order is irrelevant.
-# Just use dates
-# @cond Perl
-
-STDOUT->autoflush(1);
-STDERR->autoflush(1);
-
-#@ISA = qw(Exporter);
-#@EXPORT = qw(func1 func2);
-#@EXPORT_OK = qw($sally @listabob %harry func3);
-
-## private #################################################################
-
-sub BEGIN {}
-
-sub END {
- my $old_status = $?;
-
- $? = $old_status;
-}
-
-## public ##################################################################
-
-my $pref_debug = 0;
-my $pref_verbose = 0;
-
-sub set_debug {
- my($value) = @_;
- $pref_debug = 1;
-}
-
-sub set_verbose {
- my($value) = @_;
- $pref_verbose = 1;
-}
-
-sub debug {
- my($message) = @_;
- print STDERR $message if $pref_debug;
-}
-
-sub verbose {
- my($message) = @_;
- print STDERR $message if ($pref_verbose || $pref_debug);
-}
-
-my $elapsed_offset = 0;
-
-sub elapsed_reset {
- my $prefix = shift;
- my($user,$system) = times;
- $elapsed_offset = $user + $system;
- print STDERR $prefix . " ... " if $prefix;
-}
-sub elapsed {
- my $prefix = shift;
- print STDERR $prefix if $prefix;
- my($user,$system) = times;
- print STDERR '(elapsed time: ' . ($user + $system - $elapsed_offset) . ")\n";
-}
-
-package CBBlib::Sink;
-use strict;
-use English;
-use IO;
-
-# Abstract class -- no "new" defined.
-
-# A destination for money. Parent class for Acct and Cat.
-
-# It's really possible that ledgers should be a separate class, but
-# I'm tired and that's too big a change right now.
-
-
-sub acquire_ledger {
- my $self = shift;
- my $ledger = $self->get_ledger_();
- if(!$ledger) {
- $self->build_ledger_();
- print STDERR "Building ledger\n";
- }
- $self->set_ledger_usage_count_($self->get_ledger_usage_count_() + 1);
- return $self->get_ledger_();
-}
-
-sub release_ledger {
- my $self = shift;
- my $ledger = $self->get_ledger_();
- if(!$ledger) {
- print STERR "Big problem. Released ledger that didn't exist!\n";
- exit 1;
- }
-
- my $usage_count = $self->get_ledger_usage_count_();
- if(!$usage_count) {
- print STERR
- "Big problem. Released ledger that no-one could be holding!\n";
- exit 1;
- }
-
- $self->set_ledger_usage_count_($usage_count - 1);
- if($usage_count == 1) {
- print STDERR "Killing ledger\n";
- $self->set_ledger_(undef);
- }
-}
-
-sub build_ledger_ {
- my($self) = @_;
- my $db = $self->get_db();
- my $transactions = $db->get_txns();
- my $ledger = $self->get_ledger_();
- if(!$ledger) {
- $self->set_ledger_([]);
- $ledger = $self->get_ledger_();
- }
- @$ledger = ();
-
- my $cleared_balance = 0;
- my $total = 0;
- my $txn;
- foreach $txn (@$transactions) {
- my($debit, $credit, $applicable_txn) = $txn->totals_wrt($self);
- if($applicable_txn) {
- $total += ($credit - $debit);
- if($txn->cleared_wrt_p($self)) {
- $cleared_balance += ($credit - $debit);
- }
- push @$ledger, [ $txn, $total ];
- }
- }
- $self->set_cleared_balance_($cleared_balance);
- $self->set_final_balance_($total);
-}
-
-sub compare_ledger_and_txn_ {
- my($ledger, $txn) = @_;
- return($$ledger[0]->get_date() cmp $txn->get_date());
-}
-
-sub match_ledger_and_txn_ {
- my($ledger, $txn) = @_;
- return($$ledger[0] == $txn);
-}
-
-my $started_mods_p;
-my $mods_acct;
-my $cleared_balance_diff_tmp;
-
-sub handle_ledger_entry_merge_ {
- my($ledger, $index, $new_p) = @_;
-
- if($new_p || $started_mods_p) {
- if($new_p) {
- # convert txn to ledger pair.
- my $txn = $$ledger[$index];
- $$ledger[$index] = [$txn, 0.0];
- $started_mods_p = 1;
- }
-
- my $entry = $$ledger[$index];
- my $txn = $$entry[0];
- my($debit, $credit, $applicable_txn) = $txn->totals_wrt($mods_acct);
-
- if($new_p) {
- if($txn->cleared_wrt_p($mods_acct)) {
- $cleared_balance_diff_tmp += ($credit - $debit);
- }
- }
-
- my $prev_total = 0;
- my $prev_entry = $$ledger[$index - 1];
- if($prev_entry) {
- $prev_total = $$prev_entry[1];
- }
- $$entry[1] = $prev_total + ($credit - $debit);
- }
-}
-
-my $ledger_removal_diff;
-
-sub handle_ledger_entry_removal_ {
- my($killed_p, $ledger, $index, $old_item) = @_;
-
- if($killed_p || $started_mods_p) {
- my $txn = $$ledger[$index]; $txn = $$txn[0];
- if($killed_p) {
- my($debit, $credit, $applicable_txn) = $txn->totals_wrt($mods_acct);
- $ledger_removal_diff += ($credit - $debit);
- if($txn->cleared_wrt_p($mods_acct)) {
- $cleared_balance_diff_tmp -= ($credit - $debit);
- }
- $started_mods_p = 1;
- } else {
- my $prev_total = 0;
- my $prev_entry = $$ledger[$index - 1];
- if($prev_entry) { $prev_total = $$prev_entry[1]; }
- my $entry = $$ledger[$index];
- $$entry[1] = $prev_total - $ledger_removal_diff;
- }
- }
-}
-
-sub ledger_add_txns_ {
- my($self, $txns) = @_;
-
- my $ledger = $self->get_ledger_();
- if(!$ledger) {
- return [];
- }
-
- # Globals, yuck...
- $cleared_balance_diff_tmp = 0;
- $started_mods_p = 0;
- $mods_acct = $self;
- CBBlib::debug("There are " . scalar(@$ledger) . " ledger entries\n");
- CBBlib::debug(" adding " . scalar(@$txns) . " ledger entries\n");
- $$txns[0]->print(\*STDERR);
- my $added_indices =
- main::destructive_merge_mangle($ledger, $txns,
- \&compare_ledger_and_txn_,
- \&handle_ledger_entry_merge_);
- $self->set_cleared_balance_($self->get_cleared_balance() +
- $cleared_balance_diff_tmp);
- my $final = $$ledger[$#$ledger];
- $self->set_final_balance_($$final[1]);
- return $added_indices;
-}
-
-sub ledger_modify_txns_ {
- my($self, $txn_date_changed, $txns) = @_;
- # presumes @$txns is sorted on date to match the database order.
-
- my $ledger = $self->get_ledger_();
- if(!$ledger) {
- return ([], []);
- }
-
- # Brute force date change handling. We should do better later...
- my @txns_w_date_changes = grep {
- $$txn_date_changed{$_};
- } @$txns;
-
- my @moves = ();
-
- if(@txns_w_date_changes) {
- print STDERR "Handling ledger mods for date changes\n";
-
- # Get the current positions of the changed $txns
- my %move_from_txn;
- my @candidates = @txns_w_date_changes;
- my $candidate = shift @candidates;
- # Unfortunately, these txns won't be in the order relative to the
- # old ledger since their dates have changed, so we have to loop.
- # This may be marginally faster than just traversing once per txn.
- while($candidate) {
- print STDERR "Looking for candidate $candidate\n";
- my $initial_value = $candidate;
- my $i;
- for($i=0; $candidate && $i < scalar(@$ledger); $i++) {
- my $entry = $$ledger[$i];
- my $txn = $$entry[0];
- print STDERR "[$txn] [$candidate]\n";
- if($txn == $candidate) {
- my $move = [$i];
- push @moves, $move;
- $move_from_txn{$txn} = $move;
- $candidate = shift @candidates;
- }
- }
- if($initial_value == $candidate) {
- die "Couldn't find transaction in ledger during ledger modify";
- }
- }
-
- # Just trash the existing one to get the new one with these
- # transactions in the proper positions.
- $self->build_ledger_();
-
- # Now things should be properly sorted to match the order of
- # @txns_w_date_changes. We'll leave the extra loop just in case,
- # but this should go off in one pass.
- @candidates = @txns_w_date_changes;
- $candidate = shift @candidates;
- while($candidate) {
- my $initial_value = $candidate;
- my $i;
- for($i=0; $candidate && $i < scalar(@$ledger); $i++) {
- my $entry = $$ledger[$i];
- my $txn = $$entry[0];
- if($txn == $candidate) {
- my $move = $move_from_txn{$txn};
- die "FATAL: Couldn't find move in ledger search" if ! $move;
- push @$move, $i;
- $candidate = shift @candidates;
- }
- }
- if($initial_value == $candidate) {
- die "Couldn't find transaction in ledger during ledger modify";
- }
- }
- }
-
- my @modified_indices = ();
- my $current_index = 0;
-
- if(@$txns) {
- my @mod_txns = @$txns;
- my $next_mod_txn = shift @mod_txns;
- my $prev_ledger_value = 0;
- my $started_mods = 0;
- my $cleared_balance_diff = 0;
- my $diff = 0;
- my $entry;
- foreach $entry (@$ledger) {
- my $txn = $$entry[0];
- if(defined($next_mod_txn) && $next_mod_txn == $txn) {
- $started_mods = 1;
- my $prev_value = $$entry[1];
- my($debit, $credit, $applicable_txn) = $txn->totals_wrt($self);
- my $new_value = $prev_ledger_value + ($credit - $debit);
- my $local_change = $new_value - $prev_value;
- if($txn->cleared_wrt_p($self)) {
- $cleared_balance_diff -= ($credit - $debit);
- }
- $diff += $local_change;
- $$entry[1] = $new_value;
- $next_mod_txn = shift @mod_txns;
- push @modified_indices, $current_index;
- } elsif ($started_mods) {
- $$entry[1] += $diff;
- }
- $prev_ledger_value = $$entry[1];
- $current_index++;
- }
- $self->set_cleared_balance_($self->get_cleared_balance() +
- $cleared_balance_diff);
- }
- my $final = $$ledger[$#$ledger];
- $self->set_final_balance_($$final[1]);
- return (\@modified_indices, \@moves);
-}
-
-sub ledger_remove_txns_ {
- my($self, $txns) = @_;
- # presumes @$txns is sorted on date to match the database order.
- # returns a list where each item is [$txn, $old_index].
-
- my $ledger = $self->get_ledger_();
- if(!$ledger) {
- return;
- }
-
- # Globals, yuck...
- $ledger_removal_diff = 0;
- $cleared_balance_diff_tmp = 0;
- $started_mods_p = 0;
- $mods_acct = $self;
-
- my $removed_indices =
- main::destructive_remove_mangle($ledger,
- $txns,
- \&match_ledger_and_txn_,
- \&handle_ledger_entry_removal_);
-
- print STDERR
- "Finished removing ledger items (" . join(" ", @$removed_indices) .
- ")\n";
-
- $self->set_cleared_balance_($self->get_cleared_balance() +
- $cleared_balance_diff_tmp);
- my $final = $$ledger[$#$ledger];
- $self->set_final_balance_($$final[1]);
-
- my @txns_tmp = @$txns;
- my @result = map {
- my $txn = shift @txns_tmp;
- [$_, $txn];
- } @$removed_indices;
- return(\@result);
-}
-
-
-package CBBlib::Acct;
-use strict;
-use English;
-use IO;
-
-use vars qw(@ISA);
-unshift @ISA, qw(CBBlib::Sink);
-
-sub new {
- my $class = shift;
- my ($db, $name, $notes) = @_;
- my $self = make_internals_();
- bless $self, $class;
-
- $self->set_db_($db);
- $self->set_name_($name);
- $self->set_notes_($notes);
-
- return $self;
-}
-
-sub print {
- my($self, $fh, $prefix, $id_map) = @_;
- my $name = $self->get_name();
- my $notes = $self->get_notes();
- $notes = "" if ! $notes;
- $prefix = "" unless $prefix;
- if($id_map) {
- print $fh $prefix . $$id_map{$self} . "\t$name\t$notes\n";
- } else {
- print $fh $prefix . "$self\t$name\t$notes\n";
- }
-}
-
-
-package CBBlib::Cat;
-use strict;
-use English;
-use IO;
-
-use vars qw(@ISA);
-unshift @ISA, qw(CBBlib::Sink);
-
-sub new {
- my $class = shift;
- my ($db, $name, $notes) = @_;
- my $self = make_internals_();
- bless $self, $class;
-
- $self->set_db_($db);
- $self->set_name_($name);
- $self->set_notes_($notes);
-
- return $self;
-}
-
-sub print {
- my($self, $fh, $prefix, $id_map) = @_;
- my $name = $self->get_name();
- my $notes = $self->get_notes();
- $notes = "" if ! $notes;
- $prefix = "" unless $prefix;
- if($id_map) {
- print $fh $prefix . $$id_map{$self} . "\t$name\t$notes\n";
- } else {
- print $fh $prefix . "$self\t$name\t$notes\n";
- }
-}
-
-package CBBlib::Txn;
-use strict;
-use English;
-use IO;
-
-sub new {
- my $class = shift;
- my ($date, $source, $checkno, $desc, $status) = @_;
- $status = "" if !$status;
-
- my $self = make_internals_();
- bless $self, $class;
-
- $self->set_date_($date);
-
- die "CBBlib::Txn new: source must be a CBBlib::Acct."
- unless (ref($source) eq 'CBBlib::Acct');
-
- $self->set_source_($source);
-
- $self->set_checkno_($checkno);
- $self->set_desc_($desc);
- $self->set_status_($status);
-
- return $self;
-}
-
-
-sub make_clone_ {
- my ($self) = @_;
-
- my $clone = $self->get_clone_();
- if(!$clone) {
- $self->set_clone_($self->copy_obj_());
- $clone = $self->get_clone_();
- }
- return $clone;
-}
-
-
-
-
-# All the set/get slot functions are in CBBlib-auto.pl.
-
-# "" = irrelevant (for split line with category destination)
-# " " = new and untouched
-# "*" = selected from the balance window to tentatively be
-# cleared (stage one of the balance process)
-# "x" = cleared (stage two of the balance process)
-#
-# "?" = a tentative future (recurring) transaction
-# "!" = a past (recurring) transaction
-
-sub get_status_wrt {
- my($self, $sink) = @_;
- my $result;
- if($self->get_source() == $sink) {
- $result = $self->get_status();
- } else {
- $result = $self->get_transfer_status($sink);
- }
- if(!defined($result)) {
- print STDERR "Undefined status wrt $sink for\n";
- $self->print(\*STDERR, " ");
- }
- return $result;
-}
-
-sub set_status_wrt_ {
- my($self, $sink, $val) = @_;
- if($self->get_source() == $sink) {
- $self->set_status($val);
- } else {
- $self->set_transfer_status_($sink, $val);
- }
-}
-
-sub copy_obj_ {
- my($self) = shift;
-
- my @copy = @$self;
- my $copy_ref = \@copy;
- bless $copy_ref, ref($self);
-
- my $splits = $copy_ref->get_splits_();
-
- # Copy only the spine of the list (so we can do a "diff" later).
- my @splits_copy = @$splits;
-
- $copy_ref->set_splits_(\@splits_copy);
- return $copy_ref;
-}
-
-
-sub get_transfer_status {
- my($self, $sink) = @_;
- my $splits = $self->get_splits_();
- my $result;
- my $split;
- foreach $split (@$splits) {
- if($split->get_dest() == $sink) {
- $result = $split;
- last;
- }
- }
- undef $split;
-
- if(!$result) {
- return undef;
- } else {
- return $result->get_status();
- }
-}
-
-
-sub set_transfer_status_ {
- my($self, $acct, $new_status) = @_;
- my $splits = $self->get_splits_();
- my $result;
- my $split;
- foreach $split (@$splits) {
- my $dest = $split->get_dest();
- if($split->get_dest() == $acct) {
- $split->set_status($new_status);
- }
- }
-}
-
-sub cleared_p_ {
- my($self) = @_;
- return $self->get_status() eq 'x';
-}
-
-sub cleared_wrt_p {
- my($self, $acct) = @_;
- return $self->get_status_wrt($acct) eq 'x';
-}
-
-sub clear_wrt {
- my($self, $acct) = @_;
- $self->set_status_wrt_($acct, 'x');
-}
-
-sub clear_pending_wrt_p {
- my($self, $acct) = @_;
- return $self->get_status_wrt($acct) eq '*';
-}
-
-sub clear_pending_wrt {
- my($self, $acct) = @_;
- $self->set_status_wrt_($acct, '*');
-}
-
-sub uncleared_wrt_p {
- my($self, $acct) = @_;
- return $self->get_status_wrt($acct) eq ' ';
-}
-
-sub unclear_wrt {
- my($self, $acct) = @_;
- $self->set_status_wrt_($acct, ' ');
-}
-
-sub void {
- # ???
-}
-
-sub add_split {
- my($self, $split, $insert_position) = @_;
-
- # Don't forget to change modify functions in CBBlib-auto.plp too
- # whenever you make changes here.
-
- my $splits;
-
- $split->set_txn_($self);
-
- my $db = $self->get_db();
- if($db) {
-
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $splits = $clone->get_splits_();
-
- if($insert_position) {
- splice @$splits, $insert_position, 0, ($split);
- } else {
- push @$splits, $split;
- $insert_position = $#$splits;
- }
- } else {
- $splits = $self->get_splits_();
-
- if($insert_position) {
- splice @$splits, $insert_position, 0, ($split);
- } else {
- push @$splits, $split;
- $insert_position = $#$splits;
- }
- }
-
- my $i;
- for($i = $insert_position; $i < scalar(@$splits); $i++) {
- $$splits[$i]->set_pos_($i);
- }
-
- if($db) {
- $db->record_txn_modification_($self);
- $db->end_txn_modifications();
- }
-}
-
-sub remove_split {
- my($self, $split) = @_;
-
- # Don't forget to change modify functions in CBBlib-auto.plp too
- # whenever you make changes here.
-
- my $db = $self->get_db();
- my $splits;
- if($db) {
- $db->begin_txn_modifications();
-
- my $clone = $self->make_clone_();
- $splits = $clone->get_splits_();
- } else {
- $splits = $self->get_splits_();
- }
-
- my $old_index = 0;
- my $split_found = 0;
- my $candidate;
- foreach $candidate (@$splits) {
- if($candidate == $split) {
- $split_found = 1;
- last;
- }
- $old_index++;
- }
- if(!$split_found) {
- die "Failed to find split in Txn::remove_split";
- }
- splice @$splits, $old_index, 0;
-
- my $i;
- for($i = $old_index; $i < scalar(@$splits); $i++) {
- $$splits[$i]->set_pos_($i);
- }
-
- if($db) {
- my $txn = $split->get_txn_();
- $split->set_txn_(undef);
- $db->record_txn_modification_($txn);
- $db->end_txn_modifications();
- }
-}
-
-sub totals_wrt {
- my($self, $sink) = @_;
- # O(n)
- # Returns (total_debit, total_credit, applicable)
-
- my($total_debit, $total_credit, $applicability) = (0, 0, 0);
- my $splits = $self->get_splits_();
-
- my $split;
- foreach $split (@$splits) {
- my $dest = $split->get_dest();
-
- if($self->get_source() == $sink) {
- $total_debit += $split->get_debit();
- $total_credit += $split->get_credit();
- $applicability = 1;
- } elsif($dest == $sink) {
- #} elsif((ref($dest) eq 'CBBlib::Acct') && ($dest == $sink)) {
- $total_debit += $split->get_credit();
- $total_credit += $split->get_debit();
- $applicability = 1;
- }
- }
- return($total_debit, $total_credit, $applicability);
-}
-
-
-sub affected_sinks {
- my($self) = @_;
- # O(n)
- # Returns list of affected sinks
-
- my $source = $self->get_source();
- my %result = ($source => $source);
- my $splits = $self->get_splits_();
-
- map {
- my $dest = $_->get_dest();
- if(!$dest) {
- die "\nNo dest in $_\n";
- }
- $result{$dest} = $dest;
- } @$splits;
- return(values(%result));
-}
-
-
-sub print {
- my($self, $fh, $prefix, $id_map) = @_;
- $prefix = "" if ! $prefix;
-
- print $fh $prefix . $self->get_date() . "\t";
- if($id_map) {
- print $fh $$id_map{$self->get_source()} . "\t";
- } else {
- print $fh $self->get_source() . "\t";
- }
- print $fh $self->get_checkno() . "\t";
- print $fh $self->get_desc() . "\t";
- print $fh $self->get_status() . "\n";
- my $splits = $self->get_splits_();
- my $split;
- foreach $split (@$splits) {
- $split->print($fh, $prefix . ' ', $id_map);
- }
-}
-
-sub print_pretty {
- my($self, $fh, $prefix) = @_;
- $prefix = "" if ! $prefix;
-
- print $fh $prefix . $self->get_date() . ":";
- print $fh ($self->get_source())->get_name() . ":";
- print $fh $self->get_checkno() . ":";
- print $fh $self->get_desc() . ":";
- print $fh $self->get_status() . "\n";
- my $splits = $self->get_splits_();
- my $split;
- foreach $split (@$splits) {
- $split->print_pretty($fh, $prefix . " ");
- }
-}
-
-package CBBlib::Split;
-use strict;
-use English;
-use IO;
-
-sub new {
- my $class = shift;
- my ($dest, $notes, $debit, $credit, $status) = @_;
- my $self = make_internals_();
- bless $self, $class;
-
- $status = '' if ! $status;
-
- $self->set_dest_($dest);
- $self->set_notes_($notes);
- $self->set_debit_($debit);
- $self->set_credit_($credit);
- $self->set_status_($status);
-
- return $self;
-}
-
-sub copy_obj_ {
- my($self) = shift;
-
- my @copy = @$self;
- my $copy_ref = \@copy;
- bless $copy_ref, ref($self);
- return $copy_ref;
-}
-
-sub make_clone_ {
- my ($self) = @_;
-
- my $clone = $self->get_clone_();
- if(!$clone) {
- my $txn = $self->get_txn_();
- if($txn) {
- $txn->make_clone_();
- }
- $self->set_clone_($self->copy_obj_());
- $clone = $self->get_clone_();
- }
- return $clone;
-}
-
-sub get_db {
- my $self = shift;
- my $txn = $self->get_txn();
- if($txn) {
- return $txn->get_db();
- } else {
- return undef;
- }
-}
-
-sub cleared_p_ {
- my($self) = @_;
- my $status = $self->get_status();
- if($status) {
- return $status eq 'x';
- } else {
- return undef;
- }
-}
-
-
-sub print {
- my($self, $fh, $prefix, $id_map) = @_;
- $prefix = "" if ! $prefix;
-
- print $fh $prefix;
- if($id_map) {
- print $fh $$id_map{$self->get_dest()} . "\t";
- } else {
- print $fh $self->get_dest() . "\t";
- }
- print $fh $self->get_notes() . "\t";
- print $fh $self->get_debit() . "\t";
- print $fh $self->get_credit() . "\t";
- print $fh $self->get_status() . "\n";
-}
-
-
-package CBBlib::Db;
-use strict;
-use English;
-use IO;
-
-sub new {
- my($class, $default_sink) = @_;
- my $self = make_internals_();
- bless $self, $class;
-
- if($default_sink) {
- $self->add_sinks([$default_sink]);
- } else {
- $default_sink = new CBBlib::Cat($self, '<<unitemized>>', '');
- $self->add_sinks([$default_sink]);
- }
- $self->set_default_sink($default_sink);
-
- return $self;
-}
-
-sub clean_p {
- # Should eventually know the truth, but this is safe at the moment.
- return 0;
-}
-
-sub add_sinks {
- my($self, $sinks) = @_;
-
- my $accts = $self->get_accts_();
- my $cats = $self->get_cats_();
- map {
- $_->set_db_($self);
- if(ref($_) eq 'CBBlib::Acct') {
- push @$accts, $_;
- } elsif(ref($_) eq 'CBBlib::Cat') {
- push @$cats, $_;
- } else {
- die "Unknown sink type in CBBlib::Db::add_sinks()";
- }
- } @$sinks;
-}
-
-sub record_txn_modification_ {
- my($self, $txn) = @_;
-
- my $mod_level = $self->get_modified_txns_level_();
- if(!$mod_level) {
- die "Tried to record_txn_modification_ when not in update region.";
- }
- my $modified_txns = $self->get_modified_txns_();
- #my $serial_number = $self->get_modified_txns_serial_num_();
- #$self->set_modified_txns_serial_num_($serial_number + 1);
-
- if(ref($txn) eq 'CBBlib::Split') {
- $txn = $txn->get_txn_();
- }
- $$modified_txns{$txn} = $txn;
-}
-
-sub update_dirty_txns_hash_ {
- my($self, $dirty_hash, $txn) = @_;
-
- my @affected_sinks = $txn->affected_sinks();
-
- map {
- my $sink = $_;
- if(!$$dirty_hash{$sink}) {
- $$dirty_hash{$sink} = [$sink, [$txn]];
- } else {
- my $list = $$dirty_hash{$sink};
- $list = $$list[1];
- push @$list, $txn;
- }
- } @affected_sinks;
-}
-
-
-sub debug_txns_modified_data {
- my($self, $modifications, $dirty_sinks) = @_;
- CBBlib::debug("CBBlib CALLBACK: txns-modified\n");
-
- CBBlib::debug(" Modifications:\n");
- map {
- my $txn = $$_[0];
- my $mods = $$_[1];
- CBBlib::debug(" [$txn");
- map {
- CBBlib::debug("\n [");
- my $first = 1;
- map {
- if($first) {
- $first = 0;
- } else {
- print " ";
- }
- if(!defined($_)) {
- print "<<undefined>>";
- } else {
- print $_;
- }
- } @$_;
- CBBlib::debug("]");
- } @$mods;
- CBBlib::debug("]\n");
- } @$modifications;
-
- CBBlib::debug(" Affected sinks:\n");
- map {
- my ($sink, $mod_txns, $indices) = @$_;
- $sink->print(\*STDERR, " ");
- } values(%$dirty_sinks);
-}
-
-
-sub post_modification_notices_ {
- my $self = shift;
- CBBlib::debug("CBBlib::post_modification_notices_: checking for changes.\n");
-
- my $modified_txns_hash = $self->get_modified_txns_();
- my @sorted_txns = sort {
- $a->get_date <=> $b->get_date();
- } values(%$modified_txns_hash);
- my @modifications = ();
-
- # Have to treat credit/debit mods the same as other field mods since
- # in the end we need the ledger indices of all the txns.
- my %dirty_sinks;
-
- # This is not the most efficient way to go about this, but it's
- # easy, and I'm in a hurry. Someone can make it do the merge/remove
- # mangle thing later. Be careful, though, you don't want to cause
- # spurious add/remove events.
- my $date_changed;
- my %txn_date_changed;
-
- # generate modified events for each transaction
- my $txn;
- foreach $txn (@sorted_txns) {
- my $new_txn = $txn->get_clone_();
- my $old_splits = $txn->get_splits_();
- my $new_splits = $new_txn->get_splits_();
- my @txn_mods = ();
-
- my $i;
- for($i=0; $i < scalar(@$old_splits); $i++) {
- my $old_item = $$old_splits[$i];
- if(! grep { $_ == $old_item } @$new_splits) {
- my $old_index = $i;
- push @txn_mods, ['split-removed', $old_item, $old_index];
- }
- }
-
- for($i=0; $i < scalar(@$new_splits); $i++) {
- my $new_item = $$new_splits[$i];
- if(! grep { $_ == $new_item } @$old_splits) {
- my $new_index = $i;
- push @txn_mods, ['split-added', $new_item, $new_index];
- }
- }
-
- # This could be much faster with a better algorithm.
- my @modified_splits = grep { $_->get_clone_() } @$new_splits;
-
- if($new_txn->get_date_ ne $txn->get_date_()) {
- push @txn_mods, ['date', $txn->get_date_()];
- $txn->set_date_($new_txn->get_date_());
- $date_changed = 1;
- $txn_date_changed{$txn} = $txn;
- }
- if($new_txn->get_checkno_ ne $txn->get_checkno_()) {
- push @txn_mods, ['checkno', $txn->get_checkno_()];
- $txn->set_checkno_($new_txn->get_checkno_());
- }
- if($new_txn->get_desc_ ne $txn->get_desc_()) {
- push @txn_mods, ['desc', $txn->get_desc_()];
- $txn->set_desc_($new_txn->get_desc_());
- }
- if($new_txn->get_status_ ne $txn->get_status_()) {
- push @txn_mods, ['status', $txn->get_status_()];
- $txn->set_status_($new_txn->get_status_());
- }
-
- my $split;
- foreach $split (@modified_splits) {
- my $new_split = $split->get_clone_();
-
- my $old_txn = $split->get_txn();
- if(defined($old_txn) && ($old_txn == $new_split->get_txn())) {
- # This is really a modification to an existing split (is that
- # what this test should be doing)?
-
- my $old_pos = $split->get_pos__();
- my $new_pos = $new_split->get_pos__();
- if((defined($new_pos) != defined($old_pos)) ||
- ($new_pos != $old_pos)) {
- push @txn_mods, ['split-modified', $split, 'pos',
- $split->get_pos__()];
- $split->set_pos__($new_split->get_pos__());
- }
- if($new_split->get_dest_ != $split->get_dest_()) {
- push @txn_mods, ['split-modified', $split, 'dest',
- $split->get_dest_()];
- $split->set_dest_($new_split->get_dest_());
- }
- if($new_split->get_notes_ ne $split->get_notes_()) {
- push @txn_mods, ['split-modified', $split, 'notes',
- $split->get_notes_()];
- $split->set_notes_($new_split->get_notes_());
- }
- if($new_split->get_debit_ != $split->get_debit_()) {
- push @txn_mods, ['split-modified', $split, 'debit',
- $split->get_debit_()];
- $split->set_debit_($new_split->get_debit_());
- }
- if($new_split->get_credit_ != $split->get_credit_()) {
- push @txn_mods, ['split-modified', $split, 'credit',
- $split->get_credit_()];
- $split->set_credit_($new_split->get_credit_());
- }
- if($new_split->get_status_ ne $split->get_status_()) {
- push @txn_mods, ['split-modified', $split, 'status',
- $split->get_status_()];
- $split->set_status_($new_split->get_status_());
- }
- }
- $split->set_clone_(undef);
- }
- $txn->set_splits_($new_splits);
- $txn->set_clone_(undef);
-
- if(@txn_mods) {
- $self->update_dirty_txns_hash_(\%dirty_sinks, $txn);
- push @modifications, [ $txn, \@txn_mods ];
- }
- }
-
- # Re-sort if needed, so the positions will be right for the next
- # steps.
- if($date_changed) {
- print STDERR "Re-sorting txns\n";
- my $txns = $self->get_txns();
- @$txns = sort {
- $a->get_date <=> $b->get_date();
- } @$txns;
- }
-
- # Act on dirty ledgers hash.
- my $acct_data;
- foreach $acct_data (values %dirty_sinks) {
- my $acct = $$acct_data[0];
- my $acct_txns = $$acct_data[1];
- my ($txn_indices, $moves) =
- $acct->ledger_modify_txns_(\%txn_date_changed,
- $acct_txns);
- push @$acct_data, $txn_indices, $moves;
- }
-
- if(@modifications) {
-
- debug_txns_modified_data($self, \@modifications, \%dirty_sinks);
-
- # txns-modified callback
- my $callbacks_hash = $self->get_callbacks_hash_();
- my $callbacks = $$callbacks_hash{'txns-modified'};
- my $callback;
- foreach $callback (@$callbacks) {
- my $func = $$callback[0];
- my $args = $$callback[1];
-
- # @modifications elements are of the form
- # [ $txn, [ mod, mod, mod, ...]]
-
- # %dirty_sinks
- # Key: $sink
- # Value: [ $sink, @$txns, @$current_indices, @$moves]
- # where @$moves is a ref to a list of pairs
- # of the form [$prev_pos, $new_pos] sorted on $prev_pos
-
- &$func($self, \@modifications, \%dirty_sinks, $args);
-
- }
- }
-}
-
-
-sub begin_txn_modifications {
- my ($self) = shift;
- my $mod_level = $self->get_modified_txns_level_();
- if(!$mod_level) {
- $self->set_modified_txns_({});
- #$self->set_modified_txns_serial_num_(0);
- }
- $self->set_modified_txns_level_($mod_level + 1);
-}
-
-sub end_txn_modifications {
- my ($self) = shift;
- my $mod_level = $self->get_modified_txns_level_();
- if($mod_level == 1) {
- $self->post_modification_notices_();
- } elsif(!$mod_level) {
- die
- "Big problem. Db::end_txn_modifications called when not modifying.\n";
- }
- $self->set_modified_txns_level_($mod_level - 1);
-}
-
-sub get_accts_by_name {
- my($self, $name) = @_;
- my $accts = $self->get_accts();
- my @matches = grep {
- if($_) {
- $_->get_name() eq $name;
- } else {
- 0;
- }
- } @$accts;
- return \@matches;
-}
-
-sub get_cats_by_name {
- my($self, $name) = @_;
- my $cats = $self->get_cats();
- my @matches = grep {
- if($_) {
- $_->get_name() eq $name;
- } else {
- 0;
- }
- } @$cats;
- return \@matches;
-}
-
-sub extract_accounts_ {
- my($text, $hash) = @_;
- my @accounts = split("\n", $text);
- return map {
- my $acct = $_;
- my @fields = split("\t", $acct);
- (scalar(@fields) < 4) or die "Wrong number of fields in account.";
-
- my $name = $fields[1];
- my $notes = $fields[2];
- $acct = new CBBlib::Acct(undef, $name, $notes);
- $$hash{$fields[0]} = $acct;
- $acct;
- } @accounts;
-}
-
-sub extract_categories_ {
- my($text, $hash) = @_;
- my @categories = split("\n", $text);
- return map {
- my $cat = $_;
- my @fields = split("\t", $cat);
- (scalar(@fields) < 4) or die "Wrong number of fields in category.";
-
- my $name = $fields[1];
- my $notes = $fields[2];
- $cat = new CBBlib::Cat(undef, $name, $notes);
- $$hash{$fields[0]} = $cat;
- $cat;
- } @categories;
-}
-
-sub calc_account_totals_only_ {
- my($self) = @_;
- my $transactions = $self->get_txns();
- my $accts = $self->get_accts();
- map {
- if($_) {
- $_->set_cleared_balance_(0);
- $_->set_final_balance_(0);
- }
- } @$accts;
-
- #my $cleared_balance = 0;
- #my $final_balance = 0;
-
- my $txn;
- foreach $txn (@$transactions) {
- my $splits = $txn->get_splits_();
-
- my $split;
- foreach $split (@$splits) {
-
- my $source = $txn->get_source();
- my $dest = $split->get_dest();
- my $debit = $split->get_debit();
- my $credit = $split->get_credit();
-
- my $cleared_bal;
- my $final_bal;
- my $diff = $credit - $debit;
-
- if($txn->cleared_p_()) {
- $cleared_bal = $source->get_cleared_balance() + $diff;
- $source->set_cleared_balance_($cleared_bal);
- }
- $final_bal = $source->get_final_balance() + $diff;
- $source->set_final_balance_($final_bal);
-
- if(ref($dest) eq 'CBBlib::Acct' && ($source != $dest)) {
- if($split->cleared_p_()) {
- $cleared_bal = $dest->get_cleared_balance();
- $dest->set_cleared_balance_($cleared_bal - $diff);
- }
- $final_bal = $dest->get_final_balance() - $diff;
- $dest->set_final_balance_($final_bal);
- }
- }
- }
-}
-
-
-sub add_callback_ {
- my($self, $name, $callback, $user_data) = @_;
- my $data = [$callback, $user_data];
- my $callbacks_hash = $self->get_callbacks_hash_();
- my $txn_callbacks = $$callbacks_hash{$name};
- if(!$txn_callbacks) {
- $$callbacks_hash{$name} = [];
- $txn_callbacks = $$callbacks_hash{$name};
- }
- push @$txn_callbacks, $data;
- return $data;
-}
-
-sub remove_callback_ {
- my($self, $name, $callback_id) = @_;
- my $callbacks_hash = $self->get_callbacks_hash_();
- my $callbacks = $$callbacks_hash{$name};
- if(scalar(@$callbacks)) {
- @$callbacks = grep { !($_ == $callback_id) } @$callbacks;
- }
-}
-
-# add_txn_callback
-# Called whenever new transactions are added
-# Called with args ($db, $new_txns, $user_data)
-
-sub add_txns_added_callback {
- my($self, $callback, $user_data) = @_;
- return $self->add_callback_('txns-added', $callback, $user_data);
-}
-
-
-sub remove_txns_added_callback {
- my($self, $callback_id) = @_;
- $self->remove_callback_('txns-added', $callback_id);
-}
-
-
-# add_txn_callback
-# Called whenever new transactions are added
-# Called with args ($db, $dead_txns, $user_data)
-
-sub add_txns_removed_callback {
- my($self, $callback, $user_data) = @_;
- return $self->add_callback_('txns-removed', $callback, $user_data);
-}
-
-
-sub remove_txns_removed_callback {
- my($self, $callback_id) = @_;
- $self->remove_callback_('txns-removed', $callback_id);
-}
-
-sub add_txns_modified_callback {
- my($self, $callback, $user_data) = @_;
- return $self->add_callback_('txns-modified', $callback, $user_data);
-}
-
-sub remove_txns_modified_callback {
- my($self, $callback_id) = @_;
- $self->remove_callback_('txns-modified', $callback_id);
-}
-
-sub merge_new_txns_into_main_list_ {
- my($self, $new_txns) = @_;
- my $txns = $self->get_txns();
-
- my $added_indices =
- main::destructive_merge_mangle($txns, $new_txns, sub {
- return $_[0]->get_date() cmp $_[1]->get_date();
- });
-
- map { $_->set_db_($self); } @$new_txns;
-
- my %affected_sinks;
- my $txn;
- foreach $txn (@$new_txns) {
- my @accts = $txn->affected_sinks();
- my $acct;
- foreach $acct (@accts) {
- my $data = $affected_sinks{$acct};
- if(!$data) { $data = $affected_sinks{$acct} = [$acct, []]; }
- my $list = $$data[1];
- push @$list, $txn;
- }
- }
-
- return (\%affected_sinks, $added_indices);
-}
-
-sub merge_new_txns_into_ledger_lists_ {
- my($self, $new_txns, $affected_accts) = @_;
-
- # $affected accts is a hash mapping accounts to [acct,
- # relevant_txns] acct is a ref to the account, and relevant txns is
- # a ref to a list of the relevant transactions. The transactions
- # must be ordered in each list like they are in the global DB.
-
- # We're going to add the resulting new ledger indices to the hash
- # values so we have: [acct, relevant_txns, indices]
-
- my $data;
- foreach $data (values(%$affected_accts)) {
- my $acct_ref = $$data[0];
- my $txns = $$data[1];
- my $added_indices = $acct_ref->ledger_add_txns_($txns);
- push @$data, $added_indices;
- }
-}
-
-sub add_txns {
- my($self, $new_txns) = @_;
-
- @$new_txns = sort {
- $a->get_date() <=> $b->get_date();
- } @$new_txns;
-
- my ($affected_accts, $added_indices) =
- $self->merge_new_txns_into_main_list_($new_txns);
-
- $self->merge_new_txns_into_ledger_lists_($new_txns, $affected_accts);
-
- my $callbacks_hash = $self->get_callbacks_hash_();
- my $txn_callbacks = $$callbacks_hash{'txns-added'};
- my $callback;
- foreach $callback (@$txn_callbacks) {
- my $func = $$callback[0];
- my $args = $$callback[1];
-
- if($main::pref_debug) {
- print STDERR
- "(txns-added\n" .
- " db: $self\n" .
- ' added-indices: (' . join("\n" .
- ' ', @$added_indices) . ")\n" .
- " (affected-accts\n";
- my $acct_data;
- foreach $acct_data (values(%$affected_accts)) {
- my $acct = $$acct_data[0];
- my $txns = $$acct_data[1];
- my $indices = $$acct_data[2];
- print STDERR
- " acct: $acct\n" .
- ' txns: (' . join("\n" .
- ' ', @$txns) . ")\n" .
- ' indices: (' . join("\n" .
- ' ', @$indices) . ")\n";
- }
- CBBlib::debug(' args: ' . $args . "))\n");
- }
- &$func($self, $added_indices, $affected_accts, $args);
- }
-}
-
-sub remove_txns_from_ledger_lists_ {
- my($self, $dead_txns, $affected_accts) = @_;
- # $affected accts is a hash mapping accounts to refs to lists
- # of relevant transactions. The transactions must be ordered
- # in each list like they are in the global DB.
-
- # returns a hash from $sink to a listref of [$sink, @$txn_info] where
- # @$txn_info is a lists of [$txn, $prev_ledger_index] pairs
-
- my %result;
-
- my $acct;
- foreach $acct (keys(%$affected_accts)) {
- my $data = $$affected_accts{$acct};
- my $acct_ref = $$data[0];
- my $txns = $$data[1];
- my $removal_info = $acct_ref->ledger_remove_txns_($txns);
- $result{$acct} = [$acct, $removal_info];
- }
- return \%result;
-}
-
-sub remove_txns_from_main_list_ {
- my($self, $dead_txns) = @_;
- my $txns = $self->get_txns();
-
- my $removed_indices =
- main::destructive_remove_mangle($txns, $dead_txns, sub {
- return $_[0] == $_[1];
- });
-
- map { $_->set_db_($self); } @$dead_txns;
-
- my %affected_accts;
- my $txn;
- foreach $txn (@$dead_txns) {
- my @accts = $txn->affected_sinks();
- my $acct;
- foreach $acct (@accts) {
- my $data = $affected_accts{$acct};
- if(!$data) { $data = $affected_accts{$acct} = [$acct, []]; }
- my $list = $$data[1];
- push @$list, $txn;
- }
- }
-
- return (\%affected_accts, $removed_indices);
-}
-
-sub remove_txns {
- my($self, $dead_txns) = @_;
-
- @$dead_txns = sort {
- $a->get_date() cmp $b->get_date();
- } @$dead_txns;
-
- my ($affected_accts, $removed_db_indices) =
- $self->remove_txns_from_main_list_($dead_txns);
-
- my $ledger_removal_info =
- $self->remove_txns_from_ledger_lists_($dead_txns, $affected_accts);
-
- my $callbacks_hash = $self->get_callbacks_hash_();
- my $txn_callbacks = $$callbacks_hash{'txns-removed'};
- my $callback;
- foreach $callback (@$txn_callbacks) {
- my $func = $$callback[0];
- my $args = $$callback[1];
- &$func($self, $dead_txns,
- $removed_db_indices,
- $ledger_removal_info,
- $args);
- }
-}
-
-sub print_sinks {
- my ($self, $fh, $id_map) = @_;
-
- print $fh "#### Accounts ####\n";
- my $accts = $self->get_accts();
- map { $_->print($fh, '', $id_map); } @$accts;
- undef $accts;
- print $fh "\n";
-
- print $fh "#### Categories ####\n";
- my $cats = $self->get_cats();
- map { $_->print($fh, '', $id_map); } @$cats;
- undef $cats;
- print $fh "\n";
-}
-
-sub print_txns {
- my ($self, $fh, $id_map) = @_;
- print $fh "#### Transactions ####\n\n";
- my $txns = $self->get_txns();
- my $txn;
- foreach $txn (@$txns) {
- $txn->print($fh, '',$id_map);
- print $fh "\n";
- }
-}
-
-sub print {
- my($self, $fh) = @_;
-
- my %id_map;
- my $i = 0;
- my $accts = $self->get_accts();
- map {
- $id_map{$_} = "a$i";
- $i++;
- } @$accts;
- $i = 0;
- my $cats = $self->get_cats();
- map {
- $id_map{$_} = "c$i";
- $i++;
- } @$cats;
-
- print $fh "# CBB data file\n";
- print $fh "Version: 1.0\n";
- print $fh 'Default-sink: ' . $id_map{$self->get_default_sink()} . "\n";
- print $fh "\n";
-
- $self->print_sinks($fh, \%id_map);
- $self->print_txns($fh, \%id_map);
-}
-
-package CBBlib;
-
-sub key_colon_value_to_hash {
- my($text) = @_;
- # Assumes comment lines have already been stripped.
-
- my @lines = split("\n", $text);
- my %data;
-
- map {
- if($_ =~ m/\s*([^:]+):\s*(.*)$/o) {
- $data{$1} = $2;
- } else {
- die 'Bad line in database file, first "key: value" section.';
- }
- } @lines;
- return \%data;
-}
-
-sub load_file {
- # Args (filename:<string>)
-
- elapsed_reset("Starting load");
- my $name = shift;
- my $categories;
- my $accounts;
- my @transactions = ();
- my $fh = new IO::File;
- my $file;
-
- $fh->open($name) or die "Can't open input data file $file.";
- $fh->input_record_separator('');
-
- # Get the initial key/value pairs.
- my $text = <$fh>;
- $text =~ s/#.*//mgo; # Kill comment lines.
- $text =~ s/^\n//mgo; # Kill blank lines.
- my $file_data = key_colon_value_to_hash($text);
-
- die "Couldn't determine data file version"
- unless $$file_data{'Version'};
- die "Couldn't find default sink in $text."
- unless $$file_data{'Default-sink'};
-
- my %sink_map = ();
-
- # Get accounts
- $text = <$fh>;
- $text =~ s/#.*\n//mgo; # Kill comment lines.
- my @sinks = CBBlib::Db::extract_accounts_($text, \%sink_map);
-
- # Get categories
- $text = <$fh>;
- $text =~ s/#.*\n//mgo; # Kill comment lines.
- push @sinks, CBBlib::Db::extract_categories_($text, \%sink_map);
-
- my $default_sink = $sink_map{$$file_data{'Default-sink'}};
- die "Default sink " . $$file_data{'Default-sink'} .
- " not in database file." unless $default_sink;
-
- my $self = new CBBlib::Db($default_sink);
-
- $self->add_sinks(\@sinks);
-
-
- my @new_txns = ();
-
- # Read the "Transactions" comment line.
- scalar(<$fh>);
-
- my $count = 1;
- while(<$fh>) {
- print "\rLoading record $count";
- $count++;
-
- my @lines = split('\n', $_);
- my $transaction_info = shift @lines;
- my($date, $source, $checknum, $description, $status) =
- split("\t", $transaction_info);
- $source = $sink_map{$source};
-
- if(!defined($status) || $status eq '') { $status = ' '; }
-
- my $transaction =
- new CBBlib::Txn($date, $source, $checknum, $description, $status);
-
- # @lines is now just the split lines
- my $split_line;
- foreach $split_line (@lines) {
- $split_line =~ s/^\s*//o;
- my($destination, $note, $debit, $credit, $status) =
- split("\t", $split_line);
- if($destination) {
- my $old_dest = $destination;
- $destination = $sink_map{$destination};
- if(!$destination) {
- die "No destination for key [$old_dest]\n";
- }
- } else {
- $destination = $self->get_default_sink();
- }
-
- $transaction->add_split(new CBBlib::Split($destination, $note,
- $debit, $credit, $status));
- }
- push @new_txns, $transaction;
- }
- print "\n";
- elapsed();
- elapsed_reset(" Now adding transactions");
- $self->add_txns(\@new_txns);
- elapsed();
- elapsed_reset(" Calculating totals");
- $self->calc_account_totals_only_();
- elapsed();
- $fh->close() or die "Can't open close file $name.";
- print STDERR "finished load\n";
-
- return $self;
-}
-
-1;
-__END__
-## @endcond Perl
diff --git a/src/experimental/cbb/cbb-engine/Makefile.am b/src/experimental/cbb/cbb-engine/Makefile.am
deleted file mode 100644
index dd27967..0000000
--- a/src/experimental/cbb/cbb-engine/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-
-EXTRA_DIST = \
- CBBlib-auto.pl \
- CBBlib-auto.plp \
- CBBlib.pl \
- common.pl
diff --git a/src/experimental/cbb/cbb-engine/common.pl b/src/experimental/cbb/cbb-engine/common.pl
deleted file mode 100644
index b124091..0000000
--- a/src/experimental/cbb/cbb-engine/common.pl
+++ /dev/null
@@ -1,478 +0,0 @@
-#!/usr/bin/perl -w
-# common.pl - common routines shared by many CBB files
-#
-# Written by Curtis Olson. Started August 22, 1994.
-#
-# Copyright (C) 1994 - 1997 Curtis L. Olson - curt at sledge.mn.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, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# $Id$
-# (Log is kept at end of this file)
-
-## @file
-# @brief common routines shared by many CBB files
-# @author Curtis Olson
-# @date Started August 22, 1994
-# @cond PERL
-# ignore the following for doxygen
-
-use strict;
-
-sub destructive_merge_mangle {
- my($destination_ref, $source_ref, $comparison, $mangler) = @_;
- # Merges elements of destination into source according to the
- # comparison function. Assumes that both source and destination
- # are already sorted wrt comparison.
-
- # mangler is optional, but if provided will be called for each
- # element of the modified destination with the args
- # ($destination_ref, $index, $new_item_p). You can check for undef
- # on the next or previous index values to see if you're inserting at
- # the end/beginning of the list.
-
- # returns the indexes (in the new list) of the txns that were
- # inserted
-
- my @inserted_indices = ();
- my @source = @$source_ref;
- my $src_head = shift @source;
- my $current_splice_pos = 0;
- my $dest_items_left = scalar(@$destination_ref);
- my $next_dest = $$destination_ref[$current_splice_pos];
- while($src_head && $dest_items_left) {
- if(&$comparison($next_dest, $src_head) == 1) {
- # i.e. next_dest > src_head
- splice @$destination_ref, $current_splice_pos, 0, $src_head;
- push @inserted_indices, $current_splice_pos;
- &$mangler($destination_ref, $current_splice_pos, 1) if $mangler;
- $src_head = shift @source;
- $current_splice_pos++;
- } else {
- &$mangler($destination_ref, $current_splice_pos, 0) if $mangler;
- $current_splice_pos++;
- $next_dest = $$destination_ref[$current_splice_pos];
- $dest_items_left--;
- }
- }
- if($src_head) {
- push @$destination_ref, $src_head, @source;
- my $tail;
- foreach $tail ($src_head, @source) {
- &$mangler($destination_ref, $current_splice_pos, 1) if $mangler;
- push @inserted_indices, $current_splice_pos;
- $current_splice_pos++;
- }
- } else {
- # Must be some destination_ref items left.
- while ($dest_items_left) {
- &$mangler($destination_ref, $current_splice_pos, 0) if $mangler;
- $current_splice_pos++;
- $dest_items_left--;
- }
- }
- return \@inserted_indices;
-}
-
-sub destructive_remove_mangle {
- my($destination_ref, $source_ref, $comparison, $mangler) = @_;
-
- # Removes elements of source from destination according to the
- # comparison function which is just boolean. Assumes that source
- # items are in the same order in source_ref as they are in
- # destination_ref
-
- # mangler is optional, but if provided will be called for each item
- # in the new destination list with the args:
-
- # ($killed_p, $destination_ref, $index, $old_item). If killed is true
- # ($killed_p, $destination_ref, $index). If killed is false
-
- # if killed is true, index is the delete pos, while if false, it's
- # the new index. You can check for undef on the next or previous
- # index values to see if you're at the end/beginning of the list.
-
- my @removed_indices = ();
- my $old_position = 0;
- my @source = @$source_ref;
- my $src_head = shift @source;
- my $current_splice_pos = 0;
- my $dest_items_left = scalar(@$destination_ref);
- my $next_dest = $$destination_ref[$current_splice_pos];
- while($src_head && $dest_items_left) {
- if(&$comparison($next_dest, $src_head)) {
- # found an item to delete.
- splice @$destination_ref, $current_splice_pos, 1;
- &$mangler(1, $destination_ref, $current_splice_pos, $src_head)
- if $mangler;
- $src_head = shift @source;
- push @removed_indices, $old_position;
- } else {
- &$mangler(0, $destination_ref, $current_splice_pos) if $mangler;
- $current_splice_pos++;
- }
- $old_position++;
- $dest_items_left--;
- $next_dest = $$destination_ref[$current_splice_pos];
- }
- if($src_head) {
- print STDERR
- "Warning: source items left after destructive_remove_mangle\n";
- }
- if($mangler && $dest_items_left) {
- while($dest_items_left) {
- &$mangler(0, $destination_ref, $current_splice_pos);
- $current_splice_pos++;
- $dest_items_left--;
- }
- }
- return \@removed_indices;
-}
-
-sub timestamp {
- my($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time);
- $month++; # don't want 0 based months.
- $month = "0" . $month if $month < 10;
- $mday = "0" . $mday if $mday < 10;
- $hour = "0" . $hour if $hour < 10;
- $min = "0" . $min if $min < 10;
- $sec = "0" . $sec if $sec < 10;
- $year += 1900;
-
- return("$year-$month-$mday-$hour-$min-$sec");
-}
-
-# We need a version number
-$CBB::version = "Version <not_installed>";
-($CBB::junk, $CBB::version_num, $CBB::junk) = split(/ +/, $CBB::version);
-
-
-# Contributed by Christopher Browne, Oct. 24/94
-sub pad {
- return sprintf("%02d", $_[0]);
-}
-
-
-# return the directory of a file name
-sub file_dirname {
- my($file) = @_;
- my($pos);
-
- $pos = rindex($file, "/");
- if ( $pos >= 0 ) {
- return substr($file, 0, ($pos + 1));
- } else {
- return "./";
- }
-}
-
-
-# return the base file name
-sub file_basename {
- my($file) = @_;
- my($pos);
-
- $pos = rindex($file, "/");
- return substr($file, ($pos + 1));
-}
-
-
-# return the file name root (ending at last ".")
-sub file_root {
- my($file) = @_;
- my($pos);
-
- $pos = rindex($file, ".");
- return substr($file, 0, $pos);
-}
-
-
-# return the file name extension (starting at first ".")
-sub file_extension {
- my($file) = @_;
- my($pos);
-
- $pos = rindex($file, ".");
- return substr($file, ($pos + 1));
-}
-
-
-# return current date in a nice format
-sub nice_date {
- my($date_fmt) = @_;
-
- my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
- localtime(time());
-
- # right now we're only going to deal with yyyymmdd. We'll change
- # this soon.
-
- return(sprintf("%04d", 1900 + $year) .
- sprintf("%02d", $mon + 1) .
- sprintf("%02d", $mday));
-
- #if ( $date_fmt eq 'usa' ) {
- # return &pad($mon+1) . "/" . &pad($mday) . "/" . &pad($year);
- #} else {
- # return &pad($mday) . "." . &pad($mon+1) . "." . &pad($year);
- #}
-}
-
-
-# return current date in a raw format
-sub raw_date {
- my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
- localtime(time);
- return ¢ury() . &pad($year) . &pad($mon+1) . &pad($mday);
-}
-
-# start date: return date in raw format, takes argument of those types:
-# -[num]m months (eg. "-0m" means only current month, "-1m" means current and last)
-# -[num]d days (eg. "-10m" means 10 days)
-# dd.mm.yy[yy] : "international" format
-# mm/dd/yy[yy] : "us" format
-# yyyymmdd : "raw" format
-#
-# This can get a bit complicated, thank god we don't have to care whether
-# we return invalid days
-
-sub start_date {
- my($idate) = @_;
- my($odate, $value);
- my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
- localtime(time);
-
- $mon = $mon + 1;
-
- if ( $idate =~ /^\d{8}$/ ) { # "raw" format
- $odate = $idate;
- } elsif ($idate =~ /^-\d{1,2}m$/ ) { # "month" format
-
- $value = substr($idate, 1, 3); # a maximum of 99 months !
- if ($value >= $mon) {
- $year = $year - 1 - int( ($value - $mon) / 12 );
- $value = ($value % 12 );
- }
- $mon = $mon - $value;
- if ($mon < 1) {
- $value = $value + 12;
- }
- $odate = ¢ury() . &pad($year) . &pad($mon) . &pad(1);
-
- } elsif ($idate =~ /^-\d{1,3}d$/ ) { # "day" format
-
- $value = substr($idate, 1, 4); # a maximum of 999 days !
- if ($value >= $yday) {
- $year = $year - 1 - int( ($value - $yday) / 360 );
- $value = ( $value % 360 );
- }
- if ($value >= $mday) {
- $mon = $mon - 1 - int( ($value - $mday) / 30 );
- if ($mon < 1) {
- $mon = $mon + 12;
- }
- $value = ( $value % 30 );
- }
- $mday = $mday - $value;
- if ($mday < 1) {
- $mday = $mday + 30;
- }
- $odate = ¢ury() . &pad($year) . &pad($mon) . &pad($mday);
-
- } elsif ( $idate =~ /^\d{1,2}\/\d{1,2}\/\d{2,4}$/ ) { # "us" format
-
- ($mon, $mday, $year) = split(/\//, $idate);
- if ($year < 100) {
- $value = ¢ury();
- } else {
- $value = $year / 100;
- }
- $odate = &pad($value) . &pad($year) . &pad($mon) . &pad($mday);
-
- } elsif ( $idate =~ /^\d{1,2}\.\d{1,2}\.\d{2,4}$/ ) { # "int" format
-
- ($mday, $mon, $year) = split(/\./, $idate);
- if ($year < 100) {
- $value = ¢ury();
- } else {
- $value = $year / 100;
- }
- $odate = &pad($value) . &pad($year) . &pad($mon) . &pad($mday);
-
- } else { # nonsense, give them everything since 1900
- $odate = "19000101";
- }
-
- return ($odate);
-}
-
-# return the current century in the form 19, 20, 21, etc.
-# requires the Unix "date" command to be in the path
-sub century {
- my($unix_date, $year, $century, $junk);
-
- $unix_date = localtime; # e.g. "Thu Oct 3 16:53:37 1996"
- ($junk, $junk, $junk, $junk, $year) = split(/\s+/, $unix_date);
- $century = substr($year, 0, 2);
-
- return($century);
-}
-
-
-sub mypwd {
- my $dir = `pwd`;
- chomp($dir);
- return $dir;
-}
-
-
-1; # need to return a true value
-__END__
-
-## @endcond
-# ----------------------------------------------------------------------------
-# $Log$
-# Revision 1.1 2000/06/02 09:00:14 peticolas
-# Rob Browning's patch to add automake.
-#
-# Revision 1.2 1999/01/17 17:05:59 linas
-# patch from msimons at fsimons01.erols.com (Mike Simons)
-#
-# Revision 1.1 1998/04/22 03:02:38 linas
-# CBB conversion tools from Rob Browning
-#
-# Revision 1.3 1998/01/24 02:21:24 rlb
-# Many changes. Hopefully I'll be better about commits now.
-#
-# Revision 1.2 1997/10/22 03:46:00 rlb
-# Working (before txn data stucture switch)
-#
-# Revision 1.1 1997/10/10 18:15:53 rlb
-# Initial submission
-#
-# Revision 2.5 1996/12/17 14:53:54 curt
-# Updated copyright date.
-#
-# Revision 2.4 1996/12/14 17:15:21 curt
-# The great overhaul of December '96.
-#
-# Revision 2.3 1996/12/11 18:33:31 curt
-# Ran a spell checker.
-#
-# Revision 2.2 1996/12/08 07:39:58 curt
-# Rearranged quite a bit of code.
-# Put most global variables in cbb() structure.
-#
-# Revision 2.1 1996/12/07 20:38:14 curt
-# Renamed *.tk -> *.tcl
-#
-# Revision 2.3 1996/09/30 15:14:36 curt
-# Updated CBB URL, and hardwired wish path.
-#
-# Revision 2.2 1996/07/13 02:57:39 curt
-# Version 0.65
-# Packing Changes
-# Documentation changes
-# Changes to handle a value in both debit and credit fields.
-#
-# Revision 2.1 1996/02/27 05:35:38 curt
-# Just stumbling around a bit with cvs ... :-(
-#
-# Revision 2.0 1996/02/27 04:41:50 curt
-# Initial 2.0 revision. (See "Log" files for old history.)
-
-
-
-# ----------------------------------------------------------------------------
-# $Log$
-# Revision 1.1 2000/06/02 09:00:14 peticolas
-# Rob Browning's patch to add automake.
-#
-# Revision 1.2 1999/01/17 17:05:59 linas
-# patch from msimons at fsimons01.erols.com (Mike Simons)
-#
-# Revision 1.1 1998/04/22 03:02:38 linas
-# CBB conversion tools from Rob Browning
-#
-# Revision 1.3 1998/01/24 02:21:24 rlb
-# Many changes. Hopefully I'll be better about commits now.
-#
-# Revision 1.2 1997/10/22 03:46:00 rlb
-# Working (before txn data stucture switch)
-#
-# Revision 1.1 1997/10/10 18:15:53 rlb
-# Initial submission
-#
-# Revision 2.11 1997/05/06 01:00:26 curt
-# Added patches contributed by Martin Schenk <schenkm at ping.at>
-# - Default to umask of 066 so .CBB files get created rw by owner only
-# - Added support for pgp encrypting data files
-# - Added support for displaying only recent parts of files (avoids
-# waiting to load in lots of old txns you don't currently need.)
-# - Added a feature to "cache" whole accounts in the perl engine so
-# that switching between accounts can be faster.
-# - The above options can be turned on/off via the preferrences menu.
-#
-# Revision 2.10 1997/01/18 03:28:41 curt
-# Added "use strict" pragma to enforce good scoping habits.
-#
-# Revision 2.9 1996/12/17 14:53:54 curt
-# Updated copyright date.
-#
-# Revision 2.8 1996/12/11 18:33:30 curt
-# Ran a spell checker.
-#
-# Revision 2.7 1996/10/03 22:02:25 curt
-# I found a way in perl to get the century directly, so I was able to
-# eliminate the dependency on the external Unix date command.
-#
-# Revision 2.6 1996/10/03 04:48:59 curt
-# Fixed an inconsistency in &raw_date() in common.pl (with how it was
-# called.)
-#
-# Version now is 0.67-beta-x
-#
-# Revision 2.5 1996/10/03 04:13:39 curt
-# Refined default century handling code.
-#
-# Revision 2.4 1996/10/03 03:52:57 curt
-# CBB now determines the current century automatically ... no need for it
-# to be hard coded. Removed all hardcoded instances of the century (especially
-# in reports.pl and recur.pl)
-#
-# Added an optional --debug flag to the invocation of CBB.
-#
-# Revision 2.3 1996/10/02 19:37:18 curt
-# Replaced instances of hardcoded century (19) with a variable. We need to
-# know the current century in cases where it is not provided and it is
-# assumed to be the current century. Someday I need to figure out how
-# to determine the current century, but I have a couple of years to do it. :-)
-#
-# I still need to fix conf-reports and reports.pl
-#
-# Revision 2.2 1996/07/13 02:57:39 curt
-# Version 0.65
-# Packing Changes
-# Documentation changes
-# Changes to handle a value in both debit and credit fields.
-#
-# Revision 2.1 1996/02/27 05:35:37 curt
-# Just stumbling around a bit with cvs ... :-(
-#
-# Revision 2.0 1996/02/27 04:41:50 curt
-# Initial 2.0 revision. (See "Log" files for old history.)
-
-
-
diff --git a/src/experimental/cbb/cbb-old-to-cbb-alpha b/src/experimental/cbb/cbb-old-to-cbb-alpha
deleted file mode 100644
index 87505a5..0000000
--- a/src/experimental/cbb/cbb-old-to-cbb-alpha
+++ /dev/null
@@ -1,602 +0,0 @@
-#!/usr/bin/perl -w
-use strict;
-use English;
-use IO;
-
-my $pwd = `pwd`; chomp($pwd);
-push @INC, "$pwd/src";
-require 'CBBlib.pl';
-require 'CBBlib-auto.pl';
-require 'common.pl';
-
-# To do
-
-# URGENT -- convert '' statuses to ' '
-
-# Can we post process to check for leftover split destinations?
-# (i.e. straglers)
-
-# switch to checking credits and debits independently...
-
-# Check/convert all the cleared fields. Change to status?
-# Status: open cleared void -- lookup table?
-
-# Hope that forcing status into each relevant split line in
-# mark_matching is good enough...
-
-# I'm just killing preferred directions. Someone else can deal with
-# it later. I'm pretty sure getting it wrong won't hurt, and so no
-# one will ever see it.
-# my %preferred_directions;
-
-#### Offsets for old cbb fields
-
-my $date_old_idx = 0;
-my $checknum_old_idx = 1;
-my $description_old_idx = 2;
-my $debit_old_idx = 3;
-my $credit_old_idx = 4;
-my $category_old_idx = 5;
-my $comment_old_idx = 6;
-my $cleared_old_idx = 7;
-
-#### Offsets for new cbb fields
-
-#my $date_new_idx = 0;
-#my $source_new_idx = 1;
-#my $checknum_new_idx = 2;
-#my $description_new_idx = 3;
-#my $status_new_idx = 4;
-#my $splits_new_idx = 5;
-
-# Splits
-
-#my $category_new_idx = 0;
-#my $comment_new_idx = 1;
-#my $debit_new_idx = 2;
-#my $credit_new_idx = 3;
-#my $split_status_new_idx = 4;
-
-#my($account_ids, $category_ids);
-
-
-#sub invert_hash {
-# my($hash) = @_;
-# my %result;
-# my ($key, $value);
-# while(($key, $value) = each %$hash) {
-# $result{$value} = $key;
-# }
-# return \%result;
-#}
-
-# date check desc debit credit cat com cleared
-# 19930710 Transfer 0 200.00 [nb-savings] *
-#19950216 DEP Deposit 0 1303.81 |[dad]|All Old stuff|1103.00|[dad]|Allowance etc.|200.00|(Interest)|Interest Earned|0.81| x
-
-sub cleanup_status_field {
- my($status) = @_;
-
- # Legal values are:
- # "" (nothing) = new manually entered transaction, uncleared
- # "*" = selected from the balance window to tentatively be
- # cleared (stage one of the balance process)
- # "x" = cleared (stage two of the balance process)
- # "?" = a tentative future (recurring) transaction
- # "!" = a past (recurring) transaction
-
- if($status !~ /^([\*xX\?\!]?)$/o) {
- die "Illegal status value $status.";
- }
- # Handle X's left over from (who knows where).
- return lc($status);
-}
-
-# Collect category and account name hashes mapping from names to id num.
-sub get_categories_and_accounts {
- my(@files) = @_;
- my %categories = ();
- my %accounts = ();
- my $fh = new IO::File;
- my $file;
-
- foreach $file (@files) {
- print "Collecting categories and accounts from $file\n";
- $fh->open($file) or die "Can't open input file $file.";
-
- # Make sure all the accounts are listed as a [name] category.
- $_ = <$fh>;
- m|^# CBB Data File .*?[/ ]([^/]+)\.cbb$|o or
- die "Couldn't find data file name in $_";
-
- $accounts{$1} = 1;
-
- while(<$fh>) {
- next if /^#/;
- chomp($_);
- my @fields = split("\t", $_, 8);
-
- if($fields[$category_old_idx] =~ /^\|/) {
- $fields[$category_old_idx] = substr($fields[$category_old_idx], 1, -1);
- my @split_fields = split('\|', $fields[$category_old_idx]);
-
- my $i;
- for($i = 0; $i < $#split_fields; $i++) {
- my $candidate = $split_fields[$i];
- if($candidate =~ /^\[(.*)\]$/o) {
- $accounts{$1} = 1;
- } else {
- $categories{$candidate} = 1;
- }
- $i+=2;
- }
- } else {
- my $candidate = $fields[$category_old_idx];
- if($candidate =~ /^\[(.*)\]$/o) {
- $accounts{$1} = 1;
- } else {
- $categories{$candidate} = 1;
- }
- }
- }
- $fh->close() or die "Can't close file $file.";
- }
-
- # Kill the special "no category" case
- delete $accounts{''};
- delete $categories{''};
-
- my @accounts = keys(%accounts);
- my @categories = keys(%categories);
-
- return(\@accounts, \@categories);
-}
-
-
-sub load_old_cbb_transactions {
- my($db, $acct_map, $cat_map, @files) = @_;
- my @transactions = ();
- my $fh = new IO::File;
-
- my $file;
- foreach $file (@files) {
- print "Collecting transactions from $file\n";
- $fh->open('<' . $file) or die "Can't open input file $file.";
-
- # Make sure all the accounts are listed as a [name] category.
- $_ = <$fh>;
- m|^# CBB Data File .*?[/ ]([^/]+)\.cbb$|o or
- die "Couldn't find data file name in $_";
-
- my $current_account = $$acct_map{$1};
- if(!$current_account) {
- die "Couldn't find CBBlib::Acct for account name $1\n";
- }
-
- my $default_sink = $db->get_default_sink();
- if(!$default_sink) {
- die "No default sink!\n";
- }
-
- while(<$fh>) {
- next if /^#/;
-
- chomp($_);
- my @fields = split("\t", $_, 8);
- my @splits = ();
-
- if($fields[$category_old_idx] =~ /^\|/) {
- # got to deal with splits.
- $fields[$category_old_idx] = substr($fields[$category_old_idx], 1, -1);
- my @split_fields = split('\|', $fields[$category_old_idx]);
-
- my $i;
- for($i = 0; $i < $#split_fields; $i++) {
-
- my $destination = $split_fields[$i++];
- # ??? Need to check for non-existent hash-entries.
- if(!$destination) {
- $destination = $default_sink;
-
- } elsif ($destination =~ /^\[(.*)\]$/o) {
- $destination = $$acct_map{$1};
- if(!$destination) {
- die "No destintion acct matching $1\n";
- }
- } else {
- my $name = $destination;
- $destination = $$cat_map{$name};
- if(!$destination) {
- die "No destintion category matching $name\n";
- }
- }
-
- my $note = $split_fields[$i++];
- my $debit = 0;
- my $credit = 0;
-
- if($split_fields[$i] < 0) {
- $debit = abs($split_fields[$i]);
- } else {
- $credit = $split_fields[$i];
- }
-
- push @splits, new CBBlib::Split($destination, $note,
- $debit, $credit);
- }
- } else {
- # no splits
- my $destination = $fields[$category_old_idx];
- if(!$destination) {
- $destination = $default_sink;
- } elsif ($destination =~ /^\[(.*)\]$/o) {
- $destination = $$acct_map{$1};
- } else {
- $destination = $$cat_map{$destination};
- }
- my $debit = $fields[$debit_old_idx];
- my $credit = $fields[$credit_old_idx];
- $debit = 0 if !$debit;
- $credit = 0 if !$credit;
-
- push @splits, new CBBlib::Split($destination,
- $fields[$comment_old_idx],
- $debit, $credit);
- }
-
- my $status = cleanup_status_field($fields[$cleared_old_idx]);
- my $transaction = new CBBlib::Txn($fields[$date_old_idx],
- $current_account,
- $fields[$checknum_old_idx],
- $fields[$description_old_idx],
- $status);
- map { $transaction->add_split($_) } @splits;
- push @transactions, $transaction;
- }
- $fh->close() or die "Can't open close file $file.";
- }
- return(\@transactions);
-}
-
-#sub preferred_direction {
-# my($source, $destination) = @_;
-# my $sourcename = $$account_ids{$source};
-# my $destname = $$account_ids{$destination};
-#
-# my $preferred_targets = $preferred_directions{$sourcename};
-# if(scalar(grep { /^$destname$/ } @$preferred_targets) >= 1) {
-# print STDERR " Preferred transsfer $sourcename -> $destname\n";
-# return 1;
-# }
-#
-# my($key, $value);
-# foreach $key (keys(%preferred_directions)) {
-# my $value = $preferred_directions{$key};
-# my $potential_sources = $preferred_directions{$key};
-# if(scalar(grep { /^$sourcename$/ } @$potential_sources) >= 1) {
-# if($key eq $destname) {
-# print STDERR " Preferred transfer $sourcename <- $destname\n";
-# return -1;
-# }
-# }
-# }
-# return 0;
-#}
-
-
-# This is really inefficient.
-
-sub mark_matching {
- my($transaction, $destination, $amount, $split_idxs, $index,
- $transactions, $transaction_status,
- $handle_singles) = @_;
-
- my $date = $transaction->get_date();
- my $source = $transaction->get_source();
- my $description = $transaction->get_desc(); # description iffy?
- my $splits = $transaction->get_splits();
-
- $$transaction_status[$index] = 'done';
-
- print STDERR "Looking for match on $date <$index>\n" .
- " ($source $destination $amount)\n";
- if($source == $destination) {
- print STDERR " Skipping search for this transaction (self deposit)\n";
- return;
- }
-
- # Find all the ones on the right date
- my $i = -1;
- my @potentials = map {
- my $ref = $_;
- $i++;
- if($_->get_date() == $date) {
- $i;
- } else {
- ();
- }
- } @$transactions;
-
- if(scalar(@potentials) > 0) {
- print STDERR " Found matches (" . join(" ", @potentials) . ")\n";
-
- # I believe we're guaranteed that all the splits from a given
- # transaction to a given account will result in a single
- # transaction in the destination with the sum. I'm assuming that
- # here.
-
- my $match;
- my $performed_delete = 0;
- foreach $match (@potentials) {
- my $candidate_txn = $$transactions[$match];
- #print STDERR " Checking ($$transaction[1] eq $destination)\n";
- $candidate_txn->print(\*STDERR);
- if($candidate_txn->get_source() == $destination) {
- my $candidate_splits = $candidate_txn->get_splits();
- my $csplit = $$candidate_splits[0];
-
- my $split_source = $csplit->get_dest();
- if(ref($split_source) eq 'CBBlib::Acct') {
-
- # Sense of addition is screwy because we're trying to make
- # sure that the totals match in both directions, but in the
- # source a credit is a debit here.
- #print STDERR "Checking ($split_source eq $source && " .
- # "((- $$split[2] + $$split[3]) == $amount)\n";
-
- if($split_source == $source &&
- (abs((- $csplit->get_debit() + $csplit->get_credit()) -
- $amount) < 0.0001)) {
-
- # Not interactive, just go ahead and do something.
- if($$transaction_status[$match] eq 'deleted') {
- print STDERR " Already deleted, skipping.\n";
- } elsif($$transaction_status[$match] eq 'done') {
- print STDERR " Already considered, skipping.\n";
- } elsif(!$$transaction_status[$match]) {
- print STDERR " Deleting transaction $match\n";
- $$transaction_status[$match] = 'deleted';
-
- my $affected_split_idx;
- foreach $affected_split_idx (@$split_idxs) {
- my $split = $$splits[$affected_split_idx];
- $split->set_status($candidate_txn->get_status());
- }
- $performed_delete = 1;
- last;
- } else {
- die "Fatal error, unknown transaction status.";
- }
- } else {
- print STDERR " Checking ($split_source eq $source && " .
- "((- " . $csplit->get_debit() . " + " . $csplit->get_credit() .
- ") == $amount)\n";
- print STDERR " Source or amount did not match, skipping.\n";
- }
- } else {
- print STDERR " Not a transfer, skipping\n";
- }
- } else {
- print STDERR ' Source ' . $candidate_txn->get_source() .
- " != destination $destination, skipping\n";
- }
- }
- if(!$performed_delete) {
- print STDERR
- "\n\n" .
- "*** ERROR: Couldn't find the other half of a split in the\n" .
- "following transaction. This might be because you used a\n" .
- "non-existent destination, or it could be because you entered\n" .
- "a multiple-transfer split in the old CBB, which couldn't\n" .
- "handle that.\n\n";
-
- $transaction->print(\*STDERR);
- exit(1);
- }
- }
-}
-
-sub handle_transaction_splits {
- my($transaction, $index, $transactions, $transaction_status,
- $handle_singles) = @_;
-
- # Skip if we've already dealt with this one.
- return if($$transaction_status[$index]);
-
- my $splits = $transaction->get_splits();
- if(!$handle_singles) {
- return if(scalar(@$splits) == 1);
- }
-
- $$transaction_status[$index] = 'done';
-
- my %transfers = ();
- my %split_lines = ();
- my $split;
- my $split_idx= 0;
- foreach $split (@$splits) {
- my $destination = $split->get_dest();
- if(ref($destination) eq 'CBBlib::Acct') {
- $transfers{$destination} =
- [$destination, 0] if ! $transfers{$destination};
-
- # calculate the total effect on the *other* side.
- # i.e. invert sense of credit and debit.
- my $data = $transfers{$destination};
- $$data[1] += ($split->get_debit() - $split->get_credit());
- if(!$split_lines{$destination}) {
- $split_lines{$destination} = [];
- }
- my $listref = $split_lines{$destination};
- push @$listref, $split_idx;
- }
- $split_idx++;
- }
- my $data;
- foreach $data (values(%transfers)) {
- my $destination = $$data[0];
- my $split_idxs = $split_lines{$destination};
-
- mark_matching($transaction,
- $destination, # destination
- $$data[1], # amount
- $split_idxs,
- $index,
- $transactions,
- $transaction_status,
- $handle_singles);
- }
-}
-
-sub clean_old_cbb_transaction_splits {
- # This is not the most efficient, but it's pretty straightforward.
- my($transactions) = @_;
- my @transaction_status = ("") x scalar(@$transactions);
-
- my $index = 0;
- # Lets deal with multiple splits first because we know which way they go.
- my $transaction;
- foreach $transaction (@$transactions) {
- handle_transaction_splits($transaction, $index, $transactions,
- \@transaction_status, 0);
- $index++;
- }
-
- # Now all we have left is the singles that didn't have a multi-split
- # match.
-
- $index = 0;
- foreach $transaction (@$transactions) {
- handle_transaction_splits($transaction, $index, $transactions,
- \@transaction_status, 1);
- $index++;
- }
-
- $index = 0;
- my @preened_transactions = map {
-
- my $status = $transaction_status[$index];
- my @result;
- if($status eq 'deleted') {
- print STDERR "Deleting $index\n";
- $_->print(\*STDERR);
- print STDERR "\n";
- @result = ();
- } elsif($status eq 'done') {
- @result = ($_);
- } else {
- print STDERR "Warning: found unprocessesed transaction " .
- "(status: $status)\n";
- $_->print(\*STDERR);
- die;
- }
- $index++;
- @result;
- } @$transactions;
- return(\@preened_transactions);
-}
-
-sub choose_default_sink {
- my($accounts, $categories) = @_;
- my $result = undef;
-
- my $done = 0;
- while(!$done) {
-
- print STDOUT
- "In the old CBB, it was OK to have empty transaction destinations.\n" .
- "This is no longer true. Please choose one of the following categories\n" .
- "or accounts as your default transaction destination. All old\n" .
- "transactions will be modified to reflect this. Note that if you\n" .
- "select the final <<unitemized>> category, then a new category with\n" .
- "that name will be created and used:\n\n";
-
- my $item_num = 0;
- my @item_map;
- print STDOUT "Accounts:\n";
- map {
- $item_map[$item_num] = $_;
- printf STDOUT (" %6d [%s]\n", $item_num++, $_->get_name());
- } sort { $a->get_name() cmp $b->get_name() } @$accounts;
- print STDOUT "\nCategories:\n";
- map {
- $item_map[$item_num] = $_;
- printf STDOUT (" %6d %s\n", $item_num++, $_->get_name());
- } sort { $a->get_name() cmp $b->get_name() } @$categories;
- printf STDOUT (" %6d %s\n", $item_num, '<<unitemized>>');
- my $unitemized_id = $item_num;
-
- print STDOUT "Please choose an item by number: ";
- flush STDOUT;
- my $response = <STDIN>;
- if($response !~ /^\s*(\d+)\s*$/o) {
- printf STDOUT " Invalid choice. Please try again.\n";
- sleep 2;
- } else {
- if($response == $unitemized_id) {
- $result = 0;
- } else {
- $result = $item_map[$response];
- }
- $done = 1;
- }
- }
- return $result;
-}
-
-
-STDOUT->autoflush(1);
-STDERR->autoflush(1);
-
-my $output_file = $ARGV[0];
-my @input_files = @ARGV[1..$#ARGV];
-
-die "Usage: convert-cbbfile output-file input-file ..."
- if !$output_file && @input_files;
-
-my($account_names, $category_names) =
- get_categories_and_accounts(@input_files);
-
-my @accounts = map { new CBBlib::Acct(undef, $_, ''); } @$account_names;
-my @categories = map { new CBBlib::Cat(undef, $_, ''); } @$category_names;
-
-my $default_sink = choose_default_sink(\@accounts, \@categories);
-
-if($default_sink) {
- # So we don't add it to db twice;
- @accounts = grep { $_ != $default_sink} @accounts;
- @categories = grep { $_ != $default_sink} @categories;
-}
-
-my $db = new CBBlib::Db($default_sink);
-
-$db->add_sinks([@accounts, @categories]);
-
-my %name_to_acct_map;
-my $accts = $db->get_accts();
-map {
- $name_to_acct_map{$_->get_name()} = $_;
-} @$accts;
-
-my %name_to_cat_map;
-my $cats = $db->get_cats();
-map {
- $name_to_cat_map{$_->get_name()} = $_;
-} @$cats;
-
-my $transactions = load_old_cbb_transactions($db,
- \%name_to_acct_map,
- \%name_to_cat_map,
- @input_files);
-
-my $purified_transactions =
- clean_old_cbb_transaction_splits($transactions);
-
-$db->add_txns($purified_transactions);
-
-open(OUTPUT, ">$output_file") or
- die "Couldn't open $output_file for output.\n";
-$db->print(\*OUTPUT);
-close(OUTPUT);
-
-__END__
diff --git a/src/experimental/cbb/cbb-to-xacc b/src/experimental/cbb/cbb-to-xacc
deleted file mode 100644
index 3424b7a..0000000
--- a/src/experimental/cbb/cbb-to-xacc
+++ /dev/null
@@ -1,264 +0,0 @@
-#!/usr/bin/perl -w
-use strict;
-use English;
-use IO;
-
-push @INC, './cbb-engine/';
-use lib '../swig/perl5/';
-use gnucash;
-
-require "CBBlib.pl";
-require "CBBlib-auto.pl";
-require "common.pl";
-
-sub query_user {
- my($out_stream, $in_stream, $prompt, $validation_regexp) = @_;
- my $result;
- my $old_rs = $$in_stream->input_record_separator();
- my $old_oaf = $$out_stream->autoflush();
- $$in_stream->input_record_separator("\n");
- $$out_stream->autoflush(1);
-
- while(!$result) {
- print $out_stream $prompt;
- $result = <$in_stream>;
- chomp $result;
- if($result !~ /$validation_regexp/m) {
- print $out_stream "Invalid response\n";
- $result = undef;
- }
- }
- $$in_stream->input_record_separator($old_rs);
- $$out_stream->autoflush($old_oaf);
- return $result;
-}
-
-sub split_date {
- my($datestring) = @_;
- if($datestring =~ /(\d\d\d\d)(\d\d)(\d\d)/o) {
- return($1, $2, $3);
- } else {
- return ();
- }
-}
-
-my %cash_account = ('cash' => 1
- );
-
-my %asset_account = ('nike' => 1,
- 'loans-misc' => 1,
- 'nike' => 1,
- 'mom' => 1,
- 'dad' => 1
- );
-
-sub create_accounts {
- my($xdb, $cbbdb) = @_;
-
- my %accthash;
-
- my $cbbacts = $cbbdb->get_accts();
- map {
- my $cbbacct = $_;
- my $acct = gnucash::xaccMallocAccount();
-
- my $accname = $cbbacct->get_name();
- gnucash::xaccAccountSetName($acct, $accname);
-
- if($cash_account{$accname}) {
- gnucash::xaccAccountSetType($acct, $gnucash::CASH);
- } elsif($asset_account{$accname}) {
- gnucash::xaccAccountSetType($acct, $gnucash::ASSET);
- } elsif($accname =~ /^cc-/o) {
- gnucash::xaccAccountSetType($acct, $gnucash::CREDIT);
- } else {
- gnucash::xaccAccountSetType($acct, $gnucash::BANK);
- }
-
- my $val = $cbbacct->get_notes();
- gnucash::xaccAccountSetDescription($acct, $val) if $val;
-
- gnucash::insertAccount($xdb, $acct);
- $accthash{$cbbacct} = $acct;
- $accthash{$acct} = $cbbacct;
- } @$cbbacts;
-
- my $cbbcats = $cbbdb->get_cats();
-
- #my $cat_parent = gnucash::xaccMallocAccount();
- #gnucash::xaccAccountSetName($cat_parent, "Categories");
-
- map {
- my $cbbcat = $_;
- my $cat = gnucash::xaccMallocAccount();
-
- my $cbbname = $cbbcat->get_name();
- gnucash::xaccAccountSetName($cat, $cbbname);
-
- if($cbbname =~ /\A\((.*)\)\Z/o) {
- gnucash::xaccAccountSetType($cat, $gnucash::INCOME);
- } else {
- gnucash::xaccAccountSetType($cat, $gnucash::EXPENSE);
- }
-
- my $val = $cbbcat->get_notes();
- gnucash::xaccAccountSetDescription($cat, $val) if $val;
-
- gnucash::insertAccount($xdb, $cat);
- #gnucash::xaccInsertSubAccount($cat_parent, $cat);
- $accthash{$cbbcat} = $cat;
- $accthash{$cat} = $cbbcat;
- } @$cbbcats;
-
- #gnucash::insertAccount($xdb, $cat_parent);
- return %accthash;
-}
-
-sub get_adjustment_acct {
- my($xdb) = @_;
-
- my $adjustment_acct;
- while(!$adjustment_acct) {
- my $acct_name = query_user(\*STDOUT, \*STDIN,
-
-"\nCBB allowed self-referent transactions (where the source and
-destination account are the same). Xacc forbids this. The
-alternative is to have an \"adjustments\" account, and use that as the
-destination. Please enter a name for this account [adjustments]: ",
-
- '\w+');
-
- $adjustment_acct = gnucash::xaccGetAccountFromName($xdb, $acct_name);
-
- if($adjustment_acct) {
- my $use_existing = query_user(\*STDOUT, \*STDIN,
- "Account " . $acct_name .
- " already exists, use it [y/n]? ",
- '\A\s*([y]|[n])\s*\Z');
- if($use_existing =~ /n/o) {
- $adjustment_acct = undef;
- }
- } else {
- $adjustment_acct = gnucash::xaccMallocAccount();
- gnucash::xaccInitAccount($adjustment_acct);
- gnucash::xaccAccountSetName($adjustment_acct, $acct_name);
- gnucash::xaccAccountSetType($adjustment_acct, $gnucash::INCOME);
- gnucash::insertAccount($xdb, $adjustment_acct);
- }
- }
- return($adjustment_acct);
-}
-
-sub map_cbb_status_to_xacc {
- my($cbbstatus) = @_;
- my $result;
- if($cbbstatus eq ' ') {
- $result = $gnucash::NREC;
- } elsif($cbbstatus eq '') {
- $result = $gnucash::NREC;
- } elsif($cbbstatus eq '*') {
- print STDERR "Demoting CBB status 'pending balance' to untouched\n";
- $result = $gnucash::NREC;
- } elsif($cbbstatus eq 'x') {
- $result = $gnucash::CREC;
- }
- return $result;
-}
-
-
-sub migrate_transactions {
- my($xdb, $cbbdb, $adjustment_acct, %accthash) = @_;
- my $adjustment_acct_name = gnucash::xaccAccountGetName($adjustment_acct);
-
- my $txns = $cbbdb->get_txns();
-
- map {
- my $ctxn = $_;
- my $xtxn = gnucash::xaccMallocTransaction();
-
- my($year, $month, $day) = split_date($ctxn->get_date());
-
- if(!$year) {
- $ctxn->print(\*STDERR, "");
- die "Bad date " . $ctxn->get_date();
- }
-
- gnucash::xaccTransSetDate($xtxn, $day, $month, $year);
- my $val;
- $val = $ctxn->get_checkno();
- gnucash::xaccTransSetNum($xtxn, $val) if $val;
- $val = $ctxn->get_desc();
- gnucash::xaccTransSetDescription($xtxn, $val) if $val;
-
- my $cbbstatus = $ctxn->get_status();
- my $xstatus = map_cbb_status_to_xacc($cbbstatus);
- if($xstatus) {
- gnucash::xaccTransSetReconcile($xtxn, $xstatus);
- } else {
- print STDERR
- "ERROR: Can't map CBB status field value $cbbstatus to Xacc.\n";
- $ctxn->print(\*STDOUT, "");
- exit(1);
- }
-
- my $source_acc = $accthash{$ctxn->get_source()};
- my $source_split = gnucash::xaccTransGetSourceSplit($xtxn);
- gnucash::xaccAccountInsertSplit($source_acc, $source_split);
-
- my $cdest_splits = $ctxn->get_splits();
-
- my $total = 0;
- my $num_splits = scalar(@$cdest_splits);
- map {
- my $csplit = $_;
- my $xsplit = gnucash::xaccMallocSplit();
-
- $val = $csplit->get_notes();
- gnucash::xaccSplitSetMemo($xsplit, $val) if $val;
-
- my $cbbstatus = $csplit->get_status();
- my $xstatus = map_cbb_status_to_xacc($cbbstatus);
- if($xstatus) {
- gnucash::xaccSplitSetReconcile($xsplit, $xstatus);
- } else {
- print STDERR
- "ERROR: Can't map CBB status field value $cbbstatus to Xacc.\n";
- $ctxn->print(\*STDOUT, "");
- exit(1);
- }
-
- my $debit = $csplit->get_debit();
- my $credit = $csplit->get_credit();
- $val = -($credit - $debit);
- $total += $credit - $debit;
- gnucash::xaccSplitSetValue($xsplit, $val) if $val;
-
- if($num_splits == 1 && $csplit->get_dest() == $ctxn->get_source()) {
- print "self-referent " . $ctxn->get_source()->get_name() .
- " transaction converted to transfer from " .
- $adjustment_acct_name . "\n";
- gnucash::xaccAccountInsertSplit($adjustment_acct, $xsplit);
- } else {
- my $dest_acct = $accthash{$csplit->get_dest()};
- gnucash::xaccAccountInsertSplit($dest_acct, $xsplit);
- }
- gnucash::xaccTransAppendSplit($xtxn, $xsplit);
- } @$cdest_splits;
- gnucash::xaccSplitSetValue($source_split, $total);
-
- } @$txns;
-}
-
-my $filename = $ARGV[0];
-
-my $cbbdb = CBBlib::load_file($filename);
-my $xdb = gnucash::xaccMallocAccountGroup();
-
-my %accthash = create_accounts($xdb, $cbbdb);
-my $adjustment_acct = get_adjustment_acct($xdb);
-
-migrate_transactions($xdb, $cbbdb, $adjustment_acct, %accthash);
-
-gnucash::xaccWriteAccountGroup("foobar.xac", $xdb);
-
-__END__
diff --git a/src/experimental/cgi-bin/Makefile.am b/src/experimental/cgi-bin/Makefile.am
deleted file mode 100644
index cb34c97..0000000
--- a/src/experimental/cgi-bin/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-# cgi-bin Makefile.am file.
-
-
-bin_PROGRAMS = hello hello2 fastcgi-hello hello3 gnc-server
-
-AM_CPPFLAGS = \
- -I../../engine -I${srcdir}/../../engine \
- -I../../backend/xml -I${srcdir}/../../backend/xml \
- ${GLIB_CFLAGS}
-
-LDADD = \
- ../../engine/libgncengine.la \
- -lxml -lghttp -lglib -lfcgi -ldl
-
-hello_SOURCES = \
- hello.c
-
-hello2_SOURCES = \
- hello2.c
-
-hello3_SOURCES = \
- hello3.c
-
-fastcgi_hello_SOURCES = \
- fastcgi-hello.c
-
-gnc_server_SOURCES = \
- gnc-server.c
-
-noinst_HEADERS =
-
-
-EXTRA_DIST = \
- README \
- login.html
diff --git a/src/experimental/cgi-bin/README b/src/experimental/cgi-bin/README
deleted file mode 100644
index d669804..0000000
--- a/src/experimental/cgi-bin/README
+++ /dev/null
@@ -1,82 +0,0 @@
-This directory contains some cgi-bin prototypes,
-including a prototype gnucash server.
-
-hello.c -- totally bogus cgi-bin example.
- initializes the gnucash engine, sends gnc-xml data.
-
-hello2.c -- as above, but fiddles with gnucash query xml
- (to see if they work)
-
-hello3.c -- a minimally functional gnc server. No error checking,
- no login, but it does listen to queries, and responds
- to them.
-
-fastcgi-hello.c -- demo program illustrating how fast-cgi
- works.
-
-gnc-server.c -- the prototype gnucash server, as it currently stands.
- Currently, its a major hack job, but it tries to do
- some things right. See install instruction below.
-
-
-===================
-The fast-cgi applications require fast-cgi to be installed.
-www.fastcgi.com
-
-This takes some doing:
--- there are two parts to fast_cgi -- the apache module,
- and the development kit. You need only the development
- kit to build these demos; but you need the server module
- to run them.
-
- (Note: instead of using the apache module, you can
- also use the 'cgi-fcgi' server that comes with the
- fcgi development kit. With this program, you don't
- need to recompile the apache server or install any
- modules.)
-
--- To install the server module:
- There are debian .debs, you can apt-get install fastcgi
-
- I could not find redhat RPM's for this module, which means
- apache must be compiled by hand with the fast-cgi module.
-
- Next, configured as per directions on www.fastcgi.com
- For example, the following enables any cgi-bin with
- the .fcgi suffix to be treated as fast-cgi.
-
- <IfModule mod_alias.c>
- <IfModule mod_fastcgi.c>
- <Directory "/home/wherever/cgi-bin">
- AddHandler fastcgi-script fcg fcgi fpl
- AllowOverride None
- Options None
- Order allow,deny
- Allow from all
- </Directory>
- </IfModule>
- </IfModule>
-
-
--- the fast-cgi development toolkit must be downloaded
- and installed.
-
-===================
-To install and run gnc-server:
-
--- copy some old gnucash data file to /tmp/demo.xac
- (right now, because there's no sql backend for gnucash,
- the demo runs off a data file.)
--- copy login.html to somwhere in your web server path.
--- copy gnc-server to /cgi-bin/gnc-server.fcgi
-
--- power up a gnucash client, and load login.html with
- the gnucash help browser.
-
-
-===================
-The gnc-server is a pre-pre-alpha server for gnucash.
-A huge anmount of work is needed to make it run right.
-
---linas
-January 2001
diff --git a/src/experimental/cgi-bin/fastcgi-hello.c b/src/experimental/cgi-bin/fastcgi-hello.c
deleted file mode 100644
index ca7b117..0000000
--- a/src/experimental/cgi-bin/fastcgi-hello.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/********************************************************************\
- * 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 at gnu.org *
- * *
-\********************************************************************/
-
-
-#include <fcgi_stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-extern char **environ;
-
-int main (int argc, char *argv[])
-{
- char *query_string, *method, *len = 0x0;
- int count = 0;
- int i, ilen = 0;
-
- while (FCGI_Accept() >= 0)
- {
- printf("Content-type: text/html\r\n"
- "\r\n"
- "<title>FastCGI Hello!</title>"
- "<h1>FastCGI Hello!</h1>"
- "Request number %d running on host <i>%s</i>\n",
- ++count, getenv("SERVER_NAME"));
-
- printf("<p>If you have configured fastcgi correctly, then "
- "the request number should increment every time you "
- "hit reload on your browser. You should also see "
- "\"%s\" (the name of this program) showing up in ps ax.\n",
- argv[0]);
-
- query_string = getenv ("QUERY_STRING");
- printf ("<p>The QUERY_STRING environment vairable is %s\n"
- "The other environment variables are:<p>", query_string);
-
- for (i = 0; environ[i]; i++)
- {
- printf ("<br>%s\n", environ[i]);
- }
-
- method = getenv ("REQUEST_METHOD");
- if (!strcmp (method, "POST"))
- {
- char * bufp;
- ilen = atoi (getenv ("CONTENT_LENGTH"));
- printf ("<P>This is a method=post request, "
- "with content length=%d<P>\n", ilen);
- bufp = (char *) malloc (ilen);
- fread (bufp, ilen, 1, stdin);
-
- printf ("The POST data is<P>%s\n", bufp);
- free (bufp);
- }
-
- }
- return 0;
-}
diff --git a/src/experimental/cgi-bin/gnc-server.c b/src/experimental/cgi-bin/gnc-server.c
deleted file mode 100644
index a2f2176..0000000
--- a/src/experimental/cgi-bin/gnc-server.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * FILE:
- * gnc-server.c
- *
- * FUNCTION:
- * Experimental gnucash server
- * Written as a demo, not real code.
- * A 'real' server would be a bit more architected than this;
- * this implementation doesn't hide interfaces sufficiently.
- */
-/********************************************************************\
- * 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 at gnu.org *
- * *
-\********************************************************************/
-
-
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "gnc-engine.h"
-#include "io-gncxml.h"
-
-#include <fcgi_stdio.h>
-
-
-/* ======================================================== */
-/* XXX -- hack alert -- should do the below in some far more
- * elegant fashion ... */
-
-static void
-reject_user_agent (const char *user_agent)
-{
- printf("Content-type: text/html\r\n"
- "\r\n"
- "<html>\n"
- "<head><title>ERROR</title></head>\n"
- "<body bgcolor=#ffffff>\n"
- "<h1>Error - Wrong Browser</h1>\n"
- "Your browser was deteted to be %s<p>\n"
- "This server returns finacial data (XML) that only\n"
- "the GnuCash client understands. You must use GnuCash\n"
- "to view this data\n"
- "</body></html>\n",
- user_agent);
-}
-
-static void
-reject_method (const char * method)
-{
- printf("Content-type: text/html\r\n"
- "\r\n"
- "<html>\n"
- "<head><title>ERROR</title></head>\n"
- "<body bgcolor=#ffffff>\n"
- "<h1>Error - Unsupported Method</h1>\n"
- "Your browser sent METHOD=%s\n"
- "<p>Only METHOD=POST is supported\n"
- "</body></html>\n",
- method);
-}
-
-static void
-reject_session (const char * session)
-{
- printf("Content-type: text/html\r\n"
- "\r\n"
- "<html>\n"
- "<head><title>ERROR</title></head>\n"
- "<body bgcolor=#ffffff>\n"
- "<h1>Error - Invalid Session ID</h1>\n"
- "Your browser sent the session id %s\n"
- "<p>This is not a valid session ID\n"
- "</body></html>\n",
- session);
-}
-
-static void
-reject_auth (void)
-{
- printf("Content-type: text/html\r\n"
- "\r\n"
- "<html>\n"
- "<head><title>ERROR</title></head>\n"
- "<body bgcolor=#ffffff>\n"
- "<h1>Error - Bad Login</h1>\n"
- "Your supplied a bad username or password\n"
- "<p>Try again\n"
- "</body></html>\n");
-}
-
-/* ======================================================== */
-/* XXX -- hack alert -- cheesy user authentication and tracking
- * this should be replaced by something more professional
- *
- * This implementation uses gnucash GncGUID's to track sessions,
- * but the API is designed so that anything that can be converted
- * to a string & back will work.
- */
-
-GList * logged_in_users = NULL;
-
-/* The auth_user() routine authenticates the user. If the
- * authentication fails, then NULL is returned. If the authentication
- * suceeds, then a string that uniquely identifies this session
- * should be returned. (When the user logs off, the session
- * should become invalid.
- */
-
-static const char *
-auth_user (const char * name, const char *passwd, char *buff)
-{
- GncGUID *guid;
- const char *session_auth_string;
-
- /* hack alert - XXX - we do no authentication whatsoever,
- * any user is allowed to login. We only reject null users.
- */
- if (!name || !passwd) return NULL;
-
- guid = guid_new();
- logged_in_users = g_list_prepend (logged_in_users, guid);
-
- guid_to_string_buffer (guid, buff);
- return buff;
-}
-
-/*
- * The have_session() routine checks to see whether the given
- * session string corresponds to a valid session. It returns
- * true if it does.
- */
-
-static gboolean
-have_session (const char *session_auth_string)
-{
- GncGUID guid;
- GList *next = logged_in_users;
-
- string_to_guid (session_auth_string, &guid);
-
- while (next)
- {
- if (guid_equal (&guid, next->data)) return TRUE;
- next = next->next;
- }
-
- /* guid was not found */
- return FALSE;
-}
-
-/* ======================================================== */
-/* handy utility routine for finding a cookie in the cookie string */
-
-static const char *
-find_cookie (const char * cookie_name)
-{
- const char *cookie_string;
- size_t len;
- len = strlen (cookie_name);
-
- cookie_string = getenv ("HTTP_COOKIE");
- if (!cookie_string) return NULL;
-
- while (cookie_string)
- {
- if (!strncmp (cookie_string, cookie_name, len) &&
- ('=' == cookie_string[len]))
- {
- return cookie_string + len + 1;
- }
- cookie_string = strchr (cookie_string, ';');
- if (cookie_string) cookie_string ++;
- }
-
- return NULL;
-}
-
-/* ======================================================== */
-/* simpleminded utility parses GET/POST string for username,
- * password. Not only is it totally inflexible as to what
- * it looks for, but it also fails to url-decode, so that
- * characters like & cannot be used insode of passwords
- * XXX hack alert above should be fixed.
- */
-static void
-parse_for_login (char * bufp, char **namep, char **passwdp)
-{
- if (!bufp) return;
-
- while (bufp)
- {
- if (!strncmp (bufp, "name=", 5))
- {
- *namep = bufp + 5;
- }
- else if (!strncmp (bufp, "passwd=", 7))
- {
- *passwdp = bufp + 7;
- }
-
- bufp = strchr (bufp, '&');
- if (bufp)
- {
- *bufp = 0x0;
- bufp++;
- }
- }
-}
-
-/* ======================================================== */
-
-int
-main (int argc, char *argv[])
-{
- int err, fake_argc = 1;
- char * fake_argv[] = {"hello", 0};
- QofBook *book;
- Account *root;
- char *request_bufp, *reply_bufp;
- int rc, sz;
-
- /* intitialize the engine */
- gnc_engine_init (fake_argc, fake_argv);
-
- /* contact the database, which is a flat file for this demo */
- /* this should really be an SQL server */
- book = qof_book_new ();
-
- rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE);
- if (!rc) goto bookerrexit;
-
- rc = gnc_book_load (book);
- if (!rc) goto bookerrexit;
-
- /* the root pointer points to our local cache of the data */
- root = gnc_book_get_root_account (book);
-
- /* --------------------------------------------------- */
- /* done with initialization, go into event loop */
-
- while (FCGI_Accept() >= 0)
- {
- GList *split_list;
- Query *q = NULL;
- const char *request_method;
- const char *user_agent;
- const char *auth_string;
- const char *content_length;
- gchar guidstr[GUID_ENCODING_LENGTH+1];
- int read_len = 0;
- int send_accts = 0;
-
- /* get the user agent; reject if wrong agent */
- user_agent = getenv ("HTTP_USER_AGENT");
- if (strncmp ("gnucash", user_agent, 7))
- {
- reject_user_agent (user_agent);
- continue;
- }
-
- /* get the request method */
- request_method = getenv ("REQUEST_METHOD");
- if (strcmp ("POST", request_method))
- {
- /* method=post is the only spported method*/
- reject_method(request_method);
- continue;
- }
-
- /* ----------------------------------------------- */
- /* look for an authentication cookie */
- auth_string = find_cookie ("gnc-server");
-
- /* found the cookie, lets make sure that it is valid */
- if (auth_string)
- {
- gboolean valid_session;
- valid_session = have_session (auth_string);
- if (!valid_session)
- {
-
- /* XXX invalid sessions are a sign of hacking;
- * this event should be noted in a security log
- * and the server admin contacted.
- */
- reject_session (auth_string);
- continue;
- }
- }
-
- /* go ahead and read the message body.
- * we'll need this soon enough */
- content_length = getenv("CONTENT_LENGTH");
- read_len = atoi (content_length);
-
- /* read 'read_len' bytes from stdin ... */
- request_bufp = (char *) g_malloc (read_len);
- fread (request_bufp, read_len, 1, stdin);
-
- /* if no previously authenticated session,
- * authenticate now */
- if (!auth_string)
- {
- char *name = NULL, *passwd = NULL;
- parse_for_login (request_bufp, &name, &passwd);
-
- auth_string = auth_user (name, passwd, guidstr);
- if (!auth_string)
- {
- reject_auth();
- g_free (request_bufp);
- continue;
- }
- send_accts = 1;
- }
-
- /* ----------------------------------------------- */
- /* send only the accounts to the user */
- if (send_accts)
- {
- /* print the HTTP header */
- printf("Content-type: text/gnc-xml\r\n"
- "Set-Cookie: %s\r\n"
- "Content-Length: %d\r\n"
- "\r\n",
- auth_string, sz);
-
- /* since this is the first time the user is logging
- * in, send them the full set of accounts.
- * (Do not send them any transactions yet).
- */
- gncxml_write_account_tree_to_buf(root, &reply_bufp, &sz);
-
- /* send the xml to the client */
- printf ("%s", reply_bufp);
- g_free (request_bufp);
-
- /* wait for the next request */
- continue;
- }
-
- /* ----------------------------------------------- */
- /* If we got to here, then the ser should be sending
- * us a query xml.
- * we should somehow error check that what we got
- * is really a valid query
- */
-
- /* conver the xml input into a gnucash query structure... */
- q = gncxml_read_query (request_bufp, read_len);
- xaccQuerySetGroup (q, root);
-
- /* hack -- limit to 30 splits ... */
- qof_query_set_max_results (q, 30);
- split_list = qof_query_run (q);
-
- /* poke those splits into an ccount group structure */
- /* XXX not implemented */
-
- /* send the account group structure back to the user */
- /* XXX not implemented */
-
- qof_query_destroy (q);
- g_free (request_bufp);
-
- }
-
-bookerrexit:
-
- err = gnc_book_get_error (book);
-
- /* 500 Server Error */
- FCGI_SetExitStatus (500);
-
- printf("Content-type: text/plain\r\n\r\n"
- "error was %s\n", strerror (err));
-
- FCGI_Finish();
-
- /* close the book */
- qof_book_destroy (book);
-
- /* shut down the engine */
- gnc_engine_shutdown ();
-
- sleep (1);
-
- /* must return a non-zero error code, otherwise fastcgi
- * attempts to respawn this daemon. */
- return 500;
-}
-
diff --git a/src/experimental/cgi-bin/hello.c b/src/experimental/cgi-bin/hello.c
deleted file mode 100644
index 1d376c6..0000000
--- a/src/experimental/cgi-bin/hello.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * FILE:
- * hello.c
- *
- * FUNCTION:
- * The first in a sequence of demos for cgi-bin programming
- * This demo shows how to intialize the gnc_engine, and how
- * to dump the entire contents of a gnucash file to stdout.
- *
- */
-/********************************************************************\
- * 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 at gnu.org *
- * *
-\********************************************************************/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gnc-commodity.h"
-#include "gnc-engine.h"
-#include "io-gncxml-v2.h"
-
-
-int
-main (int argc, char *argv[])
-{
- int fake_argc = 1;
- char * fake_argv[] = {"hello", 0};
- QofBook *book;
- int rc;
-
- /* intitialize the engine */
- gnc_engine_init (fake_argc, fake_argv);
-
- /* dirty little hack to work around commodity borkeness */
- {
- gnc_commodity_table *t = gnc_engine_commodities ();
- gnc_commodity *cm = gnc_commodity_new ("US Dollar", "ISO4217", "USD", "840", 100);
- gnc_commodity_table_insert (t, cm);
- }
-
- /* contact the database, which is a flat file for this demo */
- book = qof_book_new ();
-
- rc = gnc_book_begin (book, "file:/tmp/demo.gml", FALSE, FALSE);
- if (!rc)
- {
- GNCBackendError err = gnc_book_get_error (book);
- printf ("HTTP/1.1 500 Server Error\n");
- printf ("\n");
- printf ("err=%d \n", err);
- goto bookerrexit;
- }
-
- rc = gnc_book_load (book);
- if (!rc)
- {
- GNCBackendError err = gnc_book_get_error (book);
- printf ("HTTP/1.1 500 Server Error\n");
- printf ("\n");
- printf ("err=%d \n", err);
- goto bookerrexit;
- }
-
- /* print the HTTP header */
- printf ("HTTP/1.1 200 OK\n");
- printf ("Content-Type: text/gnc-xml\r\n");
- // the current write interfaces don't give us a length :-(
- // printf ("Content-Length: %d\r\n", sz);
- printf ("\r\n");
-
- gnc_book_write_to_xml_filehandle_v2 (book, stdout);
-
-bookerrexit:
- /* close the book */
- qof_book_destroy (book);
-
- /* shut down the engine */
- gnc_engine_shutdown ();
-
- return 0;
-}
diff --git a/src/experimental/cgi-bin/hello2.c b/src/experimental/cgi-bin/hello2.c
deleted file mode 100644
index 8646f41..0000000
--- a/src/experimental/cgi-bin/hello2.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * FILE:
- * hello2.c
- *
- * FUNCTION:
- * the second in a series of cgi-bin programming eamples.
- */
-/********************************************************************\
- * 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 at gnu.org *
- * *
-\********************************************************************/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gnc-engine.h"
-#include "io-gncxml.h"
-#include "Query.h"
-
-int
-main (int argc, char *argv[])
-{
- int fake_argc = 1;
- char * fake_argv[] = {"hello2", 0};
- QofBook *book;
- Account *root;
- Query *q, *qq;
- GList *split_list, *sl2, *node;
- Split *s;
- char *bufp;
- int i, ii, rc, sz;
-
-
- /* intitialize the engine */
- gnc_engine_init (fake_argc, fake_argv);
-
- /* contact the database, which is a flat file for this demo */
- book = qof_book_new ();
-
- rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE);
- if (!rc)
- {
- int err = gnc_book_get_error (book);
- printf ("HTTP/1.1 500 Server Error\n");
- printf ("\n");
- printf ("%d %s\n", err, strerror (err));
- goto bookerrexit;
- }
-
- rc = gnc_book_load (book);
- if (!rc)
- {
- int err = gnc_book_get_error (book);
- printf ("HTTP/1.1 500 Server Error\n");
- printf ("\n");
- printf ("%d %s\n", err, strerror (err));
- goto bookerrexit;
- }
-
- /* the root pointer points to our local cache of the data */
- root = gnc_book_get_root_account (book);
-
- /* build a query */
- q = qof_query_create_for(GNC_ID_SPLIT);
- xaccQuerySetGroup (q, root);
- qof_query_set_max_results (q, 30);
-
- /* Get everything between some random dates */
- /* In real life, we would use a query as specified by the user */
- xaccQueryAddDateMatch (q, TRUE, 28, 2, 1982,
- FALSE, 16, 10, 2010,
- QOF_QUERY_OR);
-
- split_list = qof_query_run (q);
-
- /* count number of splits */
- i = 0;
- for (node = split_list; node; node = node->next)
- {
- s = node->data;
- i++;
- }
-
- gncxml_write_query_to_buf(q, &bufp, &sz);
- qq = gncxml_read_query (bufp, sz);
- qof_query_set_max_results (qq, 30);
- xaccQuerySetGroup (qq, root);
- sl2 = qof_query_run (qq);
-
- /* count number of splits */
- ii = 0;
- for (node = sl2; node; node = node->next)
- {
- s = node->data;
- ii++;
- }
-
- /* print the HTTP header */
- printf ("HTTP/1.1 200 OK\n");
- printf ("Content-Type: text/xml\n");
- printf ("Content-Length: %d\n", sz);
- printf ("\n");
-
- printf ("%s", bufp);
-
- printf (" its %d and %d \n", i, ii);
-
- free (bufp);
- qof_query_destroy (q);
-
-
-bookerrexit:
- /* close the book */
- qof_book_destroy (book);
-
- /* shut down the engine */
- gnc_engine_shutdown ();
-
- return 0;
-}
diff --git a/src/experimental/cgi-bin/hello3.c b/src/experimental/cgi-bin/hello3.c
deleted file mode 100644
index e31ca82..0000000
--- a/src/experimental/cgi-bin/hello3.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * FILE:
- * hello3.c
- *
- * FUNCTION:
- * experimental gnucash server
- * written as a demo, not real code.
- * this file is here mostly as a simple intro to what
- * the server is doing.
- */
-/********************************************************************\
- * 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 at gnu.org *
- * *
-\********************************************************************/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "gnc-engine.h"
-#include "io-gncxml.h"
-
-#include <fcgi_stdio.h>
-
-
-int
-main (int argc, char *argv[])
-{
- int err, fake_argc = 1;
- char * fake_argv[] = {"hello", 0};
- QofBook *book;
- Account *root;
- char *bufp;
- int rc, sz;
-
- /* intitialize the engine */
- gnc_engine_init (fake_argc, fake_argv);
-
- /* contact the database, which is a flat file for this demo */
- book = qof_book_new ();
-
- rc = gnc_book_begin (book, "file:/tmp/demo.gnucash", FALSE);
- if (!rc) goto bookerrexit;
-
- rc = gnc_book_load (book);
- if (!rc) goto bookerrexit;
-
- /* the root pointer points to our local cache of the data */
- root = gnc_book_get_root_account (book);
-
- /* --------------------------------------------------- */
- /* done with initialization, go into event loop */
-
- while (FCGI_Accept() >= 0)
- {
- GList *split_list;
- Query *q = NULL;
- char *request_method;
- int read_len = 0;
-
- /* get the request method */
- request_method = getenv ("REQUEST_METHOD");
-
- /* Lets pretend that method=get means user has logged
- * in. Send the user the accounts and currencies,
- * but not the transactions/splits. */
- if (!strcmp ("GET", request_method))
- {
- gncxml_write_account_tree_to_buf(root, &bufp, &sz);
-
- /* print the HTTP header */
- printf("Content-type: text/gnc-xml\r\n"
- "Content-Length: %d\r\n"
- "\r\n", sz);
-
- /* send the xml to the client */
- printf ("%s", bufp);
- free (bufp);
-
- /* wait for the next request */
- continue;
- }
-
-
- if (!strcmp ("POST", request_method))
- {
- char * content_length = getenv("CONTENT_LENGTH");
- read_len = atoi (content_length);
-
- /* read 'read_len' bytes from stdin ... */
- bufp = (char *) malloc (read_len);
- fread (bufp, read_len, 1, stdin);
-
- /* conver the xml input into a gnucash query structure... */
- q = gncxml_read_query (bufp, read_len);
- xaccQuerySetGroup (q, root);
-
- /* hack -- limit to 30 splits ... */
- qof_query_set_max_results (q, 30);
- split_list = qof_query_run (q);
-
- qof_query_destroy (q);
-
- /* wait for the next request */
- continue;
- }
-
- /* if we got to here, an error -- unknown method */
- printf("Content-type: text/plain\r\n"
- "\r\n"
- "unknown request type \n");
-
-
- }
-
-bookerrexit:
-
- err = gnc_book_get_error (book);
-
- /* 500 Server Error */
- FCGI_SetExitStatus (500);
-
- printf("Content-type: text/plain\r\n\r\n"
- "error was %s\n", strerror (err));
-
- FCGI_Finish();
-
- /* close the book */
- qof_book_destroy (book);
-
- /* shut down the engine */
- gnc_engine_shutdown ();
-
- sleep (1);
-
- return 0;
-}
-
diff --git a/src/experimental/cgi-bin/login.html b/src/experimental/cgi-bin/login.html
deleted file mode 100644
index 7bab83a..0000000
--- a/src/experimental/cgi-bin/login.html
+++ /dev/null
@@ -1,40 +0,0 @@
-
-<html>
-<head>
-<title>GnuCash Server Login Form</title>
-</head>
-<body bgcolor=#ffffff>
-<h1>GnuCash Experimental Server Login Form</h1>
-This is the login form for the demo of the experimental
-Gnucash accounting server. This server is meant to
-demonstrate the multi-user, network-enabled abilities
-of GnuCash. Note that this demo is alpha, most features
-don't work.
-<p>
-
-For this demo, any username and password will work.
-
-<FORM METHOD=POST ACTION="/cgi-bin/gnc-server.fcgi">
-<table>
-<tr>
-<td>Name
-<td><input type="text" name="name" value="">
-<tr>
-<td>Password
-<td><input type="password" name="passwd" value="">
-<tr>
-<td>
-<td><input type="submit" name="login" value="Login">
-</table>
-</form>
-
-You must use the GnuCash client to log into this server:
-you cannot do so with MSIE and Netscape. This is because
-the GnuCash server returns financial data to client,
-and ordinary web browsers would have no idea of what to do
-with this data.
-<p>
-
-
-</body>
-</html>
diff --git a/src/experimental/gg/Makefile.am b/src/experimental/gg/Makefile.am
deleted file mode 100644
index d7c896c..0000000
--- a/src/experimental/gg/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-
-EXTRA_DIST = \
- README \
- canvas-test.scm \
- gnucash-sample.scm \
- hello-world.scm
diff --git a/src/experimental/gg/README b/src/experimental/gg/README
deleted file mode 100644
index cb498cc..0000000
--- a/src/experimental/gg/README
+++ /dev/null
@@ -1,20 +0,0 @@
-
-This is a directory for playing around with gnome-guile for those of
-you who have it installed. One of these days, it might be a suitable
-replacement for much of the exising gnome code, but for now it's just
-for exploration.
-
-If you're having trouble getting gnome-guile to run, and you've got it
-installed in a non-standard location. Especially, if that location
-isn't the same as your guile install location, you may need any or all
-of these environment variables set. The examples are for my current
-setup:
-
- export LD_LIBRARY_PATH=/usr/local/opt/gnome
- export PATH=/usr/local/opt/gnome/bin:${PATH}
- export GUILE_LOAD_PATH=/usr/local/opt/gnome/share/guile
-
-The hello-world.scm and canvas-test.scm examples were taken from the
-upstream gnome-guile examples.
-
-
diff --git a/src/experimental/gg/canvas-test.scm b/src/experimental/gg/canvas-test.scm
deleted file mode 100644
index c68bec9..0000000
--- a/src/experimental/gg/canvas-test.scm
+++ /dev/null
@@ -1,83 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 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 at gnu.org
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-#! /bin/sh
-exec gnomeg -s $0 $*
-!#
-(use-modules (gnome gnome)
- (gtk gtk)
- (gtk gdk))
-
-;;(gnome-init-hack "canvas" #f '())
-
-(let* ((win (gtk-window-new 'toplevel))
- (vbox (gtk-vbox-new #f 0))
- (zoom-a (gtk-adjustment-new 1 0.2 5.1 0.05 0.05 0.1))
- (zoom-s (gtk-hscale-new zoom-a))
- (canvas (gnome-canvas-new))
- (root (gnome-canvas-root canvas)))
-
- (define (create-draggable-item type x1 y1 x2 y2 color)
- (let* ((item (gnome-canvas-item-new root type
- 'x1 x1 'y1 y1 'x2 x2 'y2 y2
- 'width_pixels 1
- 'outline_color "black"
- 'fill_color color))
- (last-x #f)
- (last-y #f)
- (dragging #f))
- (define (handler ev)
- (case (gdk-event-type ev)
- ((enter-notify)
- (gnome-canvas-item-set item 'width_units 2))
- ((leave-notify)
- (gnome-canvas-item-set item 'width_pixels 0))
- ((button-press)
- (case (gdk-event-button ev)
- ((1)
- (set! last-x (gdk-event-x ev))
- (set! last-y (gdk-event-y ev))
- (set! dragging #t))))
- ((button-release)
- (set! dragging #f))
- ((motion-notify)
- (if dragging
- (let ((x (gdk-event-x ev))
- (y (gdk-event-y ev)))
- (gnome-canvas-item-move item (- x last-x) (- y last-y))
- (set! last-x x)
- (set! last-y y))))))
- (gtk-signal-connect item "event" handler)))
-
- (gtk-container-add win vbox)
- (gtk-box-pack-start vbox canvas)
- (gtk-box-pack-start vbox zoom-s #f)
- ;;(gnome-canvas-set-size canvas 300 300)
- (gtk-widget-set-usize canvas 300 300)
- (gtk-widget-show-all win)
-
- (create-draggable-item 'GnomeCanvasRect 50 50 150 150 "red")
- (create-draggable-item 'GnomeCanvasEllipse 100 100 200 200 "green")
-
- (gtk-signal-connect zoom-a "value-changed"
- (lambda ()
- (let ((val (gtk-adjustment-value zoom-a)))
- (gnome-canvas-set-pixels-per-unit canvas val))))
-
- (gtk-standalone-main win))
diff --git a/src/experimental/gg/gnucash-sample.scm b/src/experimental/gg/gnucash-sample.scm
deleted file mode 100644
index 2f07dbf..0000000
--- a/src/experimental/gg/gnucash-sample.scm
+++ /dev/null
@@ -1,96 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 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 at gnu.org
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-#! /bin/sh
-exec gnomeg -s $0 $*
-!#
-(use-modules (gnome gnome)
- (gtk gtk)
- (gtk gdk))
-
-
-;; Use a nicer font IMO, if available */
-(let* ((font "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*")
- (default-style (gtk-widget-get-default-style))
- (new-font (gdk-font-load font)))
-
- ;(if (and default-style new-font)
- ; st->font = f;
- ; }
- ; }
-
- (exit 0))
-
-;;(gnome-init-hack "canvas" #f '())
-
-(let* ((win (gtk-window-new 'toplevel))
- (vbox (gtk-vbox-new #f 0))
- (zoom-a (gtk-adjustment-new 1 0.2 5.1 0.05 0.05 0.1))
- (zoom-s (gtk-hscale-new zoom-a))
- (canvas (gnome-canvas-new))
- (root (gnome-canvas-root canvas)))
-
- (define (create-draggable-item type x1 y1 x2 y2 color)
- (let* ((item (gnome-canvas-item-new root type
- 'x1 x1 'y1 y1 'x2 x2 'y2 y2
- 'width_pixels 1
- 'outline_color "black"
- 'fill_color color))
- (last-x #f)
- (last-y #f)
- (dragging #f))
- (define (handler ev)
- (case (gdk-event-type ev)
- ((enter-notify)
- (gnome-canvas-item-set item 'width_units 2))
- ((leave-notify)
- (gnome-canvas-item-set item 'width_pixels 0))
- ((button-press)
- (case (gdk-event-button ev)
- ((1)
- (set! last-x (gdk-event-x ev))
- (set! last-y (gdk-event-y ev))
- (set! dragging #t))))
- ((button-release)
- (set! dragging #f))
- ((motion-notify)
- (if dragging
- (let ((x (gdk-event-x ev))
- (y (gdk-event-y ev)))
- (gnome-canvas-item-move item (- x last-x) (- y last-y))
- (set! last-x x)
- (set! last-y y))))))
- (gtk-signal-connect item "event" handler)))
-
- (gtk-container-add win vbox)
- (gtk-box-pack-start vbox canvas)
- (gtk-box-pack-start vbox zoom-s #f)
- ;;(gnome-canvas-set-size canvas 300 300)
- (gtk-widget-set-usize canvas 300 300)
- (gtk-widget-show-all win)
-
- (create-draggable-item 'GnomeCanvasRect 50 50 150 150 "red")
- (create-draggable-item 'GnomeCanvasEllipse 100 100 200 200 "green")
-
- (gtk-signal-connect zoom-a "value-changed"
- (lambda ()
- (let ((val (gtk-adjustment-value zoom-a)))
- (gnome-canvas-set-pixels-per-unit canvas val))))
-
- (gtk-standalone-main win))
diff --git a/src/experimental/gg/hello-world.scm b/src/experimental/gg/hello-world.scm
deleted file mode 100644
index fbd5b03..0000000
--- a/src/experimental/gg/hello-world.scm
+++ /dev/null
@@ -1,49 +0,0 @@
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 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 at gnu.org
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-#! /bin/sh
-exec guile-gtk -s $0 $*
-!#
-;; Time-stamp: <1998-03-15 21:45:18 szi>
-;;
-;; Hello World for Guile-Gtk
-;;
-;; This is a simple example program, that creates a window with a
-;; button labeled "Say Hello". The program prints "Hello World!" when
-;; you press the button and exits.
-;;
-
-(use-modules (gtk gtk))
-
-(let ((window (gtk-window-new 'toplevel))
- (button (gtk-button-new-with-label "Say Hello")))
- (gtk-window-set-title window "Guile-Gtk: Hello World")
- (gtk-container-border-width window 10)
- (gtk-container-add window button)
- (gtk-signal-connect button "clicked"
- (lambda ()
- (display "Hello World!")
- (newline)
- (gtk-widget-destroy window)))
- (gtk-widget-show-all window)
- (gtk-standalone-main window))
-
-; Local Variables:
-; mode: scheme
-; End:
diff --git a/src/experimental/ofx/README b/src/experimental/ofx/README
deleted file mode 100644
index 6833eee..0000000
--- a/src/experimental/ofx/README
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-This directory used to contain an OFX parser. That code is obsolete
-and has been cvs delete'd, as of 20 January 2003.
-
-The 'explore' subdirectory contains some example OFX from a working etrade
-OFX server. It will be deleted someday in the future, when we can
-assure that libofx works with the etrade server.
-
---linas
diff --git a/src/experimental/ofx/explore/Makefile.am b/src/experimental/ofx/explore/Makefile.am
deleted file mode 100644
index 83ade74..0000000
--- a/src/experimental/ofx/explore/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-
-EXTRA_DIST = \
- README.OFX \
- length.cc \
- parse_error \
- post2.ofx \
- reply_post2 \
- req1 \
- req1_orig \
- req5 \
- req7
diff --git a/src/experimental/ofx/explore/README.OFX b/src/experimental/ofx/explore/README.OFX
deleted file mode 100644
index 8c7df4d..0000000
--- a/src/experimental/ofx/explore/README.OFX
+++ /dev/null
@@ -1,76 +0,0 @@
-
-some notes about the OFX test implementation for GNUCash.
----------------------------------------------------------
-
-Ueli Rutishauser (urutishauser at bigfoot.com ) / 10.4.1998
-
-All the following informationen depends on version 1.5 and 1.0.2 of the
-Open Financial Exchange Specification (OFX).
-
-version notes
--------------
-
-The actual OFXHEADER Version is 1.00 (100)
-
-The actual OFXSGML DTD Version is 1.02 (102)
-
-
-urlget
-------
-
-urlget -i -v http://localhost/
-
-urlget -i -v https://swww.etrade.com/
-
-urlget -i -v -T post2.ofx https://ofx.etrade.com/cgi-ofx/etradeofx/
-
-anonymous login
----------------
-
-to login anonymous, USERID and/or USERPASS must be set to anonymous
-followed by 23 zeros.
-
-
-BROKERID
---------
-
-BROKERID (page 102 and 256) must set to the domain of the broker eg. etrade.com
-
-general notes
--------------
-
--OFX-Files cannot contain comments (<-- not allowed)
--All Tags must be written Uppercase (<OFX> not <ofx>)
-
-test files
-----------
-
-req1_orig Original Request for Investement Statements download (with comments)
-
-req1 ready to send request for a "Investement Statement download"
-get1 response of such a request (not yet available)
-
-req5 login anonymous
-get5 result of a anonymous login (not yet available)
-
-req6 login anonymous/get FI profile
-get6 result of a anonymous login with a profile request
-
-req7 Request for a "Investement Statement download"
-reply_req7 response when a false Account-ID is provided
-reply_req7_2 regular response
-
-post4.ofx login
-reply_post4 response to a valid login request
-
-PLEASE: do not test this examples with any OFX-server when you not
-really develop on the OFX-part. We have only one working OFX URL at the
-moment...
-
-programs/code
--------------
-
-length the program length calculates the length (Content-Length) for the
- HTTP Header of a file.
-
-
diff --git a/src/experimental/ofx/explore/length.cc b/src/experimental/ofx/explore/length.cc
deleted file mode 100644
index 1423424..0000000
--- a/src/experimental/ofx/explore/length.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/* this little program calculate the content-length for a HTTP-POST
- Statement. Count begins not until the first OFX (uppercase) occures.
-
- Copyright (c) 1998 by Ueli Rutishauser
- GPL'ed
-
- */
-
-#include <iostream.h>
-#include <fstream.h>
-
-void main( int argc, char **argv)
-{
- char character;
- int input_length=0, count=0, input_alphnum=0, O_yes=0, F_yes=0, X_yes=0;
-
- cout << "This program calculates the field content-length for a HTTP Header. Counting begins after the first occurens of the string OFX (uppercase)" << endl;
-
- if ( argc < 2)
- cout << "error - no command line argument given" << endl;
-
-
- cout << "use " << argv[1] << endl;
- ifstream input(argv[1],ios::in);
-
- if (!input)
- cout << "error open input file" << endl;
- else
- {
- while (input.get(character))
- {
- //cout << character;
- if (character == 'O')
- O_yes++;
- if (character == 'F' && O_yes > 0)
- F_yes++;
- if (character == 'X' && O_yes > 0 && F_yes)
- X_yes++;
-
- if (X_yes>0)
- input_length++;
- }
-
- input_length += 2; //add OF
-
- input.close();
-
- cout << "content-length of this file is (dec)" << dec << input_length << endl;
- }
-
-}
diff --git a/src/experimental/ofx/explore/parse_error b/src/experimental/ofx/explore/parse_error
deleted file mode 100644
index 66394c4..0000000
--- a/src/experimental/ofx/explore/parse_error
+++ /dev/null
@@ -1,7 +0,0 @@
-up result 0
-HTTP/1.0 400 OFX Request Parsing Error
-Server: Netscape-Enterprise/2.01
-Date: Fri, 10 Apr 1998 18:26:55 GMT
-Content-type: application/x-ofx
-
-down result 0 1901
diff --git a/src/experimental/ofx/explore/post2.ofx b/src/experimental/ofx/explore/post2.ofx
deleted file mode 100644
index 7d09f5e..0000000
--- a/src/experimental/ofx/explore/post2.ofx
+++ /dev/null
@@ -1,29 +0,0 @@
-POST /cgi-ofx/etradeofx HTTP/1.0
-User-Agent: MyApp 5.0
-Content-Type: application/x-ofx
-Content-Length: 298
-
-OFXHEADER:100
-DATA:OFXSGML
-VERSION:102
-SECURITY:TYPE1
-ENCODING:USASCII
-
-<OFX>
-<SIGNONMSGSRQV1>
-<SONRQ>
-<DTCLIENT>19980410083500
-</DTCLIENT>
-<USERID>xxxxxx
-</USERID>
-<USERPASS>xxxxxx
-</USERPASS>
-<LANGUAGE>ENG
-</LANGUAGE>
-<APPID>MyApp
-</APPID>
-<APPVER>0500
-</APPVER>
-</SONRQ>
-</SIGNONMSGSRQV1>
-</OFX>
diff --git a/src/experimental/ofx/explore/reply_post2 b/src/experimental/ofx/explore/reply_post2
deleted file mode 100644
index 76dbc2f..0000000
--- a/src/experimental/ofx/explore/reply_post2
+++ /dev/null
@@ -1,26 +0,0 @@
-up result 0
-HTTP/1.0 200 OK
-Server: Netscape-Enterprise/2.01
-Date: Sat, 11 Apr 1998 12:44:11 GMT
-Content-type: application/x-ofx
-
-OFXHEADER:100
-DATA:OFXSGML
-VERSION:102
-SECURITY:NONE
-ENCODING:USASCII
-
-<OFX>
-<SIGNONMSGSRSV1>
-<SONRS>
-<STATUS>
-<CODE>0
-<SEVERITY>INFO
-</STATUS>
-<DTSERVER>19980411124411.000
-<LANGUAGE>ENG
-<DTPROFUP>19971105140000
-</SONRS>
-</SIGNONMSGSRSV1>
-</OFX>
-down result 0 2024
diff --git a/src/experimental/ofx/explore/req1 b/src/experimental/ofx/explore/req1
deleted file mode 100644
index 6e45018..0000000
--- a/src/experimental/ofx/explore/req1
+++ /dev/null
@@ -1,43 +0,0 @@
-POST /cgi-ofx/etradeofx HTTP/1.0
-User-Agent: MyApp 5.0
-Content-Type: application/x-ofx
-Content-Length: 537
-
-OFXHEADER:100
-DATA:OFXSGML
-VERSION:102
-SECURITY:TYPE1
-ENCODING:USASCII
-
-<OFX>
-<SIGNONMSGSRQV1>
-<SONRQ>
-<DTCLIENT>19980410101000
-<USERID>FW5853
-<USERPASS>xxxxx
-<LANGUAGE>ENG
-<APPID>GNUCash_OFX
-<APPVER>0001
-</SONRQ>
-</SIGNONMSGSRQV1>
-<INVSTMTMSGSRQV1>
-<INVSTMTTRNRQ>
-<TRNUID>1001
-<INVSTMTRQ>
-<INVACCTFROM>
-<BROKERID>etrade.com
-<ACCTID>5853
-</INVACCTFROM>
-<INCTRAN>
-<DTSTART>19970824130105
-<INCLUDE>Y
-</INCTRAN>
-<INCOO>Y
-<INCPOS>
-<INCLUDE>Y
-</INCPOS>
-<INCBAL>Y
-</INVSTMTRQ>
-</INVSTMTTRNRQ>
-</INVSTMTMSGSRQV1>
-</OFX>
diff --git a/src/experimental/ofx/explore/req1_orig b/src/experimental/ofx/explore/req1_orig
deleted file mode 100644
index 4a0f9cc..0000000
--- a/src/experimental/ofx/explore/req1_orig
+++ /dev/null
@@ -1,33 +0,0 @@
-<OFX> <!--Beginning of request data-->
-<SIGNONMSGSRQV1>
-<SONRQ> <!--Beginning of signon-->
-<DTCLIENT>19980410101000 <!--Datetime, 8/28/96, 10:10:00 am-->
-<USERID>FW5853 <!--User ID (e.g. SSN) -->
-<USERPASS>xxxxx <!--Password(SSL encrypts whole) -->
-<LANGUAGE>ENG <!--Use English for the response -->
-<APPID>GNUCash OFX Test <!--Client application ID-->
-<APPVER>0001 <!--Version 5.0-->
-</SONRQ> <!--End of signon-->
-</SIGNONMSGSRQV1>
-<INVSTMTMSGSRQV1>
-<INVSTMTTRNRQ> <!--First request in file-->
-<TRNUID>1001 <!--Unique ID for this request-->
-<INVSTMTRQ> <!--Beginning of statement download-->
-<INVACCTFROM> <!--Identify the account: -->
-<BROKERID>etrade.com <!--FI ID-->
-<ACCTID>5853 <!--Account number-->
-</INVACCTFROM> <!--End of account ID-->
-<INCTRAN> <!--Request transactions-->
-<DTSTART>19970824130105 <!--Send transactions posted after-->
-<!--Aug 24, 1996 1:01:05pm-->
-<INCLUDE>Y <!--Include transactions -->
-</INCTRAN>
-<INCOO>Y <!--Include open orders in response-->
-<INCPOS> <!--Request positions -->
-<INCLUDE>Y <!--Include current positions -->
-</INCPOS>
-<INCBAL>Y <!--Include balances in request-->
-</INVSTMTRQ>
-</INVSTMTTRNRQ> <!--End of first request-->
-</INVSTMTMSGSRQV1>
-</OFX> <!--End of Open Financial Exchangerequest data-->
diff --git a/src/experimental/ofx/explore/req5 b/src/experimental/ofx/explore/req5
deleted file mode 100644
index ac6c61a..0000000
--- a/src/experimental/ofx/explore/req5
+++ /dev/null
@@ -1,23 +0,0 @@
-POST /cgi-ofx/etradeofx HTTP/1.0
-User-Agent: MyApp 5.0
-Content-Type: application/x-ofx
-Content-Length: 288
-
-OFXHEADER:100
-DATA:OFXSGML
-VERSION:102
-SECURITY:TYPE1
-ENCODING:USASCII
-
-<OFX>
-<SIGNONMSGSRQV1>
-<SONRQ>
-<DTCLIENT>19980410093500
-<USERID>anonymous00000000000000000000000
-<USERPASS>anonymous00000000000000000000000
-<LANGUAGE>ENG
-<APPID>GNUCash
-<APPVER>0001
-</SONRQ>
-</SIGNONMSGSRQV1>
-</OFX>
diff --git a/src/experimental/ofx/explore/req7 b/src/experimental/ofx/explore/req7
deleted file mode 100644
index 1cf3e40..0000000
--- a/src/experimental/ofx/explore/req7
+++ /dev/null
@@ -1,57 +0,0 @@
-POST /cgi-ofx/etradeofx HTTP/1.0
-User-Agent: MyApp 5.0
-Content-Type: application/x-ofx
-Content-Length: 692
-
-OFXHEADER:100
-DATA:OFXSGML
-VERSION:102
-SECURITY:TYPE1
-ENCODING:USASCII
-
-<OFX>
-<SIGNONMSGSRQV1>
-<SONRQ>
-<DTCLIENT>19980411101000
-</DTCLIENT>
-<USERID>xxxxxx
-</USERID>
-<USERPASS>xxxxxx
-</USERPASS>
-<LANGUAGE>ENG
-</LANGUAGE>
-<APPID>GNUCash_OFX
-</APPID>
-<APPVER>0001
-</APPVER>
-</SONRQ>
-</SIGNONMSGSRQV1>
-<INVSTMTMSGSRQV1>
-<INVSTMTTRNRQ>
-<TRNUID>1001
-</TRNUID>
-<INVSTMTRQ>
-<INVACCTFROM>
-<BROKERID>etrade.com
-</BROKERID>
-<ACCTID>xxxx-xxxx
-</ACCTID>
-</INVACCTFROM>
-<INCTRAN>
-<DTSTART>19970824130105
-</DTSTART>
-<INCLUDE>Y
-</INCLUDE>
-</INCTRAN>
-<INCOO>Y
-</INCOO>
-<INCPOS>
-<INCLUDE>Y
-</INCLUDE>
-</INCPOS>
-<INCBAL>Y
-</INCBAL>
-</INVSTMTRQ>
-</INVSTMTTRNRQ>
-</INVSTMTMSGSRQV1>
-</OFX>
Summary of changes:
src/experimental/Makefile.am | 6 -
src/experimental/README | 3 -
src/experimental/cbb/Makefile.am | 6 -
src/experimental/cbb/cbb-engine/CBBlib-auto.pl | 523 -------
src/experimental/cbb/cbb-engine/CBBlib-auto.plp | 165 ---
src/experimental/cbb/cbb-engine/CBBlib.pl | 1739 -----------------------
src/experimental/cbb/cbb-engine/Makefile.am | 6 -
src/experimental/cbb/cbb-engine/common.pl | 478 -------
src/experimental/cbb/cbb-old-to-cbb-alpha | 602 --------
src/experimental/cbb/cbb-to-xacc | 264 ----
src/experimental/cgi-bin/Makefile.am | 35 -
src/experimental/cgi-bin/README | 82 --
src/experimental/cgi-bin/fastcgi-hello.c | 74 -
src/experimental/cgi-bin/gnc-server.c | 410 ------
src/experimental/cgi-bin/hello.c | 99 --
src/experimental/cgi-bin/hello2.c | 137 --
src/experimental/cgi-bin/hello3.c | 155 --
src/experimental/cgi-bin/login.html | 40 -
src/experimental/gg/Makefile.am | 6 -
src/experimental/gg/README | 20 -
src/experimental/gg/canvas-test.scm | 83 --
src/experimental/gg/gnucash-sample.scm | 96 --
src/experimental/gg/hello-world.scm | 49 -
src/experimental/ofx/README | 10 -
src/experimental/ofx/explore/Makefile.am | 11 -
src/experimental/ofx/explore/README.OFX | 76 -
src/experimental/ofx/explore/length.cc | 51 -
src/experimental/ofx/explore/parse_error | 7 -
src/experimental/ofx/explore/post2.ofx | 29 -
src/experimental/ofx/explore/reply_post2 | 26 -
src/experimental/ofx/explore/req1 | 43 -
src/experimental/ofx/explore/req1_orig | 33 -
src/experimental/ofx/explore/req5 | 23 -
src/experimental/ofx/explore/req7 | 57 -
34 files changed, 5444 deletions(-)
delete mode 100644 src/experimental/Makefile.am
delete mode 100644 src/experimental/README
delete mode 100644 src/experimental/cbb/Makefile.am
delete mode 100644 src/experimental/cbb/cbb-engine/CBBlib-auto.pl
delete mode 100644 src/experimental/cbb/cbb-engine/CBBlib-auto.plp
delete mode 100644 src/experimental/cbb/cbb-engine/CBBlib.pl
delete mode 100644 src/experimental/cbb/cbb-engine/Makefile.am
delete mode 100644 src/experimental/cbb/cbb-engine/common.pl
delete mode 100644 src/experimental/cbb/cbb-old-to-cbb-alpha
delete mode 100644 src/experimental/cbb/cbb-to-xacc
delete mode 100644 src/experimental/cgi-bin/Makefile.am
delete mode 100644 src/experimental/cgi-bin/README
delete mode 100644 src/experimental/cgi-bin/fastcgi-hello.c
delete mode 100644 src/experimental/cgi-bin/gnc-server.c
delete mode 100644 src/experimental/cgi-bin/hello.c
delete mode 100644 src/experimental/cgi-bin/hello2.c
delete mode 100644 src/experimental/cgi-bin/hello3.c
delete mode 100644 src/experimental/cgi-bin/login.html
delete mode 100644 src/experimental/gg/Makefile.am
delete mode 100644 src/experimental/gg/README
delete mode 100644 src/experimental/gg/canvas-test.scm
delete mode 100644 src/experimental/gg/gnucash-sample.scm
delete mode 100644 src/experimental/gg/hello-world.scm
delete mode 100644 src/experimental/ofx/README
delete mode 100644 src/experimental/ofx/explore/Makefile.am
delete mode 100644 src/experimental/ofx/explore/README.OFX
delete mode 100644 src/experimental/ofx/explore/length.cc
delete mode 100644 src/experimental/ofx/explore/parse_error
delete mode 100644 src/experimental/ofx/explore/post2.ofx
delete mode 100644 src/experimental/ofx/explore/reply_post2
delete mode 100644 src/experimental/ofx/explore/req1
delete mode 100644 src/experimental/ofx/explore/req1_orig
delete mode 100644 src/experimental/ofx/explore/req5
delete mode 100644 src/experimental/ofx/explore/req7
More information about the gnucash-changes
mailing list