// examples/escape translated by mycpp

// BEGIN mycpp output

#include "mycpp/runtime.h"

GLOBAL_STR(str0, "\\");
GLOBAL_STR(str1, "");
GLOBAL_STR(str2, "\\*?[]-:!");
GLOBAL_STR(str3, ".");
GLOBAL_STR(str4, "NOT IN .");
GLOBAL_STR(str5, "*");
GLOBAL_STR(str6, "NOT IN *");
GLOBAL_STR(str7, "result: %s");
GLOBAL_STR(str8, "echo *.[ch] *.?");
GLOBAL_STR(str9, "echo *.[ch] *.?");

namespace escape {  // forward declare


}  // forward declare namespace escape

namespace escape {  // declare

BigStr* BackslashEscape(BigStr* s, BigStr* meta_chars);
extern BigStr* GLOB_META_CHARS;
void TestNotIn();
void run_tests();
void run_benchmarks();

}  // declare namespace escape

namespace escape {  // define


BigStr* BackslashEscape(BigStr* s, BigStr* meta_chars) {
  List<BigStr*>* escaped = nullptr;
  StackRoot _root0(&s);
  StackRoot _root1(&meta_chars);
  StackRoot _root2(&escaped);

  escaped = Alloc<List<BigStr*>>();
  for (StrIter it(s); !it.Done(); it.Next()) {
    BigStr* c = it.Value();
    StackRoot _for(&c  );
    if (str_contains(meta_chars, c)) {
      escaped->append(str0);
    }
    escaped->append(c);
  }
  return str1->join(escaped);
}
BigStr* GLOB_META_CHARS = str2;

void TestNotIn() {
  if (!str_contains(GLOB_META_CHARS, str3)) {
    print(str4);
  }
  if (!str_contains(GLOB_META_CHARS, str5)) {
    print(str6);
  }
}

void run_tests() {
  mylib::print_stderr(StrFormat("result: %s", BackslashEscape(str8, GLOB_META_CHARS)));
  TestNotIn();
}

void run_benchmarks() {
  int i;
  int n;
  BigStr* s = nullptr;
  StackRoot _root0(&s);

  i = 0;
  n = 200000;
  while (i < n) {
    s = str9;
    BackslashEscape(s, GLOB_META_CHARS);
    i = (i + 1);
    mylib::MaybeCollect();
  }
}

}  // define namespace escape

int main(int argc, char **argv) {
  gHeap.Init();

  char* b = getenv("BENCHMARK");
  if (b && strlen(b)) {  // match Python's logic
    fprintf(stderr, "Benchmarking...\n");
    escape::run_benchmarks();
  } else {
    escape::run_tests();
  }

  gHeap.CleanProcessExit();
}