diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx
index 1e14cbc1866a4f55063373f8a7d781f6822adf09..39dd664e0062cc3820a3105f1598f6dcac748988 100644
--- a/core/base/src/TSystem.cxx
+++ b/core/base/src/TSystem.cxx
@@ -4156,18 +4156,41 @@ TString TSystem::SplitAclicMode(const char* filename, TString &aclicMode,
                                 TString &arguments, TString &io) const
 {
    char *fname = Strip(filename);
-
-   char *arg = strchr(fname, '(');
-   // special case for $(HOME)/aap.C(10)
-   while (arg && *arg && (arg > fname && *(arg-1) == '$') && *(arg+1))
-      arg = strchr(arg+1, '(');
-   if (arg && arg > fname) {
-      *arg = 0;
-      char *t = arg-1;
-      while (*t == ' ') {
-         *t = 0; t--;
+   TString filenameCopy = fname;
+
+   if (filenameCopy.EndsWith(")")) {
+      Ssiz_t posArgEnd = filenameCopy.Length() - 1;
+      // There is an argument; find its start!
+      int parenNestCount = 1;
+      bool inString = false;
+      Ssiz_t posArgBegin = posArgEnd - 1;
+      for (; parenNestCount && posArgBegin >= 0; --posArgBegin) {
+	 // Escaped if the previous character is a `\` - but not if it
+	 // itself is preceded by a `\`!
+	 if (posArgBegin > 0 && filenameCopy[posArgBegin] == '\\' &&
+	     (posArgBegin == 1 || filenameCopy[posArgBegin - 1] != '\\')) {
+	    // skip escape.
+	    --posArgBegin;
+	    continue;
+	 }
+	 switch (filenameCopy[posArgBegin]) {
+	 case ')':
+	    if (!inString)
+	       ++parenNestCount;
+	    break;
+	 case '(':
+	    if (!inString)
+	       --parenNestCount;
+	    break;
+	 case '"': inString = !inString; break;
+	 }
+      }
+      if (parenNestCount || inString) {
+	 Error("SplitAclicMode", "Cannot parse argument in %s", filename);
+      } else {
+	 arguments = filenameCopy(posArgBegin + 1, posArgEnd - 1);
+	 fname[posArgBegin + 1] = 0;
       }
-      arg++;
    }
 
    // strip off I/O redirect tokens from filename
@@ -4226,9 +4249,6 @@ TString TSystem::SplitAclicMode(const char* filename, TString &aclicMode,
    }
 
    TString resFilename = fname;
-   arguments = "(";
-   if (arg) arguments += arg;
-   else arguments = "";
 
    delete []fname;
    return resFilename;
diff --git a/interpreter/cling/lib/MetaProcessor/MetaParser.cpp b/interpreter/cling/lib/MetaProcessor/MetaParser.cpp
index c70dce4f49ecdd6f216268d54f1967dca4e4d88f..6525686f477a8f11b68ae63fd7c7008603b7cd90 100644
--- a/interpreter/cling/lib/MetaProcessor/MetaParser.cpp
+++ b/interpreter/cling/lib/MetaProcessor/MetaParser.cpp
@@ -276,13 +276,39 @@ namespace cling {
     const Token& Tok = getCurTok();
     if (Tok.is(tok::ident) && (Tok.getIdent().equals("x")
                                || Tok.getIdent().equals("X"))) {
-      // There might be ArgList
-      consumeAnyStringToken(tok::l_paren);
-      llvm::StringRef file(getCurTok().getIdent());
       consumeToken();
-      // '(' to end of string:
+      skipWhitespace();
+
+      // There might be an ArgList:
+      int forward = 0;
+      std::string args;
+      llvm::StringRef file(getCurTok().getBufStart());
+      while (!lookAhead(forward).is(tok::eof))
+	++forward;
+      // Now track back to find the opening '('.
+      if (lookAhead(forward - 1).is(tok::r_paren)) {
+	// Trailing ')' - we interpret that as an argument.
+	--forward; // skip ')'
+	int nesting = 1;
+	while (--forward > 0 && nesting) {
+	  if (lookAhead(forward).is(tok::l_paren))
+	    --nesting;
+	  else if (lookAhead(forward).is(tok::r_paren))
+	    ++nesting;
+	}
+	if (forward == 0) {
+	  cling::errs() << "cling::MetaParser::isXCommand():"
+	    "error parsing argument in " << getCurTok().getBufStart() << '\n';
+	  // interpret everything as "the file"
+	} else {
+	  while (forward--)
+	    consumeToken();
+	  consumeToken(); // the forward-0 token.
+	  args = getCurTok().getBufStart();
+	  file = file.drop_back(args.length());
+	}
+      }
 
-      std::string args = getCurTok().getBufStart();
       if (args.empty())
         args = "()";
       actionResult = m_Actions->actOnxCommand(file, args, resultValue);