summaryrefslogtreecommitdiff
path: root/cli/parser.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-05-11 11:19:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-05-11 11:19:04 +0200
commitb42d9a345e2b02a1b17fa61b22117fbf7b187a31 (patch)
tree9c8ea0116ae35cf8df86e958495fc46563d095dd /cli/parser.cxx
parent8062e4e9a4998cfa44002afd2435ff9083e092e8 (diff)
Add support for -I option
Now quote-included ("") option files are searched for relative to the including file while bracket-included (<>) ones are search in the directories specified with -I.
Diffstat (limited to 'cli/parser.cxx')
-rw-r--r--cli/parser.cxx103
1 files changed, 71 insertions, 32 deletions
diff --git a/cli/parser.cxx b/cli/parser.cxx
index 8289fce..55090d4 100644
--- a/cli/parser.cxx
+++ b/cli/parser.cxx
@@ -3,6 +3,10 @@
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license : MIT; see accompanying LICENSE file
+#include <unistd.h> // stat
+#include <sys/types.h> // stat
+#include <sys/stat.h> // stat
+
#include <fstream>
#include <iostream>
@@ -267,56 +271,91 @@ include_decl ()
}
else
{
- // For now we only support inclusion relative to the current file.
+ path p;
+ // If this is a quote include, then include relative to the current
+ // file.
//
- path p (path_->directory () / f);
- p.normalize ();
-
- // Detect and ignore multiple inclusions.
+ if (ik == includes::quote)
+ {
+ p = path_->directory () / f;
+ p.normalize ();
+ }
+ // Otherwise search the include directories (-I).
//
- path ap (p);
- ap.absolute ();
- ap.normalize ();
-
- include_map::iterator it (include_map_.find (ap));
- if (it == include_map_.end ())
+ else
{
- cli_unit& n (root_->new_node<cli_unit> (p, 1, 1));
- root_->new_edge<cli_includes> (*cur_, n, ik, f);
- include_map_[ap] = &n;
+ struct stat s;
+ for (paths::const_iterator i (include_paths_.begin ());
+ i != include_paths_.end (); ++i)
+ {
+ p = *i / f;
+ p.normalize ();
+
+ // Check that the file exist without checking for permissions, etc.
+ //
+ if (stat (p.string ().c_str (), &s) == 0 && S_ISREG (s.st_mode))
+ break;
- auto_restore<cli_unit> new_cur (cur_, &n);
- auto_restore<path const> new_path (path_, &p);
+ p.clear ();
+ }
- ifstream ifs (p.string ().c_str ());
- if (ifs.is_open ())
+ if (p.empty ())
{
- ifs.exceptions (ifstream::failbit | ifstream::badbit);
+ cerr << *path_ << ':' << t.line () << ':' << t.column () << ": "
+ << "error: file '" << f << "' not found in any of the "
+ << "include search directories (-I)" << endl;
+ valid_ = false;
+ }
+ }
- try
+ if (valid_)
+ {
+ // Detect and ignore multiple inclusions.
+ //
+ path ap (p);
+ ap.absolute ();
+ ap.normalize ();
+
+ include_map::iterator it (include_map_.find (ap));
+ if (it == include_map_.end ())
+ {
+ cli_unit& n (root_->new_node<cli_unit> (p, 1, 1));
+ root_->new_edge<cli_includes> (*cur_, n, ik, f);
+ include_map_[ap] = &n;
+
+ auto_restore<cli_unit> new_cur (cur_, &n);
+ auto_restore<path const> new_path (path_, &p);
+
+ ifstream ifs (p.string ().c_str ());
+ if (ifs.is_open ())
{
- lexer l (ifs, p.string ());
- auto_restore<lexer> new_lexer (lexer_, &l);
+ ifs.exceptions (ifstream::failbit | ifstream::badbit);
+
+ try
+ {
+ lexer l (ifs, p.string ());
+ auto_restore<lexer> new_lexer (lexer_, &l);
- def_unit ();
+ def_unit ();
- if (!l.valid ())
+ if (!l.valid ())
+ valid_ = false;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << p << ": error: read failure" << endl;
valid_ = false;
+ }
}
- catch (std::ios_base::failure const&)
+ else
{
- cerr << p << ": error: read failure" << endl;
+ cerr << p << ": error: unable to open in read mode" << endl;
valid_ = false;
}
}
else
- {
- cerr << p << ": error: unable to open in read mode" << endl;
- valid_ = false;
- }
+ root_->new_edge<cli_includes> (*cur_, *it->second, ik, f);
}
- else
- root_->new_edge<cli_includes> (*cur_, *it->second, ik, f);
}
}