diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-05-11 11:19:04 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-05-11 11:19:04 +0200 |
commit | b42d9a345e2b02a1b17fa61b22117fbf7b187a31 (patch) | |
tree | 9c8ea0116ae35cf8df86e958495fc46563d095dd /cli/parser.cxx | |
parent | 8062e4e9a4998cfa44002afd2435ff9083e092e8 (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.cxx | 103 |
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); } } |