aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-19 16:36:51 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-06-19 16:36:51 +0200
commit21b6e3ebeba9518259aae67954b51f5f6261b944 (patch)
tree991da5719a84db8c599c9b538d27536ad476ab65
parentad82296958864bd7302be345e4b25003e307334f (diff)
Distinguish between database and C++ type mapping
-rw-r--r--odb/pragma.cxx97
1 files changed, 89 insertions, 8 deletions
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 2994aa1..fec7014 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -2959,7 +2959,7 @@ handle_pragma_qualifier (cxx_lexer& l, string p)
pragma::add_func adder (0); // Custom context adder.
bool ns (false); // Namespace location pragma.
- cxx_tokens saved_tokens; // Saved token seuqnece to be replayed.
+ cxx_tokens saved_tokens; // Saved token sequence to be replayed.
// Pragma qualifiers.
//
@@ -2972,17 +2972,98 @@ handle_pragma_qualifier (cxx_lexer& l, string p)
else if (p == "map")
{
// map type("<regex>") as("<subst>") [to("<subst>")] [from("<subst>")]
+ // map type(<c++-type>) as(<c++-type>) [to(<expr>)] [from(<expr>)]
//
- using relational::custom_db_type;
- custom_db_type ct;
- ct.loc = loc;
- val = ct;
- name = "custom-db-types";
+ // The thing that determines whether this is a database or C++ type
+ // mapping is what we have inside 'type'. So to handle this we are
+ // going to pre-scan the pragma looking for 'type' and saving the
+ // tokens. Once we determine what this is, we replay the saved
+ // tokens to actually parse them.
+ //
+
+ // Determine what this is by scanning the pragma until we see
+ // the 'type' qualifier or EOF.
+ //
+ bool db (true);
+
+ bool done (false);
+ size_t balance (0);
+ for (tt = l.next (tl, &tn);
+ !(done && balance == 0) && tt != CPP_EOF;
+ tt = l.next (tl, &tn))
+ {
+ saved_tokens.push_back (cxx_token (l.location (), tt, tl, tn));
+
+ switch (tt)
+ {
+ case CPP_OPEN_PAREN:
+ {
+ balance++;
+ continue;
+ }
+ case CPP_CLOSE_PAREN:
+ {
+ if (balance > 0)
+ balance--;
+ else
+ {
+ error (l) << "unbalanced parenthesis in db pragma " << p << endl;
+ return;
+ }
+ continue;
+ }
+ case CPP_NAME:
+ {
+ if (balance == 0 && tl == "type")
+ break;
+
+ continue;
+ }
+ default:
+ continue;
+ }
+
+ tt = l.next (tl, &tn);
+ saved_tokens.push_back (cxx_token (l.location (), tt, tl, tn));
+
+ if (tt == CPP_OPEN_PAREN)
+ {
+ balance++;
+
+ tt = l.next (tl, &tn);
+ saved_tokens.push_back (cxx_token (l.location (), tt, tl, tn));
+
+ db = (tt == CPP_STRING);
+ }
+
+ done = true; // Scan until the closing ')'.
+ }
+
+ if (balance != 0)
+ {
+ error (l) << "unbalanced parenthesis in db pragma " << p << endl;
+ return;
+ }
+
orig_decl = global_namespace;
decl = declaration (orig_decl);
- adder = &accumulate<custom_db_type>;
- tt = l.next (tl, &tn);
+
+ if (db)
+ {
+ using relational::custom_db_type;
+
+ custom_db_type ct;
+ ct.loc = loc;
+ val = ct;
+ name = "custom-db-types";
+ adder = &accumulate<custom_db_type>;
+ }
+ else
+ {
+ error (loc) << "custom C++ type!" << endl;
+ return;
+ }
}
else if (p == "index")
{