<commit_before>/*
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: <NAME>, <NAME>
*/
#include "util/lean_path.h"
#include <string>
#include <cstdlib>
#include <fstream>
#include <vector>
#include "util/sstream.h"

#ifndef LEAN_DEFAULT_MODULE_FILE_NAME
#define LEAN_DEFAULT_MODULE_FILE_NAME "default"
#endif

namespace lean {
lean_file_not_found_exception::lean_file_not_found_exception(std::string const & fname):
    exception(sstream() << "file '" << fname << "' not found in the LEAN_PATH"),
    m_fname(fname) {}

static char const * g_default_file_name = LEAN_DEFAULT_MODULE_FILE_NAME;

static bool exists(std::string const & fn) {
    return !!std::ifstream(fn);
}

optional<std::string> get_leanpkg_path_file() {
    auto dir = lrealpath(".");
    while (true) {
        auto fn = dir + get_dir_sep() + "leanpkg.path";
        if (exists(fn)) return optional<std::string>(fn);

        auto i = dir.rfind(get_dir_sep());
        if (i == std::string::npos) {
            return optional<std::string>();
        } else {
            dir = dir.substr(0, i);
        }
    }
}

std::string get_user_leanpkg_path() {
    // TODO(gabriel): check if this works on windows
    return std::string(getenv("HOME")) + get_dir_sep() + ".lean" + get_dir_sep() + "leanpkg.path";
}

static optional<std::string> begins_with(std::string const & s, std::string const & prefix) {
    if (prefix.size() <= s.size() && s.substr(0, prefix.size()) == prefix) {
        return optional<std::string>(s.substr(prefix.size(), s.size()));
    } else {
        return optional<std::string>();
    }
}

search_path parse_leanpkg_path(std::string const & fn) {
    std::ifstream in(fn);
    if (!in) throw exception(sstream() << "cannot open " << fn);
    auto fn_dir = dirname(fn);
    search_path path;
    while (!in.eof()) {
        std::string line;
        std::getline(in, line);

        if (auto rest = begins_with(line, "path "))
            path.push_back(resolve(*rest, fn_dir));

        if (line == "builtin_path") {
            auto builtin = get_builtin_search_path();
            path.insert(path.end(), builtin.begin(), builtin.end());
        }
    }
    return path;
}

optional<search_path> get_lean_path_from_env() {<commit_msg>fix(util/lean_path): do not crash if HOME is not set<commit_after>/*
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: <NAME>, <NAME>
*/
#include "util/lean_path.h"
#include <string>
#include <cstdlib>
#include <fstream>
#include <vector>
#include "util/sstream.h"

#ifndef LEAN_DEFAULT_MODULE_FILE_NAME
#define LEAN_DEFAULT_MODULE_FILE_NAME "default"
#endif

namespace lean {
lean_file_not_found_exception::lean_file_not_found_exception(std::string const & fname):
    exception(sstream() << "file '" << fname << "' not found in the LEAN_PATH"),
    m_fname(fname) {}

static char const * g_default_file_name = LEAN_DEFAULT_MODULE_FILE_NAME;

static bool exists(std::string const & fn) {
    return !!std::ifstream(fn);
}

optional<std::string> get_leanpkg_path_file() {
    auto dir = lrealpath(".");
    while (true) {
        auto fn = dir + get_dir_sep() + "leanpkg.path";
        if (exists(fn)) return optional<std::string>(fn);

        auto i = dir.rfind(get_dir_sep());
        if (i == std::string::npos) {
            return optional<std::string>();
        } else {
            dir = dir.substr(0, i);
        }
    }
}

std::string get_user_leanpkg_path() {
    // TODO(gabriel): check if this works on windows
    if (auto home = getenv("HOME")) {
        return std::string(home) + get_dir_sep() + ".lean" + get_dir_sep() + "leanpkg.path";
    } else {
        return "/could-not-find-home";
    }
}

static optional<std::string> begins_with(std::string const & s, std::string const & prefix) {
    if (prefix.size() <= s.size() && s.substr(0, prefix.size()) == prefix) {
        return optional<std::string>(s.substr(prefix.size(), s.size()));
    } else {
        return optional<std::string>();
    }
}

search_path parse_leanpkg_path(std::string const & fn) {
    std::ifstream in(fn);
    if (!in) throw exception(sstream() << "cannot open " << fn);
    auto fn_dir = dirname(fn);
    search_path path;
    while (!in.eof()) {
        std::string line;
        std::getline(in, line);

        if (auto rest = begins_with(line, "path "))
            path.push_back(resolve(*rest, fn_dir));

        if (line == "builtin_path") {
            auto builtin = get_builtin_search_path();
            path.insert(path.end(), builtin.begin(), builtin.end());
        }
    }
    return path;
}

optional<search_path> get_lean_path_from_env() {
{'fraction_non_alphanumeric': 0.15445960125918154, 'fraction_numerical': 0.0033578174186778592, 'mean_word_length': 3.4048059149722736, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4475402', 'n_tokens_mistral': 1593, 'n_tokens_neox': 1596, 'n_words': 365}