diff --git a/integration_test.py b/integration_test.py index a59ae338..e5497db3 100644 --- a/integration_test.py +++ b/integration_test.py @@ -298,3 +298,151 @@ def test_pragma_once_matching(record_property, tmpdir): assert stdout.count("ONCE") == 1 assert stderr == "" + + +def test_input_multiple(record_property, tmpdir): + test_file = os.path.join(tmpdir, "test.c") + with open(test_file, 'w'): + pass + + test_file_1 = os.path.join(tmpdir, "test1.c") + with open(test_file_1, 'w'): + pass + + args = [ + 'test.c', + 'test1.c' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: multiple filenames specified\n" == stdout + + +def test_input_missing(record_property, tmpdir): + args = [ + 'missing.c' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: could not open file 'missing.c'\n" == stdout + + +def test_input_dir(record_property, tmpdir): + test_dir = os.path.join(tmpdir, "test") + os.mkdir(test_dir) + + args = [ + 'test' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: could not open file 'test'\n" == stdout + + +def test_incpath_missing(record_property, tmpdir): + test_file = os.path.join(tmpdir, "test.c") + with open(test_file, 'w'): + pass + + test_dir = os.path.join(tmpdir, "test") + os.mkdir(test_dir) + + args = [ + '-Itest', + '-Imissing', + 'test.c' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: could not find include path 'missing'\n" == stdout + + +def test_incpath_file(record_property, tmpdir): + test_file = os.path.join(tmpdir, "test.c") + with open(test_file, 'w'): + pass + + inc_dir = os.path.join(tmpdir, "inc") + os.mkdir(inc_dir) + + inc_file = os.path.join(tmpdir, "inc.h") + with open(test_file, 'w'): + pass + + args = [ + '-Iinc', + '-Iinc.h', + 'test.c' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: could not find include path 'inc.h'\n" == stdout + + +def test_incfile_missing(record_property, tmpdir): + test_file = os.path.join(tmpdir, "test.c") + with open(test_file, 'w'): + pass + + inc_file = os.path.join(tmpdir, "inc.h") + with open(inc_file, 'w'): + pass + + args = [ + '-include=inc.h', + '-include=missing.h', + 'test.c' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: could not open include 'missing.h'\n" == stdout + + +def test_incpath_dir(record_property, tmpdir): + test_file = os.path.join(tmpdir, "test.c") + with open(test_file, 'w'): + pass + + inc_file = os.path.join(tmpdir, "inc.h") + with open(inc_file, 'w'): + pass + + inc_dir = os.path.join(tmpdir, "inc") + os.mkdir(inc_dir) + + args = [ + '-include=inc.h', + '-include=inc', + 'test.c' + ] + + _, stdout, stderr = simplecpp(args, cwd=tmpdir) + record_property("stdout", stdout) + record_property("stderr", stderr) + + assert '' == stderr + assert "error: could not open include 'inc'\n" == stdout diff --git a/main.cpp b/main.cpp index cbae6ac8..0196d6e4 100644 --- a/main.cpp +++ b/main.cpp @@ -9,10 +9,20 @@ #include #include #include +#include #include #include #include +static bool isDir(const std::string& path) +{ + struct stat file_stat; + if (stat(path.c_str(), &file_stat) == -1) + return false; + + return (file_stat.st_mode & S_IFMT) == S_IFDIR; +} + int main(int argc, char **argv) { bool error = false; @@ -23,6 +33,7 @@ int main(int argc, char **argv) // Settings.. simplecpp::DUI dui; + dui.removeComments = true; bool quiet = false; bool error_only = false; for (int i = 1; i < argc; i++) { @@ -114,18 +125,18 @@ int main(int argc, char **argv) } } else if (filename) { std::cout << "error: multiple filenames specified" << std::endl; - std::exit(1); + return 1; } else { filename = arg; } } if (error) - std::exit(1); + return 1; if (quiet && error_only) { std::cout << "error: -e cannot be used in conjunction with -q" << std::endl; - std::exit(1); + return 1; } if (!filename) { @@ -141,32 +152,54 @@ int main(int argc, char **argv) std::cout << " -e Output errors only." << std::endl; std::cout << " -f Fail when errors were encountered (exitcode 1)." << std::endl; std::cout << " -l Print lines numbers." << std::endl; - std::exit(0); + return 0; } - dui.removeComments = true; + // TODO: move this logic into simplecpp + bool inp_missing = false; + + for (const std::string& inc : dui.includes) { + std::ifstream f(inc); + if (!f.is_open() || isDir(inc)) { + inp_missing = true; + std::cout << "error: could not open include '" << inc << "'" << std::endl; + } + } + + for (const std::string& inc : dui.includePaths) { + if (!isDir(inc)) { + inp_missing = true; + std::cout << "error: could not find include path '" << inc << "'" << std::endl; + } + } + + std::ifstream f(filename); + if (!f.is_open() || isDir(filename)) { + inp_missing = true; + std::cout << "error: could not open file '" << filename << "'" << std::endl; + } + + if (inp_missing) + return 1; // Perform preprocessing simplecpp::OutputList outputList; std::vector files; - simplecpp::TokenList *rawtokens; - if (use_istream) { - std::ifstream f(filename); - if (!f.is_open()) { - std::cout << "error: could not open file '" << filename << "'" << std::endl; - std::exit(1); + simplecpp::TokenList outputTokens(files); + { + simplecpp::TokenList *rawtokens; + if (use_istream) { + rawtokens = new simplecpp::TokenList(f, files,filename,&outputList); + } else { + f.close(); + rawtokens = new simplecpp::TokenList(filename,files,&outputList); } - rawtokens = new simplecpp::TokenList(f, files,filename,&outputList); - } else { - rawtokens = new simplecpp::TokenList(filename,files,&outputList); + rawtokens->removeComments(); + simplecpp::FileDataCache filedata; + simplecpp::preprocess(outputTokens, *rawtokens, files, filedata, dui, &outputList); + simplecpp::cleanup(filedata); + delete rawtokens; } - rawtokens->removeComments(); - simplecpp::TokenList outputTokens(files); - simplecpp::FileDataCache filedata; - simplecpp::preprocess(outputTokens, *rawtokens, files, filedata, dui, &outputList); - simplecpp::cleanup(filedata); - delete rawtokens; - rawtokens = nullptr; // Output if (!quiet) {