<commit_before>#include "config.h"
#include "acconf.h"
#include "option.h"
#include "datetime.h"
#include "quotes.h"
#include "valexpr.h"
#include "walk.h"

#include <fstream>
#include <ctime>
#include <cstdlib>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

namespace ledger {

std::list<option_t> config_options;

static config_t * config = NULL;

void config_t::reset()
{
  amount_expr	     = "a";
  total_expr	     = "O";
  total_expr_template = "#";
  pricing_leeway     = 24 * 3600;
  budget_flags       = BUDGET_NO_BUDGET;
  balance_format     = "%20T  %2_%-a\n";
  register_format    = ("%D %-.20P %-.22A %12.67t %12.80T\n%/"
			"%32|%-.22A %12.67t %12.80T\n");
  wide_register_format = ("%D  %-.35P %-.38A %22.108t %22.132T\n%/"
			  "%48|%-.38A %22.108t %22.132T\n");
  csv_register_format = "\"%D\",\"%P\",\"%A\",\"%t\",\"%T\"\n";
  plot_amount_format = "%D %(St)\n";
  plot_total_format  = "%D %(ST)\n";
  print_format       = "\n%d %Y%C%P\n    %-34W  %12o%n\n%/    %-34W  %12o%n\n";
  write_hdr_format   = "%d %Y%C%P\n";
  write_xact_format  = "    %-34W  %12o%n\n";
  equity_format      = "\n%D %Y%C%P\n%/    %-34W  %12t\n";
  prices_format      = "%[%Y/%m/%d %H:%M:%S %Z]   %-10A %12t %12T\n";
  pricesdb_format    = "P %[%Y/%m/%d %H:%M:%S] %A %t\n";

  predicate	    = "";
  display_predicate = "";

  head_entries = 0;
  tail_entries = 0;

  show_collapsed     = false;
  show_subtotal      = false;
  show_totals        = false;
  show_related       = false;
  show_all_related   = false;
  show_inverted      = false;
  show_empty	     = false;
  days_of_the_week   = false;
  by_payee           = false;
  comm_as_payee      = false;
  show_revalued      = false;
  show_revalued_only = false;
  download_quotes    = false;

  use_cache	     = false;
  cache_dirty        = false;
}

void
config_t::regexps_to_predicate(const std::string& command,
			       std::list<std::string>::const_iterator begin,
			       std::list<std::string>::const_iterator end,
			       const bool account_regexp,
			       const bool add_account_short_masks,
			       const bool logical_and)
{
  std::string regexps[2];

  assert(begin != end);

  // Treat the remaining command-line arguments as regular
  // expressions, used for refining report results.

  for (std::list<std::string>::const_iterator i = begin;
       i != end;
       i++)
    if ((*i)[0] == '-') {
      if (! regexps[1].empty())
	regexps[1] += "|";
      regexps[1] += (*i).substr(1);
    }
    else if ((*i)[0] == '+') {
      if (! regexps[0].empty())
	regexps[0] += "|";
      regexps[0] += (*i).substr(1);
    }
    else {
      if (! regexps[0].empty())
	regexps[0] += "|";
      regexps[0] += *i;
    }

  for (int i = 0; i < 2; i++) {
    if (regexps[i].empty())
      continue;

    if (! predicate.empty())
      predicate += logical_and ? "&" : "|";

    int add_predicate = 0;	// 1 adds /.../, 2 adds ///.../
    if (i == 1) {
      predicate += "!";
    }
    else if (add_account_short_masks) {
      if (regexps[i].find(':') != std::string::npos ||
	  regexps[i].find('.') != std::string::npos ||
	  regexps[i].find('*') != std::string::npos ||
	  regexps[i].find('+') != std::string::npos ||
	  regexps[i].find('[') != std::string::npos ||
	  regexps[i].find('(') != std::string::npos) {
	show_subtotal = true;
	add_predicate = 1;
      } else {
	add_predicate = 2;
      }
    }
    else {
      add_predicate = 1;
    }

    if (i != 1 && command == "b" && account_regexp) {
      if (! display_predicate.empty())
	display_predicate += "&";
      else if (! show_empty)
	display_predicate += "T&";

      if (add_predicate == 2)
	display_predicate += "//";
      display_predicate += "/(?:";
      display_predicate += regexps[i];
      display_predicate += ")/";
    }

    if (! account_regexp)
      predicate += "/";
    predicate += "/(?:";
    predicate += regexps[i];
    predicate += ")/";
  }
}

bool config_t::process_option(const std::string& opt, const char * arg)
{
  config = this;
  bool result = ::process_option(config_options, opt, arg);
  config = NULL;
  return result;
}

void config_t::process_arguments(int argc, char ** argv, const bool anywhere,
				 std::list<std::string>& args)
{
  config = this;
  ::process_arguments(config_options, argc, argv, anywhere, args);
  config = NULL;
}

void config_t::process_environment(char ** envp, const std::string& tag)
{<commit_msg>(config_t::regexps_to_predicate): Don't set the display predicate to show only matching accounts when the --related flag is in use (which was effectively masking out the whole point of using --related with balance reports).<commit_after>#include "config.h"
#include "acconf.h"
#include "option.h"
#include "datetime.h"
#include "quotes.h"
#include "valexpr.h"
#include "walk.h"

#include <fstream>
#include <ctime>
#include <cstdlib>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

namespace ledger {

std::list<option_t> config_options;

static config_t * config = NULL;

void config_t::reset()
{
  amount_expr	     = "a";
  total_expr	     = "O";
  total_expr_template = "#";
  pricing_leeway     = 24 * 3600;
  budget_flags       = BUDGET_NO_BUDGET;
  balance_format     = "%20T  %2_%-a\n";
  register_format    = ("%D %-.20P %-.22A %12.67t %12.80T\n%/"
			"%32|%-.22A %12.67t %12.80T\n");
  wide_register_format = ("%D  %-.35P %-.38A %22.108t %22.132T\n%/"
			  "%48|%-.38A %22.108t %22.132T\n");
  csv_register_format = "\"%D\",\"%P\",\"%A\",\"%t\",\"%T\"\n";
  plot_amount_format = "%D %(St)\n";
  plot_total_format  = "%D %(ST)\n";
  print_format       = "\n%d %Y%C%P\n    %-34W  %12o%n\n%/    %-34W  %12o%n\n";
  write_hdr_format   = "%d %Y%C%P\n";
  write_xact_format  = "    %-34W  %12o%n\n";
  equity_format      = "\n%D %Y%C%P\n%/    %-34W  %12t\n";
  prices_format      = "%[%Y/%m/%d %H:%M:%S %Z]   %-10A %12t %12T\n";
  pricesdb_format    = "P %[%Y/%m/%d %H:%M:%S] %A %t\n";

  predicate	    = "";
  display_predicate = "";

  head_entries = 0;
  tail_entries = 0;

  show_collapsed     = false;
  show_subtotal      = false;
  show_totals        = false;
  show_related       = false;
  show_all_related   = false;
  show_inverted      = false;
  show_empty	     = false;
  days_of_the_week   = false;
  by_payee           = false;
  comm_as_payee      = false;
  show_revalued      = false;
  show_revalued_only = false;
  download_quotes    = false;

  use_cache	     = false;
  cache_dirty        = false;
}

void
config_t::regexps_to_predicate(const std::string& command,
			       std::list<std::string>::const_iterator begin,
			       std::list<std::string>::const_iterator end,
			       const bool account_regexp,
			       const bool add_account_short_masks,
			       const bool logical_and)
{
  std::string regexps[2];

  assert(begin != end);

  // Treat the remaining command-line arguments as regular
  // expressions, used for refining report results.

  for (std::list<std::string>::const_iterator i = begin;
       i != end;
       i++)
    if ((*i)[0] == '-') {
      if (! regexps[1].empty())
	regexps[1] += "|";
      regexps[1] += (*i).substr(1);
    }
    else if ((*i)[0] == '+') {
      if (! regexps[0].empty())
	regexps[0] += "|";
      regexps[0] += (*i).substr(1);
    }
    else {
      if (! regexps[0].empty())
	regexps[0] += "|";
      regexps[0] += *i;
    }

  for (int i = 0; i < 2; i++) {
    if (regexps[i].empty())
      continue;

    if (! predicate.empty())
      predicate += logical_and ? "&" : "|";

    int add_predicate = 0;	// 1 adds /.../, 2 adds ///.../
    if (i == 1) {
      predicate += "!";
    }
    else if (add_account_short_masks) {
      if (regexps[i].find(':') != std::string::npos ||
	  regexps[i].find('.') != std::string::npos ||
	  regexps[i].find('*') != std::string::npos ||
	  regexps[i].find('+') != std::string::npos ||
	  regexps[i].find('[') != std::string::npos ||
	  regexps[i].find('(') != std::string::npos) {
	show_subtotal = true;
	add_predicate = 1;
      } else {
	add_predicate = 2;
      }
    }
    else {
      add_predicate = 1;
    }

    if (i != 1 && command == "b" && account_regexp) {
      if (! show_related && ! show_all_related) {
	if (! display_predicate.empty())
	  display_predicate += "&";
	else if (! show_empty)
	  display_predicate += "T&";

	if (add_predicate == 2)
	  display_predicate += "//";
	display_predicate += "/(?:";
	display_predicate += regexps[i];
	display_predicate += ")/";
      }
      else if (! show_empty) {
	display_predicate += "T";
      }
    }

    if (! account_regexp)
      predicate += "/";
    predicate += "/(?:";
    predicate += regexps[i];
    predicate += ")/";
  }
}

bool config_t::process_option(const std::string& opt, const char * arg)
{
  config = this;
  bool result = ::process_option(config_options, opt, arg);
  config = NULL;
  return result;
}

void config_t::process_arguments(int argc, char ** argv, const bool anywhere,
				 std::list<std::string>& args)
{
  config = this;
  ::process_arguments(config_options, argc, argv, anywhere, args);
  config = NULL;
}

void config_t::process_environment(char ** envp, const std::string& tag)
{
{'fraction_non_alphanumeric': 0.19213064445418676, 'fraction_numerical': 0.024550635686102586, 'mean_word_length': 2.803668195081284, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '438195', 'n_tokens_mistral': 3722, 'n_tokens_neox': 3507, 'n_words': 697}