#include <cstdio>
using std::printf;
#include <string>
#include <sstream>

aspect StringTracer {
 public:
  advice call ("% foo(... :: basic_string<char,...>)" && !"% printf(...)") : before () {
    printf ("calling %s\n", JoinPoint::signature ());
  }
  advice call ("% std::...::%(...)") : around () { tjp->proceed(); }
  advice execution("% build_msg(...)") : around () { tjp->proceed(); }
};

//void foo(std::string s) {
void foo(std::basic_string<char> s) {
       printf("in foo(%s)\n", s.c_str ());
}

std::string build_msg(const char* signature, const char* file, int line)  {

  std::stringstream ss;
  ss << signature << " | " << file << " | " << line;
  if (line < 0)
    throw "ignore me";
  return ss.str();
}

int main () {
  printf ("STLString: checks advice weaving for the STL string class\n");
  printf ("=========================================================\n");
  foo ("this is a string");
  std::string s = build_msg("sig", "file", 42);
  printf("msg: %s\n", s.c_str());
  try {
    std::string s2 = build_msg("sig", "file", -1); // throws an exception
  } catch(const char *msg) {
    printf ("caught test exception: %s\n", msg);
  }
  printf ("=========================================================\n");
}
