From 21b6e3ebeba9518259aae67954b51f5f6261b944 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 19 Jun 2015 16:36:51 +0200 Subject: Distinguish between database and C++ type mapping --- odb/pragma.cxx | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file 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("") as("") [to("")] [from("")] + // map type() as() [to()] [from()] // - 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; - 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; + } + else + { + error (loc) << "custom C++ type!" << endl; + return; + } } else if (p == "index") { -- cgit v1.1