From b42d9a345e2b02a1b17fa61b22117fbf7b187a31 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 11 May 2012 11:19:04 +0200 Subject: 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. --- cli/parser.cxx | 103 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 32 deletions(-) (limited to 'cli/parser.cxx') 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 // stat +#include // stat +#include // stat + #include #include @@ -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 (p, 1, 1)); - root_->new_edge (*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 new_cur (cur_, &n); - auto_restore 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 (p, 1, 1)); + root_->new_edge (*cur_, n, ik, f); + include_map_[ap] = &n; + + auto_restore new_cur (cur_, &n); + auto_restore new_path (path_, &p); + + ifstream ifs (p.string ().c_str ()); + if (ifs.is_open ()) { - lexer l (ifs, p.string ()); - auto_restore new_lexer (lexer_, &l); + ifs.exceptions (ifstream::failbit | ifstream::badbit); + + try + { + lexer l (ifs, p.string ()); + auto_restore 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 (*cur_, *it->second, ik, f); } - else - root_->new_edge (*cur_, *it->second, ik, f); } } -- cgit v1.1