text: #include "Numbertext.hxx"
  #include "numbertext-version.h"
  #include <cstring>
  
  #ifdef HAVE_BOOST_REGEX
    using namespace boost;
  #else
    using namespace std;
  #endif
  
  #define LANG "LANG"
  #define PATH "NUMBERTEXTPATH"
  #define DEFPATH DATADIR "/libnumbertext/"
  #define DEFPATH2 "data/"
  
  enum State { base, loaded, flag_lang, flag_prefix};
  
  void error()
  {
      std::cerr << "spellout: missing language module" << std::endl;
      std::exit(EXIT_FAILURE);
  }
  
  int main(int argc, char* argv[])
  {
      if (argc == 1) {
          std::cout << "spellout " NUMBERTEXT_VERSION ": convert numbers to number names and money amounts" << std::endl;
          std::cout << "Usage: spellout [-l lang] [-p prefix] par1 [par2...]" << std::endl;
          std::cout << "Parameter: n: number; n-m: range; n-m~s: range with step" << std::endl;
          std::cout << "Examples: spellout 1-10 500 1000-10000~1000" << std::endl;
          std::cout << "          spellout -l en-GB -p ordinal 1-100" << std::endl;
          std::cout << "          spellout -l en -p ordinal-number 1-100" << std::endl;
          std::cout << "          spellout -l en -p USD 100.45" << std::endl;
          std::cout << "          spellout -l en -p \"money USD\" 100.45" << std::endl;
          std::cout << "Help of language module: spellout -l es help" << std::endl;
          std::cout << "License: GNU LGPL/BSD dual-license\n";
          return 0;
      }
      std::vector <std::string> paths;
      paths.emplace_back("");
      paths.emplace_back(DEFPATH);
      paths.emplace_back(DEFPATH2);
  
      if (getenv(PATH))
          paths.insert(paths.begin() + 1, std::string(getenv(PATH)) + "/");
      std::string lang;
  
      Numbertext nt;
      State state = State::base;
      std::string prefix;
      for (int i = 1; i < argc; i++)
      {
          if (state == State::flag_lang || state == State::flag_prefix)
          {
              if (state == State::flag_lang)
              {
                  lang = argv[i];
              }
              else
              {
                  prefix = argv[i];
                  prefix += " ";
              }
              state = State::base;
              continue;
          }
          if (strcmp(argv[i], "-l") == 0)
          {
              state = State::flag_lang;
          }
          else if (strcmp(argv[i], "-p") == 0)
          {
              state = State::flag_prefix;
          }
          else
          {
              if (lang.empty()) {
                  if (getenv(LANG)) {
                      lang = std::string(getenv(LANG));
                      lang = lang.substr(0, lang.find("."));
                  }
                  if (lang.empty())
                      lang = "en";
              }
  
              if (state != State::loaded) {
                  for(auto const& path: paths) {
                      nt.set_prefix(path);
                      if (nt.load(lang))
                          break;
                  }
                  state = State::loaded;
              }
  
              std::string arg = argv[i];
              smatch n;
              if (regex_match(arg, n, regex("([0-9]+)-([0-9]+)~?([0-9]+)?")))
              {
                  long long b = std::stoll(n[1].str());
                  long long end = std::stoll(n[2].str());
                  long long step = (n[3].length() == 0) ? 1 : std::stoll(n[3].str());
                  for (int j = b; j <= end; j = j + step) {
                      std::string result = prefix + std::to_string(j);
                      if (!nt.numbertext(result, lang))
                          error();
                      std::cout << result << std::endl;
                  }
              }
              else
              {
                  std::string result = prefix + arg;
                  if (!nt.numbertext(result, lang))
                      error();
                  std::cout << result << std::endl;
              }
          }
      }
  }
  