src/util/counter.h \
src/util/forbid_copy.h \
src/util/free_list.h \
+ src/util/get_dir.h \
src/util/hash32.h \
src/util/local_increment.h \
src/util/lookup.h \
src/ast/scanner.cc \
src/ast/unescape.cc \
src/ast/validate.cc \
+ src/util/get_dir.cc \
src/util/s_to_n32_unsafe.cc \
src/util/range.cc
re2c_SOURCES = \
-/* Generated by re2c 1.1.1 on Tue Dec 25 23:07:11 2018 */
+/* Generated by re2c 1.1.1 on Thu Dec 27 23:18:50 2018 */
#line 1 "../src/conf/parse_opts.re"
#include "src/code/input_api.h"
#include "src/conf/msg.h"
error ("no source file");
return EXIT_FAIL;
}
- globopts.fix(opts.source_file);
+ globopts.fix();
return OK;
#include "src/ast/input.h"
#include "src/ast/scanner.h"
#include "src/conf/msg.h"
+#include "src/util/get_dir.h"
#include "src/util/string_utils.h"
namespace re2c {
, line(1)
{}
-bool Input::open(const std::string &filename)
-{
- name = escaped_name = filename;
- strrreplace(escaped_name, "\\", "\\\\");
-
- file = name == "<stdin>" ? stdin : fopen(name.c_str(), "rb");
- if (!file) {
- error("cannot open file: %s", name.c_str());
- return false;
- }
-
- return true;
-}
-
-bool Input::open_in_dirs(const std::string &filename
+bool Input::open(const std::string &filename, const std::string *parent
, const std::vector<std::string> &incpaths)
{
- name = escaped_name = filename;
- strrreplace(escaped_name, "\\", "\\\\");
+ std::string path;
+ name = filename;
- for (size_t i = 0; !file && i < incpaths.size(); ++i) {
- const std::string path = incpaths[i] + name;
+ if (!parent) {
+ path = name;
+ file = name == "<stdin>" ? stdin : fopen(name.c_str(), "rb");
+ }
+ else {
+ // first, search relative to the directory of including file
+ path = *parent;
+ get_dir(path);
+ path += name;
file = fopen(path.c_str(), "rb");
+
+ // otherwise search in all include paths
+ for (size_t i = 0; !file && i < incpaths.size(); ++i) {
+ path = incpaths[i] + name;
+ file = fopen(path.c_str(), "rb");
+ }
}
+
if (!file) {
- error("cannot open file: %s", name.c_str());
+ fatal("cannot open file: %s", name.c_str());
return false;
}
+ // name displayed in #line directives is the resolved name
+ escaped_name = path;
+ strrreplace(escaped_name, "\\", "\\\\");
+
return true;
}
Input();
~Input();
- bool open(const std::string &);
- bool open_in_dirs(const std::string &, const std::vector<std::string> &);
+ bool open(const std::string &filename, const std::string *parent
+ , const std::vector<std::string> &incpaths);
FORBID_COPY(Input);
};
{
Input *in = new Input;
files.push_back(in);
- return in->open(filename);
+ return in->open(filename, NULL, globopts->incpaths);
}
bool Scanner::include(const std::string &filename)
{
+ // get name of the current file (before unreading)
+ const std::string &parent = get_fname();
+
// unread buffer tail: we'll return to it later
- // file fragments are laid out left-to-right from nested to outer
+ // In the buffer nested files go before outer files. In the file stack,
+ // however, outer files go before nested files (nested are at the top).
+ // We want to break from the unreading cycle early, therefore we go in
+ // reverse order of file offsets in buffer and break as soon as the end
+ // offset is less than cursor (current position).
for (size_t i = 0; i < files.size(); ++i) {
Input *in = files[i];
if (in->so >= cur) {
// open new file and place place at the top of stack
Input *in = new Input;
files.push_back(in);
- if (!in->open_in_dirs(filename, globopts->incpaths)) return false;
+ if (!in->open(filename, &parent, globopts->incpaths)) return false;
// refill buffer (discard everything up to cursor, clear EOF)
lim = cur = mar = ctx = tok = ptr = pos = bot + BSIZE;
namespace re2c
{
-static void get_dir(std::string &path)
-{
- // scan the path backwards until the first slash (if any) and clip
- size_t i = path.length();
- for (; i > 0; --i) {
- const char c = path[i - 1];
- if (c == '/' || c == '\\') break;
- }
- path.resize(i);
- if (i == 0) path.push_back('.');
-}
-
-void conopt_t::fix(const char *filename)
+void conopt_t::fix()
{
if (target == TARGET_SKELETON) {
fFlag = false;
}
- // first include path must be the directory of the source file
- std::string path(filename);
- get_dir(path);
- incpaths.insert(incpaths.begin(), path);
// append directory separator '/' to all paths that do not have it
for (size_t i = 0; i < incpaths.size(); ++i) {
std::string &p = incpaths[i];
# undef CONSTOPT1
# undef CONSTOPT
{}
- void fix(const char *filename);
+ void fix();
FORBID_COPY(conopt_t);
};
error ("no source file");
return EXIT_FAIL;
}
- globopts.fix(opts.source_file);
+ globopts.fix();
return OK;