<commit_before>#include <sirius.h>
#include <json.hpp>

using namespace sirius;
using json = nlohmann::json;

const std::string aiida_output_file = "output_aiida.json";

enum class task_t
{
    ground_state_new = 0,
    ground_state_restart = 1,
};

const double au2angs = 0.5291772108;

void json_output_common(json& dict__)
{
    dict__["git_hash"] = git_hash;
    dict__["build_date"] = build_date;
    dict__["comm_world_size"] = mpi_comm_world().size();
    dict__["threads_per_rank"] = omp_get_max_threads();
}

std::unique_ptr<Simulation_context> create_sim_ctx(std::string     fname__,
                                                   cmd_args const& args__)
{
    auto ctx_ptr = std::unique_ptr<Simulation_context>(new Simulation_context(fname__, mpi_comm_world()));
    Simulation_context& ctx = *ctx_ptr;

    auto& inp = ctx.parameters_input();
    if (inp.gamma_point_ && !(inp.ngridk_[0] * inp.ngridk_[1] * inp.ngridk_[2] == 1)) {
        TERMINATE("this is not a Gamma-point calculation")
    }

    std::vector<int> mpi_grid_dims = ctx.mpi_grid_dims();
    mpi_grid_dims = args__.value<std::vector<int>>("mpi_grid", mpi_grid_dims);
    ctx.set_mpi_grid_dims(mpi_grid_dims);

    return std::move(ctx_ptr);
}

double ground_state(Simulation_context& ctx,
                    task_t              task,
                    cmd_args const&     args,
                    int                 write_output)
{
    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    Potential potential(ctx);
    potential.allocate();

    Density density(ctx);
    density.allocate();

    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    auto& inp = ctx.parameters_input();

    K_point_set ks(ctx, inp.ngridk_, inp.shiftk_, ctx.use_symmetry());
    ks.initialize();

    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    std::string ref_file = args.value<std::string>("test_against", "");
    bool write_state = (ref_file.size() == 0);

    DFT_ground_state dft(ctx, potential, density, ks, ctx.use_symmetry());

    if (task == task_t::ground_state_restart) {
        if (!Utils::file_exists(storage_file_name)) {
            TERMINATE("storage file is not found");
        }
        density.load();
        potential.load();
    } else {
        density.initial_density();
        potential.generate(density);
        if (!ctx.full_potential()) {
            dft.band().initialize_subspace(ks, potential);
        }
    }

    /* launch the calculation */
    int result = dft.find(inp.potential_tol_, inp.energy_tol_, inp.num_dft_iter_, write_state);

    if (ref_file.size() != 0) {
        json dict;
        dict["ground_state"] = dft.serialize();
        json dict_ref;
        std::ifstream(ref_file) >> dict_ref;

        double e1 = dict["ground_state"]["energy"]["total"];
        double e2 = dict_ref["ground_state"]["energy"]["total"];

        if (std::abs(e1 - e2) > 1e-7) {
            printf("total energy is different\n");
            exit(1);
        }

        write_output = 0;
    }

    if (!ctx.full_potential()) {
        //dft.forces();
        Stress s(ctx, ks, density, potential);
    }

    if (write_output) {
        json dict;
        json_output_common(dict);

        dict["task"] = static_cast<int>(task);
        dict["ground_state"] = dft.serialize();
        dict["timers"] = Utils::serialize_timers();

        if (ctx.comm().rank() == 0) {
            std::ofstream ofs(std::string("output_") + ctx.start_time_tag() + std::string(".json"),
                              std::ofstream::out | std::ofstream::trunc);
            ofs << dict.dump(4);
        }

        if (args.exist("aiida_output")) {
            json dict;
            json_output_common(dict);
            dict["task"] = static_cast<int>(task);
            if (result >= 0) {
                dict["task_status"] = "converged";
                dict["num_scf_iterations"] =  result;
            } else {
                dict["task_status"] = "unconverged";
            }
            dict["volume"] = ctx.unit_cell().omega() * std::pow(au2angs, 3);
            dict["volume_units"] = "angstrom^3";
            dict["energy"] = dft.total_energy() * ha2ev;
            dict["energy_units"] = "eV";
            if (ctx.comm().rank() == 0) {
                std::ofstream ofs(aiida_output_file, std::ofstream::out | std::ofstream::trunc);
                ofs << dict.dump(4);
            }
        }
    }

    /* wait for all */
    ctx.comm().barrier();

    sddk::timer::print(0);

    return dft.total_energy();
}

void run_tasks(cmd_args const& args)
{
    /* get the task id */
    task_t task = static_cast<task_t>(args.value<int>("task", 0));
    /* get the input file name */
    std::string fname = args.value<std::string>("input", "sirius.json");
    if (!Utils::file_exists(fname)) {
        TERMINATE("input file does not exist");
    }

    if (task == task_t::ground_state_new || task == task_t::ground_state_restart) {
        auto ctx = create_sim_ctx(fname, args);
        ctx->initialize();
        ground_state(*ctx, task, args, 1);
    }
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--input=", "{string} input file name");
    args.register_key("--task=", "{int} task id");
    args.register_key("--mpi_grid=", "{vector int} MPI grid dimensions");
    args.register_key("--aiida_output", "write output for AiiDA");
    args.register_key("--test_against=", "{string} json file with reference values");

    args.parse_args(argn, argv);

    if (args.exist("help")) {
        printf("Usage: %s [options] \n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);

    run_tasks(args);

    sirius::finalize();
    return 0;
}
<commit_msg>update<commit_after>#include <sirius.h>
#include <json.hpp>

using namespace sirius;
using json = nlohmann::json;

const std::string aiida_output_file = "output_aiida.json";

enum class task_t
{
    ground_state_new = 0,
    ground_state_restart = 1,
};

const double au2angs = 0.5291772108;

void json_output_common(json& dict__)
{
    dict__["git_hash"] = git_hash;
    dict__["build_date"] = build_date;
    dict__["comm_world_size"] = mpi_comm_world().size();
    dict__["threads_per_rank"] = omp_get_max_threads();
}

std::unique_ptr<Simulation_context> create_sim_ctx(std::string     fname__,
                                                   cmd_args const& args__)
{
    auto ctx_ptr = std::unique_ptr<Simulation_context>(new Simulation_context(fname__, mpi_comm_world()));
    Simulation_context& ctx = *ctx_ptr;

    auto& inp = ctx.parameters_input();
    if (inp.gamma_point_ && !(inp.ngridk_[0] * inp.ngridk_[1] * inp.ngridk_[2] == 1)) {
        TERMINATE("this is not a Gamma-point calculation")
    }

    std::vector<int> mpi_grid_dims = ctx.mpi_grid_dims();
    mpi_grid_dims = args__.value<std::vector<int>>("mpi_grid", mpi_grid_dims);
    ctx.set_mpi_grid_dims(mpi_grid_dims);

    return std::move(ctx_ptr);
}

double ground_state(Simulation_context& ctx,
                    task_t              task,
                    cmd_args const&     args,
                    int                 write_output)
{
    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    Potential potential(ctx);
    potential.allocate();

    Density density(ctx);
    density.allocate();

    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    auto& inp = ctx.parameters_input();

    K_point_set ks(ctx, inp.ngridk_, inp.shiftk_, ctx.use_symmetry());
    ks.initialize();

    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    std::string ref_file = args.value<std::string>("test_against", "");
    bool write_state = (ref_file.size() == 0);

    DFT_ground_state dft(ctx, potential, density, ks, ctx.use_symmetry());

    if (task == task_t::ground_state_restart) {
        if (!Utils::file_exists(storage_file_name)) {
            TERMINATE("storage file is not found");
        }
        density.load();
        potential.load();
    } else {
        density.initial_density();
        potential.generate(density);
        if (!ctx.full_potential()) {
            dft.band().initialize_subspace(ks, potential);
        }
    }

    /* launch the calculation */
    int result = dft.find(inp.potential_tol_, inp.energy_tol_, inp.num_dft_iter_, write_state);

    if (ref_file.size() != 0) {
        json dict;
        dict["ground_state"] = dft.serialize();
        json dict_ref;
        std::ifstream(ref_file) >> dict_ref;

        double e1 = dict["ground_state"]["energy"]["total"];
        double e2 = dict_ref["ground_state"]["energy"]["total"];

        if (std::abs(e1 - e2) > 1e-7) {
            printf("total energy is different\n");
            exit(1);
        }

        write_output = 0;
    }

    if (!ctx.full_potential()) {
        //dft.forces();
        if (ctx.control().print_stress_) {
            Stress s(ctx, ks, density, potential);
            s.print_info();
        }
    }

    if (write_output) {
        json dict;
        json_output_common(dict);

        dict["task"] = static_cast<int>(task);
        dict["ground_state"] = dft.serialize();
        dict["timers"] = Utils::serialize_timers();

        if (ctx.comm().rank() == 0) {
            std::ofstream ofs(std::string("output_") + ctx.start_time_tag() + std::string(".json"),
                              std::ofstream::out | std::ofstream::trunc);
            ofs << dict.dump(4);
        }

        if (args.exist("aiida_output")) {
            json dict;
            json_output_common(dict);
            dict["task"] = static_cast<int>(task);
            if (result >= 0) {
                dict["task_status"] = "converged";
                dict["num_scf_iterations"] =  result;
            } else {
                dict["task_status"] = "unconverged";
            }
            dict["volume"] = ctx.unit_cell().omega() * std::pow(au2angs, 3);
            dict["volume_units"] = "angstrom^3";
            dict["energy"] = dft.total_energy() * ha2ev;
            dict["energy_units"] = "eV";
            if (ctx.comm().rank() == 0) {
                std::ofstream ofs(aiida_output_file, std::ofstream::out | std::ofstream::trunc);
                ofs << dict.dump(4);
            }
        }
    }

    /* wait for all */
    ctx.comm().barrier();

    sddk::timer::print(0);

    return dft.total_energy();
}

void run_tasks(cmd_args const& args)
{
    /* get the task id */
    task_t task = static_cast<task_t>(args.value<int>("task", 0));
    /* get the input file name */
    std::string fname = args.value<std::string>("input", "sirius.json");
    if (!Utils::file_exists(fname)) {
        TERMINATE("input file does not exist");
    }

    if (task == task_t::ground_state_new || task == task_t::ground_state_restart) {
        auto ctx = create_sim_ctx(fname, args);
        ctx->initialize();
        ground_state(*ctx, task, args, 1);
    }
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--input=", "{string} input file name");
    args.register_key("--task=", "{int} task id");
    args.register_key("--mpi_grid=", "{vector int} MPI grid dimensions");
    args.register_key("--aiida_output", "write output for AiiDA");
    args.register_key("--test_against=", "{string} json file with reference values");

    args.parse_args(argn, argv);

    if (args.exist("help")) {
        printf("Usage: %s [options] \n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);

    run_tasks(args);

    sirius::finalize();
    return 0;
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <unordered_map>
#include <vector>

#include "logging.hpp"
#include "Function.hpp"
#include "GlobalContext.hpp"
#include "FunctionContext.hpp"
#include "Variable.hpp"

#include "mtac/parameter_propagation.hpp"
#include "mtac/Program.hpp"
#include "mtac/Function.hpp"
#include "mtac/Call.hpp"
#include "mtac/Argument.hpp"
#include "mtac/Param.hpp"
#include "mtac/VariableReplace.hpp"
#include "mtac/Utils.hpp"

using namespace eddic;

namespace {

typedef std::unordered_map<std::string, std::vector<std::vector<mtac::Argument>>> Arguments;

Arguments collect_arguments(mtac::Program& program){
    Arguments arguments;

    for(auto& function : program.functions){
        for(auto& block : function){
            for(auto& statement : block){
                if(auto* ptr = boost::get<std::shared_ptr<mtac::Call>>(&statement)){
                    auto& function = (*ptr)->functionDefinition;

                    if(!function.standard && !function.parameters().empty()){
                        std::vector<mtac::Argument> function_arguments;

                        auto parameters = function.parameters().size();
                        auto param_block = block->prev;

                        auto it = param_block->statements.rbegin();
                        auto end = param_block->statements.rend();

                        std::size_t discovered = 0;

                        while(it != end && discovered < parameters){
                            auto& param_statement = *it;

                            if(auto* param_ptr = boost::get<std::shared_ptr<mtac::Param>>(&param_statement)){
                                ++discovered;

                                function_arguments.push_back((*param_ptr)->arg);
                            }

                            ++it;
                        }

                        arguments[function.mangledName].push_back(std::move(function_arguments));
                    }
                }
            }
        }
    }

    return arguments;
}

} //end of anonymous namespace

bool mtac::parameter_propagation::operator()(mtac::Program& program){
    bool optimized = false;

    auto global_context = program.context;

    auto arguments = collect_arguments(program);

    for(auto& function_map : arguments){
        auto& function_name = function_map.first;
        auto& function = global_context->getFunction(function_name);
        auto& function_arguments = function_map.second;

        std::vector<std::pair<std::size_t, int>> constant_parameters;

        for(std::size_t i = 0; i < function.parameters().size(); ++i){
            bool found = false;
            int constant_value = 0;

            for(auto& arguments : function_arguments){
                auto& arg = arguments[i];

                if(auto* ptr = boost::get<int>(&arg)){
                    if(found){
                        if(*ptr != constant_value){
                            found = false;
                            break;
                        }
                    } else {
                        found = true;
                        constant_value = *ptr;
                    }
                } else {
                    found = false;
                    break;
                }
            }

            if(found){
                constant_parameters.emplace_back(i, constant_value);
            }
        }

        if(!constant_parameters.empty()){
            std::sort(constant_parameters.begin(), constant_parameters.end(),
                    [](const std::pair<int, int>& p1, const std::pair<int, int>& p2){ return p1.first > p2.first; });

            //Replace the parameter by the constant in each use of the parameter
            for(auto& mtac_function : program.functions){
                if(mtac_function.definition() == function){
                    mtac::VariableClones clones;

                    for(auto& parameter : constant_parameters){
                        auto param = mtac_function.context->getVariable(function.parameters()[parameter.first].name);
                        log::emit<Debug>("Optimizer") << "Propagate " << param->name() << " by " << parameter.second  << " in function " << function.name << log::endl;
                        clones[param] = parameter.second;
                    }

                    VariableReplace replacer(clones);
                    mtac::visit_all_statements(replacer, mtac_function);

                    break;
                }
            }

            for(auto& parameter : constant_parameters){
                auto param = function.context->getVariable(function.parameters()[parameter.first].name);
                function.context->removeVariable(param);
            }

            for(auto& parameter : constant_parameters){
                //Remove the parameter passing for each call to the function
                for(auto& mtac_function : program.functions){
                    for(auto& block : mtac_function){
                        for(auto& statement : block){
                            if(auto* ptr = boost::get<std::shared_ptr<mtac::Call>>(&statement)){
                                auto& param_function = (*ptr)->functionDefinition;

                                if(param_function == function){
                                    auto param_block = block->prev;

                                    auto it = param_block->statements.rbegin();
                                    auto end = param_block->statements.rend();

                                    std::size_t discovered = 0;

                                    while(it != end && discovered < function.parameters().size()){
                                        auto& param_statement = *it;

                                        if(boost::get<std::shared_ptr<mtac::Param>>(&param_statement)){
                                            if(discovered == parameter.first){
                                                param_block->statements.erase(--(it.base()));
                                                --it;
                                                end = param_block->statements.rend();
                                            }

                                            ++discovered;
                                        }

                                        ++it;
                                    }
                                }
                            }
                        }
                    }
                }

                //Remove the parameter from the function definition
                function.parameters().erase(function.parameters().begin() + parameter.first);
            }
        }
    }

    return optimized;
}
<commit_msg>Fix the propagation<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <unordered_map>
#include <vector>

#include "logging.hpp"
#include "Function.hpp"
#include "GlobalContext.hpp"
#include "FunctionContext.hpp"
#include "Variable.hpp"

#include "mtac/parameter_propagation.hpp"
#include "mtac/Program.hpp"
#include "mtac/Function.hpp"
#include "mtac/Call.hpp"
#include "mtac/Argument.hpp"
#include "mtac/Param.hpp"
#include "mtac/VariableReplace.hpp"
#include "mtac/Utils.hpp"

using namespace eddic;

namespace {

typedef std::unordered_map<std::string, std::vector<std::unordered_map<std::size_t, mtac::Argument>>> Arguments;

Arguments collect_arguments(mtac::Program& program){
    Arguments arguments;

    for(auto& function : program.functions){
        for(auto& block : function){
            for(auto& statement : block){
                if(auto* ptr = boost::get<std::shared_ptr<mtac::Call>>(&statement)){
                    auto& function = (*ptr)->functionDefinition;

                    if(!function.standard && !function.parameters().empty()){
                        std::unordered_map<std::size_t, mtac::Argument> function_arguments;

                        auto parameters = function.parameters().size();
                        auto param_block = block->prev;

                        auto it = param_block->statements.rbegin();
                        auto end = param_block->statements.rend();

                        std::size_t discovered = 0;

                        while(it != end && discovered < parameters){
                            auto& param_statement = *it;

                            if(auto* param_ptr = boost::get<std::shared_ptr<mtac::Param>>(&param_statement)){
                                if((*param_ptr)->param->type() == INT){
                                    function_arguments[discovered] = (*param_ptr)->arg;
                                }

                                ++discovered;
                            }

                            ++it;
                        }

                        arguments[function.mangledName].push_back(std::move(function_arguments));
                    }
                }
            }
        }
    }

    return arguments;
}

} //end of anonymous namespace

bool mtac::parameter_propagation::operator()(mtac::Program& program){
    bool optimized = false;

    auto global_context = program.context;

    auto arguments = collect_arguments(program);

    for(auto& function_map : arguments){
        auto& function_name = function_map.first;
        auto& function = global_context->getFunction(function_name);
        auto& function_arguments = function_map.second;

        std::vector<std::pair<std::size_t, int>> constant_parameters;

        for(std::size_t i = 0; i < function.parameters().size(); ++i){
            bool found = false;
            int constant_value = 0;

            for(auto& arguments : function_arguments){
                auto& arg = arguments[i];

                if(auto* ptr = boost::get<int>(&arg)){
                    if(found){
                        if(*ptr != constant_value){
                            found = false;
                            break;
                        }
                    } else {
                        found = true;
                        constant_value = *ptr;
                    }
                } else {
                    found = false;
                    break;
                }
            }

            if(found){
                constant_parameters.emplace_back(i, constant_value);
            }
        }

        if(!constant_parameters.empty()){
            std::sort(constant_parameters.begin(), constant_parameters.end(),
                    [](const std::pair<int, int>& p1, const std::pair<int, int>& p2){ return p1.first > p2.first; });

            //Replace the parameter by the constant in each use of the parameter
            for(auto& mtac_function : program.functions){
                if(mtac_function.definition() == function){
                    mtac::VariableClones clones;

                    for(auto& parameter : constant_parameters){
                        auto param = mtac_function.context->getVariable(function.parameters()[parameter.first].name);
                        log::emit<Debug>("Optimizer") << "Propagate " << param->name() << " by " << parameter.second  << " in function " << function.name << log::endl;
                        clones[param] = parameter.second;
                    }

                    VariableReplace replacer(clones);
                    mtac::visit_all_statements(replacer, mtac_function);

                    break;
                }
            }

            for(auto& parameter : constant_parameters){
                auto param = function.context->getVariable(function.parameters()[parameter.first].name);
                function.context->removeVariable(param);
            }

            for(auto& parameter : constant_parameters){
                //Remove the parameter passing for each call to the function
                for(auto& mtac_function : program.functions){
                    for(auto& block : mtac_function){
                        for(auto& statement : block){
                            if(auto* ptr = boost::get<std::shared_ptr<mtac::Call>>(&statement)){
                                auto& param_function = (*ptr)->functionDefinition;

                                if(param_function == function){
                                    auto param_block = block->prev;

                                    auto it = param_block->statements.rbegin();
                                    auto end = param_block->statements.rend();

                                    std::size_t discovered = 0;

                                    while(it != end && discovered < function.parameters().size()){
                                        auto& param_statement = *it;

                                        if(boost::get<std::shared_ptr<mtac::Param>>(&param_statement)){
                                            if(discovered == parameter.first){
                                                param_block->statements.erase(--(it.base()));
                                                --it;
                                                end = param_block->statements.rend();
                                            }

                                            ++discovered;
                                        }

                                        ++it;
                                    }
                                }
                            }
                        }
                    }
                }

                //Remove the parameter from the function definition
                function.parameters().erase(function.parameters().begin() + parameter.first);
            }
        }
    }

    return optimized;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/ftp/ftp_util.h"

#include <vector>

#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "unicode/datefmt.h"
#include "unicode/dtfmtsym.h"

// For examples of Unix<->VMS path conversions, see the unit test file. On VMS
// a path looks differently depending on whether it's a file or directory.

namespace net {

// static
std::string FtpUtil::UnixFilePathToVMS(const std::string& unix_path) {
  if (unix_path.empty())
    return std::string();

  StringTokenizer tokenizer(unix_path, "/");
  std::vector<std::string> tokens;
  while (tokenizer.GetNext())
    tokens.push_back(tokenizer.token());

  if (unix_path[0] == '/') {
    // It's an absolute path.

    if (tokens.empty()) {
      DCHECK_EQ(1U, unix_path.length());
      return "[]";
    }

    if (tokens.size() == 1)
      return unix_path.substr(1);  // Drop the leading slash.

    std::string result(tokens[0] + ":[");
    if (tokens.size() == 2) {
      // Don't ask why, it just works that way on VMS.
      result.append("000000");
    } else {
      result.append(tokens[1]);
      for (size_t i = 2; i < tokens.size() - 1; i++)
        result.append("." + tokens[i]);
    }
    result.append("]" + tokens[tokens.size() - 1]);
    return result;
  }

  if (tokens.size() == 1)
    return unix_path;

  std::string result("[");
  for (size_t i = 0; i < tokens.size() - 1; i++)
    result.append("." + tokens[i]);
  result.append("]" + tokens[tokens.size() - 1]);
  return result;
}

// static
std::string FtpUtil::UnixDirectoryPathToVMS(const std::string& unix_path) {
  if (unix_path.empty())
    return std::string();

  std::string path(unix_path);

  if (path[path.length() - 1] != '/')
    path.append("/");

  // Reuse logic from UnixFilePathToVMS by appending a fake file name to the
  // real path and removing it after conversion.
  path.append("x");
  path = UnixFilePathToVMS(path);
  return path.substr(0, path.length() - 1);
}

// static
std::string FtpUtil::VMSPathToUnix(const std::string& vms_path) {
  if (vms_path.empty())
    return ".";

  if (vms_path == "[]")
    return "/";

  std::string result(vms_path);
  if (vms_path[0] == '[') {
    // It's a relative path.
    ReplaceFirstSubstringAfterOffset(&result, 0, "[.", "");
  } else {
    // It's an absolute path.
    result.insert(0, "/");
    ReplaceSubstringsAfterOffset(&result, 0, ":[000000]", "/");
    ReplaceSubstringsAfterOffset(&result, 0, ":[", "/");
  }
  std::replace(result.begin(), result.end(), '.', '/');
  std::replace(result.begin(), result.end(), ']', '/');

  // Make sure the result doesn't end with a slash.
  if (result.length() && result[result.length() - 1] == '/')
    result = result.substr(0, result.length() - 1);

  return result;
}

// static
bool FtpUtil::AbbreviatedMonthToNumber(const string16& text, int* number) {
  icu::UnicodeString unicode_text(text.data(), text.size());

  int32_t locales_count;
  const icu::Locale* locales =
      icu::DateFormat::getAvailableLocales(locales_count);

  // Some FTP servers localize the date listings. To guess the locale,
  // we loop over all available ones.
  for (int32_t locale = 0; locale < locales_count; locale++) {
    UErrorCode status(U_ZERO_ERROR);

    icu::DateFormatSymbols format_symbols(locales[locale], status);

    // If we cannot get format symbols for some locale, it's not a fatal error.
    // Just try another one.
    if (U_FAILURE(status))
      continue;

    int32_t months_count;
    const icu::UnicodeString* months =
        format_symbols.getShortMonths(months_count);

    // Loop over all abbreviated month names in given locale.
    // An alternative solution (to parse |text| in given locale) is more
    // lenient, and may accept more than we want even with setLenient(false).
    for (int32_t month = 0; month < months_count; month++) {
      if (months[month].caseCompare(unicode_text, 0) == 0) {
        *number = month + 1;
        return true;
      }
    }
  }

  return false;
}

// static
bool FtpUtil::LsDateListingToTime(const string16& month, const string16& day,
                                  const string16& rest,
                                  const base::Time& current_time,
                                  base::Time* result) {
  base::Time::Exploded time_exploded = { 0 };

  if (!AbbreviatedMonthToNumber(month, &time_exploded.month))
    return false;

  if (!base::StringToInt(day, &time_exploded.day_of_month))
    return false;

  if (!base::StringToInt(rest, &time_exploded.year)) {
    // Maybe it's time. Does it look like time (HH:MM)?
    if (rest.length() == 5 && rest[2] == ':') {
      if (!base::StringToInt(rest.begin(),
                             rest.begin() + 2,
                             &time_exploded.hour))
        return false;

      if (!base::StringToInt(rest.begin() + 3,
                             rest.begin() + 5,
                             &time_exploded.minute))
        return false;
    } else if (rest.length() == 4 && rest[1] == ':') {
      // Sometimes it's just H:MM.
      if (!base::StringToInt(rest.begin(),
                             rest.begin() + 1,
                             &time_exploded.hour))
        return false;

      if (!base::StringToInt(rest.begin() + 2,
                             rest.begin() + 4,
                             &time_exploded.minute))
        return false;
    } else {
      return false;
    }

    // Guess the year.
    base::Time::Exploded current_exploded;
    current_time.LocalExplode(&current_exploded);

    // If it's not possible for the parsed date to be in the current year,
    // use the previous year.
    if (time_exploded.month > current_exploded.month ||
        (time_exploded.month == current_exploded.month &&
         time_exploded.day_of_month > current_exploded.day_of_month)) {
      time_exploded.year = current_exploded.year - 1;
    } else {
      time_exploded.year = current_exploded.year;
    }
  }

  // We don't know the time zone of the listing, so just use local time.
  *result = base::Time::FromLocalExploded(time_exploded);
  return true;
}

// static
string16 FtpUtil::GetStringPartAfterColumns(const string16& text, int columns) {
  size_t pos = 0;

  for (int i = 0; i < columns; i++) {
    // Skip the leading whitespace.
    while (pos < text.length() && isspace(text[pos]))
      pos++;

    // Skip the actual text of i-th column.
    while (pos < text.length() && !isspace(text[pos]))
      pos++;
  }

  string16 result(text.substr(pos));
  TrimWhitespace(result, TRIM_ALL, &result);
  return result;
}

}  // namespace
<commit_msg>FTP: fix a misuse of isspace (it can only operate on char, not char16; this triggers an assertion on Windows, see http://codereview.chromium.org/6802006/ and http://msdn.microsoft.com/en-us/library/y13z34da(v=vs.71).aspx)<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/ftp/ftp_util.h"

#include <vector>

#include "base/i18n/char_iterator.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "unicode/datefmt.h"
#include "unicode/dtfmtsym.h"
#include "unicode/uchar.h"

// For examples of Unix<->VMS path conversions, see the unit test file. On VMS
// a path looks differently depending on whether it's a file or directory.

namespace net {

// static
std::string FtpUtil::UnixFilePathToVMS(const std::string& unix_path) {
  if (unix_path.empty())
    return std::string();

  StringTokenizer tokenizer(unix_path, "/");
  std::vector<std::string> tokens;
  while (tokenizer.GetNext())
    tokens.push_back(tokenizer.token());

  if (unix_path[0] == '/') {
    // It's an absolute path.

    if (tokens.empty()) {
      DCHECK_EQ(1U, unix_path.length());
      return "[]";
    }

    if (tokens.size() == 1)
      return unix_path.substr(1);  // Drop the leading slash.

    std::string result(tokens[0] + ":[");
    if (tokens.size() == 2) {
      // Don't ask why, it just works that way on VMS.
      result.append("000000");
    } else {
      result.append(tokens[1]);
      for (size_t i = 2; i < tokens.size() - 1; i++)
        result.append("." + tokens[i]);
    }
    result.append("]" + tokens[tokens.size() - 1]);
    return result;
  }

  if (tokens.size() == 1)
    return unix_path;

  std::string result("[");
  for (size_t i = 0; i < tokens.size() - 1; i++)
    result.append("." + tokens[i]);
  result.append("]" + tokens[tokens.size() - 1]);
  return result;
}

// static
std::string FtpUtil::UnixDirectoryPathToVMS(const std::string& unix_path) {
  if (unix_path.empty())
    return std::string();

  std::string path(unix_path);

  if (path[path.length() - 1] != '/')
    path.append("/");

  // Reuse logic from UnixFilePathToVMS by appending a fake file name to the
  // real path and removing it after conversion.
  path.append("x");
  path = UnixFilePathToVMS(path);
  return path.substr(0, path.length() - 1);
}

// static
std::string FtpUtil::VMSPathToUnix(const std::string& vms_path) {
  if (vms_path.empty())
    return ".";

  if (vms_path == "[]")
    return "/";

  std::string result(vms_path);
  if (vms_path[0] == '[') {
    // It's a relative path.
    ReplaceFirstSubstringAfterOffset(&result, 0, "[.", "");
  } else {
    // It's an absolute path.
    result.insert(0, "/");
    ReplaceSubstringsAfterOffset(&result, 0, ":[000000]", "/");
    ReplaceSubstringsAfterOffset(&result, 0, ":[", "/");
  }
  std::replace(result.begin(), result.end(), '.', '/');
  std::replace(result.begin(), result.end(), ']', '/');

  // Make sure the result doesn't end with a slash.
  if (result.length() && result[result.length() - 1] == '/')
    result = result.substr(0, result.length() - 1);

  return result;
}

// static
bool FtpUtil::AbbreviatedMonthToNumber(const string16& text, int* number) {
  icu::UnicodeString unicode_text(text.data(), text.size());

  int32_t locales_count;
  const icu::Locale* locales =
      icu::DateFormat::getAvailableLocales(locales_count);

  // Some FTP servers localize the date listings. To guess the locale,
  // we loop over all available ones.
  for (int32_t locale = 0; locale < locales_count; locale++) {
    UErrorCode status(U_ZERO_ERROR);

    icu::DateFormatSymbols format_symbols(locales[locale], status);

    // If we cannot get format symbols for some locale, it's not a fatal error.
    // Just try another one.
    if (U_FAILURE(status))
      continue;

    int32_t months_count;
    const icu::UnicodeString* months =
        format_symbols.getShortMonths(months_count);

    // Loop over all abbreviated month names in given locale.
    // An alternative solution (to parse |text| in given locale) is more
    // lenient, and may accept more than we want even with setLenient(false).
    for (int32_t month = 0; month < months_count; month++) {
      if (months[month].caseCompare(unicode_text, 0) == 0) {
        *number = month + 1;
        return true;
      }
    }
  }

  return false;
}

// static
bool FtpUtil::LsDateListingToTime(const string16& month, const string16& day,
                                  const string16& rest,
                                  const base::Time& current_time,
                                  base::Time* result) {
  base::Time::Exploded time_exploded = { 0 };

  if (!AbbreviatedMonthToNumber(month, &time_exploded.month))
    return false;

  if (!base::StringToInt(day, &time_exploded.day_of_month))
    return false;

  if (!base::StringToInt(rest, &time_exploded.year)) {
    // Maybe it's time. Does it look like time (HH:MM)?
    if (rest.length() == 5 && rest[2] == ':') {
      if (!base::StringToInt(rest.begin(),
                             rest.begin() + 2,
                             &time_exploded.hour))
        return false;

      if (!base::StringToInt(rest.begin() + 3,
                             rest.begin() + 5,
                             &time_exploded.minute))
        return false;
    } else if (rest.length() == 4 && rest[1] == ':') {
      // Sometimes it's just H:MM.
      if (!base::StringToInt(rest.begin(),
                             rest.begin() + 1,
                             &time_exploded.hour))
        return false;

      if (!base::StringToInt(rest.begin() + 2,
                             rest.begin() + 4,
                             &time_exploded.minute))
        return false;
    } else {
      return false;
    }

    // Guess the year.
    base::Time::Exploded current_exploded;
    current_time.LocalExplode(&current_exploded);

    // If it's not possible for the parsed date to be in the current year,
    // use the previous year.
    if (time_exploded.month > current_exploded.month ||
        (time_exploded.month == current_exploded.month &&
         time_exploded.day_of_month > current_exploded.day_of_month)) {
      time_exploded.year = current_exploded.year - 1;
    } else {
      time_exploded.year = current_exploded.year;
    }
  }

  // We don't know the time zone of the listing, so just use local time.
  *result = base::Time::FromLocalExploded(time_exploded);
  return true;
}

// static
string16 FtpUtil::GetStringPartAfterColumns(const string16& text, int columns) {
  base::i18n::UTF16CharIterator iter(&text);

  // TODO(jshin): Is u_isspace the right function to use here?
  for (int i = 0; i < columns; i++) {
    // Skip the leading whitespace.
    while (!iter.end() && u_isspace(iter.get()))
      iter.Advance();

    // Skip the actual text of i-th column.
    while (!iter.end() && !u_isspace(iter.get()))
      iter.Advance();
  }

  string16 result(text.substr(iter.array_pos()));
  TrimWhitespace(result, TRIM_ALL, &result);
  return result;
}

}  // namespace
<|endoftext|>


<commit_before>/*
    Copyright (C) 2000 by W.C.A. Wijngaards

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    Description:
	Portable uninstall program.
	(will delete a set of files, and resulting empty directories)

	It will either read install.log in the working directory, or
	read install.log at the pathname given as argument.

	install.log contains the pathnames of the files that are installed
	(and will be deleted) separated by whitespace. Duplicates will be
	removed.

	(include install.log and uninst.exe pathnames into install.log
	if you wish them to be deleted as well.)
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

// global information
int nr_files = 0;
struct file_info {
  char *name;
  int deleted;
  struct file_info* next;
} *files = 0;

int nr_dirs = 0;
struct file_info *dirs = 0;

// a strdup (for portability to e.g. NeXT)
char *mystrdup(char *orig)
{
  int len = strlen(orig);
  char *dest = (char*)malloc(len+1);
  memcpy(dest, orig, len+1); // also copy terminating 0
  return dest;
}

// extract the notdir part of a pathname, returns a ptr in the same string
char *notdir(char *str)
{
  int len = strlen(str);
  int i= len-1;
  while(i>=0 && str[i]!='/' && str[i]!='\\' && str[i]!=':')
    i--;
  return &(str[i+1]);  /// possibly a "" string.
}

// get directory part of a pathname (assumes absolute pathnames)
void getdirpart(char *dest, char *src)
{
  char *cp = src;
  int i=0;
  //int len = strlen(src);
  char *ndir = notdir(src);

  while(cp < ndir)
  {
    dest[i++] = *(cp++);
  }
  dest[i] = 0;
  // remove trailing / \ or :
  if(i>0) dest[i-1] = 0;
}

// returns true if a file name exists in the list
int file_exists(struct file_info *start, char *checkname)
{
  struct file_info* fp= start;
  while(fp)
  {
    if(strcmp(fp->name, checkname)==0)
      return 1;
    fp = fp->next;
  }
  return 0;
}

// read all files from install.log, removing duplicates
void readallfiles(FILE *in)
{
  nr_files = 0;
  files = 0;
  char buf[500];
  struct file_info *newfile = 0;

  while( fscanf(in, " %499s", buf) == 1)
  {
    // duplicate ?
    if(file_exists(files, buf)) continue;
    // add
    nr_files ++;
    newfile = (struct file_info*)malloc(sizeof(struct file_info));
    newfile->name = mystrdup(buf);
    newfile->deleted = 0;
    newfile->next = files;
    files = newfile;
    //printf("Added file %s\n", buf);
  }
}

// get dirs from file list
void getdirs(void)
{
  nr_dirs = 0;
  dirs = 0;
  struct file_info *fp = files;
  struct file_info *newdir=0;
  char buf[500];

  while(fp)
  {
    // get directory part of a file
    getdirpart(buf, fp->name);
    // duplicate?
    if(file_exists(dirs, buf))
    {
      fp = fp->next;
      continue;
    }
    // add
    nr_dirs ++;
    newdir = (struct file_info*)malloc(sizeof(struct file_info));
    newdir->name = mystrdup(buf);
    newdir->deleted = 0;
    newdir->next = dirs;
    dirs = newdir;

    //printf("Added dir %s\n", buf);

    fp = fp->next;
  }
}

/// delete all files.
void delete_files()
{
  struct file_info *fp = files;

  while(fp)
  {
    /// do not complain if it fails. (returns -1)
    /// but if it works (returns 0) set deleted to true
    if(remove(fp->name) == 0)
      fp->deleted = 1;
    fp = fp->next;
  }
}

/// returns true if a dir could be deleted
int try_delete_dirs()
{
  struct file_info *dp = dirs;
  int succeed = 0;

  while(dp)
  {
    /// try deleting it.
    /// either use   int rmdir(char*) from unistd, or
    ///        use   int remove(char*) from stdio.
    /// both return -1 on failure, 0 on success.
    /// (and for both the directory must be empty on Linux)
    if( remove(dp->name) == 0 )
    {
      dp->deleted = 1;
      succeed = 1;
    }

    dp = dp->next;
  }
  return succeed;
}

/// delete only empty directories, but try deleting subdirs first.
void delete_dirs()
{
  /// try deleting all dirs until no dir can be deleted any more...
  while(try_delete_dirs())
    ;
}

/// clean up memory
void destruct()
{
  struct file_info *fp = files;
  struct file_info *nextfp;
  int all_files_deleted = 1;
  int all_dirs_deleted = 1;
  while(fp)
  {
    nextfp = fp->next;
    if(!fp->deleted)
    {
      all_files_deleted = 0;
      //printf("File %s could not be deleted.\n", fp->name);
    }
    free(fp->name);
    free(fp);
    fp = nextfp;
  }
  nr_files = 0;
  files = 0;

  fp = dirs;
  while(fp)
  {
    nextfp = fp->next;
    if(!fp->deleted)
    {
      all_dirs_deleted = 0;
      //printf("Directory %s could not be deleted.\n", fp->name);
    }
    free(fp->name);
    free(fp);
    fp = nextfp;
  }
  nr_dirs = 0;
  dirs = 0;

  if(!all_dirs_deleted)
  {
    printf("\nSome directories could not be deleted. These could contain\n"
      "temporary files or user data. Investigate by hand.\n\n");
  }
}

int main(int argc, char *argv[])
{
  char *install_log;
  char *notdir_inst;
  FILE *in;

  if( argc < 1 || argc > 2 )
  {
    printf("Usage: %s install.log\n", argv[0]);
    exit(1);
  }

  // default to current dir. (i.e. double click ?!)
  if(argc == 2)
    install_log = argv[1];
  else install_log = "install.log";
  /// get the notdir part.
  notdir_inst = notdir(install_log);
  if(strcmp(notdir_inst, "install.log") != 0)
  {
    printf("This program will only uninstall from a file 'install.log'.\n");
    exit(1);
  }

  /// read all from install.log
  in=fopen(install_log, "r");
  if(in == 0) {
    printf("No uninstallation possible: could not open %s\n", install_log);
    perror(argv[0]);
    exit(1);
  }
  readallfiles(in);
  getdirs();
  fclose(in);

  /// delete files
  delete_files();

  /// delete empty directories
  delete_dirs();

  /// clean up memory
  destruct();

  return 0;
}

<commit_msg>More Windows-friendly; less polluting of global namespace.<commit_after>/*
    Copyright (C) 2000 by W.C.A. Wijngaards

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    Description:
	Portable uninstall program.
	(will delete a set of files, and resulting empty directories)

	It will either read install.log in the working directory, or
	read install.log at the pathname given as argument.

	install.log contains the pathnames of the files that are installed
	(and will be deleted) separated by whitespace. Duplicates will be
	removed.

	(include install.log and uninst.exe pathnames into install.log
	if you wish them to be deleted as well.)
*/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

// global information
static int nr_files = 0;
static struct file_info
{
  char *name;
  int deleted;
  struct file_info* next;
} *files = 0;

static int nr_dirs = 0;
static struct file_info *dirs = 0;

// not all platforms provide strdup(), so roll our own.
static char *mystrdup(char const *orig)
{
  int len = orig != 0 ? strlen(orig) : 0;
  char *dest = (char*)malloc(len+1);
  if (orig != 0)
    memcpy(dest, orig, len);
  dest[len] = '\0';
  return dest;
}

// extract the notdir part of a pathname, returns a ptr in the same string
static char const *notdir(char const *str)
{
  int len = strlen(str);
  int i= len-1;
  while(i>=0 && str[i]!='/' && str[i]!='\\' && str[i]!=':')
    i--;
  return &(str[i+1]);  /// possibly a "" string.
}

// get directory part of a pathname (assumes absolute pathnames)
static void getdirpart(char *dest, char const *src)
{
  char const *cp = src;
  int i=0;
  char const *ndir = notdir(src);

  while(cp < ndir)
    dest[i++] = *(cp++);
  dest[i] = 0;
  // remove trailing / \ or :
  if(i>0) dest[i-1] = 0;
}

// returns true if a file name exists in the list
static int file_exists(struct file_info const *start, char const *checkname)
{
  struct file_info const* fp= start;
  while(fp)
  {
    if(strcmp(fp->name, checkname)==0)
      return 1;
    fp = fp->next;
  }
  return 0;
}

// read all files from install.log, removing duplicates
static void readallfiles(FILE *in)
{
  nr_files = 0;
  files = 0;
  char buf[2048];
  struct file_info *newfile = 0;

  while( fscanf(in, " %2047s", buf) == 1)
  {
    buf[sizeof(buf)-1] = '\0';
    // duplicate ?
    if(file_exists(files, buf)) continue;
    // add
    nr_files ++;
    newfile = (struct file_info*)malloc(sizeof(struct file_info));
    newfile->name = mystrdup(buf);
    newfile->deleted = 0;
    newfile->next = files;
    files = newfile;
    //printf("Added file %s\n", buf);
  }
}

// get dirs from file list
static void getdirs()
{
  nr_dirs = 0;
  dirs = 0;
  struct file_info *fp = files;
  struct file_info *newdir=0;
  char buf[2048];

  while(fp)
  {
    // get directory part of a file
    getdirpart(buf, fp->name);
    // duplicate?
    if(file_exists(dirs, buf))
    {
      fp = fp->next;
      continue;
    }
    // add
    nr_dirs ++;
    newdir = (struct file_info*)malloc(sizeof(struct file_info));
    newdir->name = mystrdup(buf);
    newdir->deleted = 0;
    newdir->next = dirs;
    dirs = newdir;

    //printf("Added dir %s\n", buf);

    fp = fp->next;
  }
}

/// delete all files.
static void delete_files()
{
  struct file_info *fp = files;

  while(fp)
  {
    /// do not complain if it fails. (returns -1)
    /// but if it works (returns 0) set deleted to true
    if(remove(fp->name) == 0)
      fp->deleted = 1;
    fp = fp->next;
  }
}

/// returns true if a dir could be deleted
static int try_delete_dirs()
{
  struct file_info *dp = dirs;
  int succeed = 0;

  while(dp)
  {
    /// try deleting it.
    /// either use   int rmdir(char*) from unistd, or
    ///        use   int remove(char*) from stdio.
    /// both return -1 on failure, 0 on success.
    /// (and for both the directory must be empty on Linux)
    if(remove(dp->name) == 0)
    {
      dp->deleted = 1;
      succeed = 1;
    }

    dp = dp->next;
  }
  return succeed;
}

/// delete only empty directories, but try deleting subdirs first.
static void delete_dirs()
{
  /// try deleting all dirs until no dir can be deleted any more...
  while(try_delete_dirs())
    ;
}

/// clean up memory
static void destruct()
{
  struct file_info *fp = files;
  struct file_info *nextfp;
  int all_files_deleted = 1;
  int all_dirs_deleted = 1;
  while(fp)
  {
    nextfp = fp->next;
    if(!fp->deleted)
    {
      all_files_deleted = 0;
      //printf("File %s could not be deleted.\n", fp->name);
    }
    free(fp->name);
    free(fp);
    fp = nextfp;
  }
  nr_files = 0;
  files = 0;

  fp = dirs;
  while(fp)
  {
    nextfp = fp->next;
    if(!fp->deleted)
    {
      all_dirs_deleted = 0;
      //printf("Directory %s could not be deleted.\n", fp->name);
    }
    free(fp->name);
    free(fp);
    fp = nextfp;
  }
  nr_dirs = 0;
  dirs = 0;

  if(!all_dirs_deleted)
  {
    printf("\nSome directories could not be deleted. These could contain\n"
      "temporary files or user data. Investigate by hand.\n\n");
  }
}

int main(int argc, char *argv[])
{
  char const *install_log;
  char *notdir_inst;
  char *p;
  FILE *in;

  if( argc < 1 || argc > 2 )
  {
    printf("Usage: %s install.log\n", argv[0]);
    exit(1);
  }

  // default to current dir.
  if(argc == 2)
    install_log = argv[1];
  else install_log = "install.log";
  /// get the notdir part.
  notdir_inst = mystrdup(notdir(install_log));
  for (p = notdir_inst; *p != '\0'; p++) // be Windows-friendly
    *p = tolower(*p);
  if(strcmp(notdir_inst, "install.log") != 0)
  {
    free(notdir_inst);
    printf("This program will only uninstall from a file 'install.log'.\n");
    exit(1);
  }
  free(notdir_inst);

  /// read all from install.log
  in=fopen(install_log, "r");
  if(in == 0) {
    printf("No uninstallation possible: could not open %s\n", install_log);
    perror(argv[0]);
    exit(1);
  }
  readallfiles(in);
  getdirs();
  fclose(in);

  /// delete files
  delete_files();

  /// delete empty directories
  delete_dirs();

  /// clean up memory
  destruct();

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "INI.h"
#include "core/Application.h"
#include "utils/Log.h"
#include "utils/Utils.h"

namespace ouzel
{
    INI::INI()
    {
    }

    INI::INI(const std::string& filename)
    {
        init(filename);
    }

    INI::INI(const std::vector<uint8_t>& data)
    {
        init(data);
    }

    bool INI::init(const std::string& filename)
    {
        std::vector<uint8_t> data;

        if (!sharedApplication->getFileSystem()->readFile(filename, data))
        {
            return false;
        }

        return init(data);
    }

    static inline std::vector<uint32_t>& ltrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(s.begin(), std::find_if(s.begin(), s.end(),
                                        std::not1(std::ptr_fun<int, int>(std::isspace))));
        return s;
    }

    static inline std::vector<uint32_t>& rtrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(std::find_if(s.rbegin(), s.rend(),
                             std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
        return s;
    }

    static inline std::vector<uint32_t>& trimUtf32(std::vector<uint32_t>& s)
    {
        return ltrimUtf32(rtrimUtf32(s));
    }

    bool INI::init(const std::vector<uint8_t>& data)
    {
        std::vector<uint32_t> utf32 = utf8to32(data);

        std::string section;

        for (auto i = utf32.begin(); i != utf32.end();)
        {
            if (*i == '\n' || *i == '\r' || *i == ' ' || *i == '\t') // line starts with a whitespace
            {
                ++i; // skip the white space
            }
            else if (*i == '[') // section
            {
                ++i; // skip the left bracket

                std::vector<uint32_t> sectionUtf32;
                bool parsedSection = false;

                for (;;)
                {
                    if (i == utf32.end() || *i == '\r' || *i == '\n')
                    {
                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected end of section";
                            return false;
                        }
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected comment";
                            return false;
                        }

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else if (*i == ']')
                    {
                        parsedSection = true;
                    }
                    else if (*i != ' ' && *i != '\t')
                    {
                        if (parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected character after section";
                            return false;
                        }
                    }

                    if (!parsedSection)
                    {
                        sectionUtf32.push_back(*i);
                    }

                    ++i;
                }

                if (sectionUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid section name";
                    return false;
                }

                section = utf32to8(sectionUtf32);
            }
            else if (*i == ';') // comment
            {
                ++i; // skip the semicolon

                while (i != utf32.end())
                {
                    if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }

                    ++i;
                }
            }
            else // key, value pair
            {
                if (section.empty())
                {
                    Log(Log::Level::ERR) << "No section";
                    return false;
                }

                std::vector<uint32_t> keyUtf32;
                std::vector<uint32_t> valueUtf32;
                bool parsedKey = false;

                for (;;)
                {
                    if (i == utf32.end())
                    {
                        break;
                    }
                    else if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == '=')
                    {
                        if (!parsedKey)
                        {
                            parsedKey = true;
                        }
                        else
                        {
                            Log(Log::Level::ERR) << "Unexpected character";
                            return false;
                        }
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else
                    {
                        if (!parsedKey)
                        {
                            keyUtf32.push_back(*i);
                        }
                        else
                        {
                            valueUtf32.push_back(*i);
                        }
                    }

                    ++i;
                }

                if (keyUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid key name";
                    return false;
                }

                keyUtf32 = trimUtf32(keyUtf32);
                valueUtf32 = trimUtf32(valueUtf32);

                std::string key = utf32to8(keyUtf32);
                std::string value = utf32to8(valueUtf32);

                sections[section][key] = value;
            }
        }

        return true;
    }

    std::string INI::getValue(const std::string& section, const std::string& key)
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                return valueIterator->second;
            }
        }

        return "";
    }

    void INI::setValue(const std::string& section, const std::string& key, const std::string& value)
    {
        sections[section][key] = value;
    }

    bool INI::deleteValue(const std::string& section, const std::string& key)
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                values.erase(valueIterator);
                return true;
            }
        }

        return false;
    }
}
<commit_msg>Add missing include<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cctype>
#include "INI.h"
#include "core/Application.h"
#include "utils/Log.h"
#include "utils/Utils.h"

namespace ouzel
{
    INI::INI()
    {
    }

    INI::INI(const std::string& filename)
    {
        init(filename);
    }

    INI::INI(const std::vector<uint8_t>& data)
    {
        init(data);
    }

    bool INI::init(const std::string& filename)
    {
        std::vector<uint8_t> data;

        if (!sharedApplication->getFileSystem()->readFile(filename, data))
        {
            return false;
        }

        return init(data);
    }

    static inline std::vector<uint32_t>& ltrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(s.begin(), std::find_if(s.begin(), s.end(),
                                        std::not1(std::ptr_fun<int, int>(std::isspace))));
        return s;
    }

    static inline std::vector<uint32_t>& rtrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(std::find_if(s.rbegin(), s.rend(),
                             std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
        return s;
    }

    static inline std::vector<uint32_t>& trimUtf32(std::vector<uint32_t>& s)
    {
        return ltrimUtf32(rtrimUtf32(s));
    }

    bool INI::init(const std::vector<uint8_t>& data)
    {
        std::vector<uint32_t> utf32 = utf8to32(data);

        std::string section;

        for (auto i = utf32.begin(); i != utf32.end();)
        {
            if (*i == '\n' || *i == '\r' || *i == ' ' || *i == '\t') // line starts with a whitespace
            {
                ++i; // skip the white space
            }
            else if (*i == '[') // section
            {
                ++i; // skip the left bracket

                std::vector<uint32_t> sectionUtf32;
                bool parsedSection = false;

                for (;;)
                {
                    if (i == utf32.end() || *i == '\r' || *i == '\n')
                    {
                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected end of section";
                            return false;
                        }
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected comment";
                            return false;
                        }

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else if (*i == ']')
                    {
                        parsedSection = true;
                    }
                    else if (*i != ' ' && *i != '\t')
                    {
                        if (parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected character after section";
                            return false;
                        }
                    }

                    if (!parsedSection)
                    {
                        sectionUtf32.push_back(*i);
                    }

                    ++i;
                }

                if (sectionUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid section name";
                    return false;
                }

                section = utf32to8(sectionUtf32);
            }
            else if (*i == ';') // comment
            {
                ++i; // skip the semicolon

                while (i != utf32.end())
                {
                    if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }

                    ++i;
                }
            }
            else // key, value pair
            {
                if (section.empty())
                {
                    Log(Log::Level::ERR) << "No section";
                    return false;
                }

                std::vector<uint32_t> keyUtf32;
                std::vector<uint32_t> valueUtf32;
                bool parsedKey = false;

                for (;;)
                {
                    if (i == utf32.end())
                    {
                        break;
                    }
                    else if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == '=')
                    {
                        if (!parsedKey)
                        {
                            parsedKey = true;
                        }
                        else
                        {
                            Log(Log::Level::ERR) << "Unexpected character";
                            return false;
                        }
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else
                    {
                        if (!parsedKey)
                        {
                            keyUtf32.push_back(*i);
                        }
                        else
                        {
                            valueUtf32.push_back(*i);
                        }
                    }

                    ++i;
                }

                if (keyUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid key name";
                    return false;
                }

                keyUtf32 = trimUtf32(keyUtf32);
                valueUtf32 = trimUtf32(valueUtf32);

                std::string key = utf32to8(keyUtf32);
                std::string value = utf32to8(valueUtf32);

                sections[section][key] = value;
            }
        }

        return true;
    }

    std::string INI::getValue(const std::string& section, const std::string& key)
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                return valueIterator->second;
            }
        }

        return "";
    }

    void INI::setValue(const std::string& section, const std::string& key, const std::string& value)
    {
        sections[section][key] = value;
    }

    bool INI::deleteValue(const std::string& section, const std::string& key)
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                values.erase(valueIterator);
                return true;
            }
        }

        return false;
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cctype>
#include <algorithm>
#include "INI.h"
#include "core/Engine.h"
#include "utils/Log.h"
#include "utils/Utils.h"

namespace ouzel
{
    INI::INI()
    {
    }

    INI::INI(const std::string& filename)
    {
        init(filename);
    }

    INI::INI(const std::vector<uint8_t>& data)
    {
        init(data);
    }

    bool INI::init(const std::string& filename)
    {
        std::vector<uint8_t> data;

        if (!sharedEngine->getFileSystem()->readFile(filename, data))
        {
            return false;
        }

        return init(data);
    }

    static inline std::vector<uint32_t>& ltrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(s.begin(), std::find_if(s.begin(), s.end(),
                                        std::not1(std::ptr_fun<int, int>(std::isspace))));
        return s;
    }

    static inline std::vector<uint32_t>& rtrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(std::find_if(s.rbegin(), s.rend(),
                             std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
        return s;
    }

    static inline std::vector<uint32_t>& trimUtf32(std::vector<uint32_t>& s)
    {
        return ltrimUtf32(rtrimUtf32(s));
    }

    bool INI::init(const std::vector<uint8_t>& data)
    {
        std::vector<uint32_t> utf32 = utf8to32(data);

        std::string section;

        for (auto i = utf32.begin(); i != utf32.end();)
        {
            if (*i == '\n' || *i == '\r' || *i == ' ' || *i == '\t') // line starts with a whitespace
            {
                ++i; // skip the white space
            }
            else if (*i == '[') // section
            {
                ++i; // skip the left bracket

                std::vector<uint32_t> sectionUtf32;
                bool parsedSection = false;

                for (;;)
                {
                    if (i == utf32.end() || *i == '\r' || *i == '\n')
                    {
                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected end of section";
                            return false;
                        }
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected comment";
                            return false;
                        }

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else if (*i == ']')
                    {
                        parsedSection = true;
                    }
                    else if (*i != ' ' && *i != '\t')
                    {
                        if (parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected character after section";
                            return false;
                        }
                    }

                    if (!parsedSection)
                    {
                        sectionUtf32.push_back(*i);
                    }

                    ++i;
                }

                if (sectionUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid section name";
                    return false;
                }

                section = utf32to8(sectionUtf32);
            }
            else if (*i == ';') // comment
            {
                ++i; // skip the semicolon

                while (i != utf32.end())
                {
                    if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }

                    ++i;
                }
            }
            else // key, value pair
            {
                if (section.empty())
                {
                    Log(Log::Level::ERR) << "No section";
                    return false;
                }

                std::vector<uint32_t> keyUtf32;
                std::vector<uint32_t> valueUtf32;
                bool parsedKey = false;

                for (;;)
                {
                    if (i == utf32.end())
                    {
                        break;
                    }
                    else if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == '=')
                    {
                        if (!parsedKey)
                        {
                            parsedKey = true;
                        }
                        else
                        {
                            Log(Log::Level::ERR) << "Unexpected character";
                            return false;
                        }
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else
                    {
                        if (!parsedKey)
                        {
                            keyUtf32.push_back(*i);
                        }
                        else
                        {
                            valueUtf32.push_back(*i);
                        }
                    }

                    ++i;
                }

                if (keyUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid key name";
                    return false;
                }

                keyUtf32 = trimUtf32(keyUtf32);
                valueUtf32 = trimUtf32(valueUtf32);

                std::string key = utf32to8(keyUtf32);
                std::string value = utf32to8(valueUtf32);

                sections[section][key] = value;
            }
        }

        return true;
    }

    bool INI::save(const std::string& filename)
    {
        std::vector<uint8_t> data;
        encode(data);

        return sharedEngine->getFileSystem()->writeFile(filename, data);
    }

    bool INI::encode(std::vector<uint8_t>& data)
    {
        std::string result;

        for (const auto& section : sections)
        {
            data.push_back('[');
            std::copy(section.first.begin(), section.first.end(), std::back_inserter(data));
            data.push_back(']');
            data.push_back('\n');

            for (const auto& value : section.second)
            {
                std::copy(value.first.begin(), value.first.end(), std::back_inserter(data));
                data.push_back('=');
                std::copy(value.second.begin(), value.second.end(), std::back_inserter(data));
                data.push_back('\n');
            }
        }

        return true;
    }

    std::string INI::getValue(const std::string& section, const std::string& key, const std::string& defaultValue) const
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                return valueIterator->second;
            }
        }

        return defaultValue;
    }

    void INI::setValue(const std::string& section, const std::string& key, const std::string& value)
    {
        sections[section][key] = value;
    }

    bool INI::deleteValue(const std::string& section, const std::string& key)
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                values.erase(valueIterator);
                return true;
            }
        }

        return false;
    }
}
<commit_msg>Remove the BOM<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cctype>
#include <algorithm>
#include "INI.h"
#include "core/Engine.h"
#include "utils/Log.h"
#include "utils/Utils.h"

namespace ouzel
{
    INI::INI()
    {
    }

    INI::INI(const std::string& filename)
    {
        init(filename);
    }

    INI::INI(const std::vector<uint8_t>& data)
    {
        init(data);
    }

    bool INI::init(const std::string& filename)
    {
        std::vector<uint8_t> data;

        if (!sharedEngine->getFileSystem()->readFile(filename, data))
        {
            return false;
        }

        return init(data);
    }

    static inline std::vector<uint32_t>& ltrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(s.begin(), std::find_if(s.begin(), s.end(),
                                        std::not1(std::ptr_fun<int, int>(std::isspace))));
        return s;
    }

    static inline std::vector<uint32_t>& rtrimUtf32(std::vector<uint32_t>& s)
    {
        s.erase(std::find_if(s.rbegin(), s.rend(),
                             std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
        return s;
    }

    static inline std::vector<uint32_t>& trimUtf32(std::vector<uint32_t>& s)
    {
        return ltrimUtf32(rtrimUtf32(s));
    }

    bool INI::init(const std::vector<uint8_t>& data)
    {
        std::vector<uint32_t> utf32;

        // BOM
        if (data.size() >= 3 &&
            data[0] == 0xEF &&
            data[1] == 0xBB &&
            data[2] == 0xBF)
        {
            std::vector<uint8_t> newData(data.begin() + 3, data.end());

            utf32 = utf8to32(newData);
        }
        else
        {
            utf32 = utf8to32(data);
        }

        std::string section;

        for (auto i = utf32.begin(); i != utf32.end();)
        {
            if (*i == '\n' || *i == '\r' || *i == ' ' || *i == '\t') // line starts with a whitespace
            {
                ++i; // skip the white space
            }
            else if (*i == '[') // section
            {
                ++i; // skip the left bracket

                std::vector<uint32_t> sectionUtf32;
                bool parsedSection = false;

                for (;;)
                {
                    if (i == utf32.end() || *i == '\r' || *i == '\n')
                    {
                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected end of section";
                            return false;
                        }
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        if (!parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected comment";
                            return false;
                        }

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else if (*i == ']')
                    {
                        parsedSection = true;
                    }
                    else if (*i != ' ' && *i != '\t')
                    {
                        if (parsedSection)
                        {
                            Log(Log::Level::ERR) << "Unexpected character after section";
                            return false;
                        }
                    }

                    if (!parsedSection)
                    {
                        sectionUtf32.push_back(*i);
                    }

                    ++i;
                }

                if (sectionUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid section name";
                    return false;
                }

                section = utf32to8(sectionUtf32);
            }
            else if (*i == ';') // comment
            {
                ++i; // skip the semicolon

                while (i != utf32.end())
                {
                    if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }

                    ++i;
                }
            }
            else // key, value pair
            {
                if (section.empty())
                {
                    Log(Log::Level::ERR) << "No section";
                    return false;
                }

                std::vector<uint32_t> keyUtf32;
                std::vector<uint32_t> valueUtf32;
                bool parsedKey = false;

                for (;;)
                {
                    if (i == utf32.end())
                    {
                        break;
                    }
                    else if (*i == '\r' || *i == '\n')
                    {
                        ++i; // skip the newline
                        break;
                    }
                    else if (*i == '=')
                    {
                        if (!parsedKey)
                        {
                            parsedKey = true;
                        }
                        else
                        {
                            Log(Log::Level::ERR) << "Unexpected character";
                            return false;
                        }
                    }
                    else if (*i == ';')
                    {
                        ++i; // skip the semicolon

                        for (;;)
                        {
                            if (i == utf32.end() || *i == '\r' || *i == '\n')
                            {
                                ++i; // skip the newline
                                break;
                            }

                            ++i;
                        }
                        break;
                    }
                    else
                    {
                        if (!parsedKey)
                        {
                            keyUtf32.push_back(*i);
                        }
                        else
                        {
                            valueUtf32.push_back(*i);
                        }
                    }

                    ++i;
                }

                if (keyUtf32.empty())
                {
                    Log(Log::Level::ERR) << "Invalid key name";
                    return false;
                }

                keyUtf32 = trimUtf32(keyUtf32);
                valueUtf32 = trimUtf32(valueUtf32);

                std::string key = utf32to8(keyUtf32);
                std::string value = utf32to8(valueUtf32);

                sections[section][key] = value;
            }
        }

        return true;
    }

    bool INI::save(const std::string& filename)
    {
        std::vector<uint8_t> data;
        encode(data);

        return sharedEngine->getFileSystem()->writeFile(filename, data);
    }

    bool INI::encode(std::vector<uint8_t>& data)
    {
        std::string result;

        for (const auto& section : sections)
        {
            data.push_back('[');
            std::copy(section.first.begin(), section.first.end(), std::back_inserter(data));
            data.push_back(']');
            data.push_back('\n');

            for (const auto& value : section.second)
            {
                std::copy(value.first.begin(), value.first.end(), std::back_inserter(data));
                data.push_back('=');
                std::copy(value.second.begin(), value.second.end(), std::back_inserter(data));
                data.push_back('\n');
            }
        }

        return true;
    }

    std::string INI::getValue(const std::string& section, const std::string& key, const std::string& defaultValue) const
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                return valueIterator->second;
            }
        }

        return defaultValue;
    }

    void INI::setValue(const std::string& section, const std::string& key, const std::string& value)
    {
        sections[section][key] = value;
    }

    bool INI::deleteValue(const std::string& section, const std::string& key)
    {
        auto sectionIterator = sections.find(section);
        if (sectionIterator != sections.end())
        {
            auto& values = sectionIterator->second;

            auto valueIterator = values.find(key);

            if (valueIterator != values.end())
            {
                values.erase(valueIterator);
                return true;
            }
        }

        return false;
    }
}
<|endoftext|>


<commit_before>/*
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 * Or
 * UC Berkeley EECS Computer Science Division, 387 Soda Hall #1776,
 * Berkeley, CA,  94707. Attention: P2 Group.
 *
 */

#include "val_null.h"
#include "val_vector.h"
#include "val_uint32.h"

class OperVector : public opr::OperCompare<Val_Vector> {
};

const opr::Oper* Val_Vector::oper_ = new OperVector();

VectorPtr Val_Vector::cast(ValuePtr v)
{

   switch(v->typeCode()) {
      case Value::VECTOR:
		{
		  return (static_cast<Val_Vector *>(v.get()))->V;
		default:
		  {
			throw Value::TypeError(v->typeCode(), Value::VECTOR);
		  }
		}
   }
}

// Marshal/Unmarshal essentially copied from Val_Tuple
void Val_Vector::xdr_marshal_subtype( XDR *x )
{
  ValPtrVector::const_iterator it;

  uint32_t sz = V->size();
  u_int32_t i = (u_int32_t)sz;
  xdr_uint32_t(x, &i);
  // Marshal the entries
  for (it = V->begin();  it != V->end(); ++it)
    { (*it)->xdr_marshal(x); }
}

ValuePtr Val_Vector::xdr_unmarshal( XDR *x )
{
  VectorPtr vp(new vector<ValuePtr>());
  u_int32_t ui;
  xdr_uint32_t(x, &ui);
  // Unmarshal the entries
  uint32_t sz = ui;
  for (uint32_t i = 0;
	   i < sz;
	   i++){
	vp->insert_element(i, Value::xdr_unmarshal(x));
  }
  return mk(vp);
}

string Val_Vector::toString() const
{
   ostringstream sb;

   sb << "[";

   ValPtrVector::const_iterator iter = V->begin();
   ValPtrVector::const_iterator end = V->end();
   ValPtrVector::const_iterator almost_end = V->end();
   almost_end--;

   while(iter != end) {
      sb << (*iter)->toString();

      if(iter != almost_end) {
         sb << ", ";
      }
      iter++;
   }

   sb << "]";

   return sb.str();

}

string Val_Vector::toConfString() const
{
   ostringstream sb;

   sb << "[";

   ValPtrVector::const_iterator iter = V->begin();
   ValPtrVector::const_iterator end = V->end();
   ValPtrVector::const_iterator almost_end = V->end();
   almost_end--;

   while(iter != end) {
      sb << (*iter)->toConfString();

      if(iter != almost_end) {
         sb << ", ";
      }
      iter++;
   }

   sb << "]";

   return sb.str();

}

// Vector comparison. Follow rules from Tuple
int Val_Vector::compareTo(ValuePtr other) const
{
   if(other->typeCode() < Value::VECTOR) {
      return -1;
   }
   else if(other->typeCode() > Value::VECTOR) {
      return 1;
   }
   else {
	 Val_Vector ov = cast(other);
	 if (size() == ov.V->size()) {
	   // same size
	   ValPtrVector::const_iterator myiter, oiter;
	   for (myiter = V->begin(), oiter = ov.V->begin();
			myiter != V->end(); myiter++, oiter++) {
		 int result = (*myiter)->compareTo(*oiter);
		 if (result != 0) {
		   // Found a field position for which we are different.  Return
		   // the difference.
		   return result;
		 }
	   }
	   // All fields are equal
	   return(0);
	 }
	 else if (size() < ov.V->size()) {
	   return -1;
	 }
	 else {
	   return 1;
	 }
   }
}
<commit_msg>get compatible with version of boost on grumpy<commit_after>/*
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 * Or
 * UC Berkeley EECS Computer Science Division, 387 Soda Hall #1776,
 * Berkeley, CA,  94707. Attention: P2 Group.
 *
 */

#include "val_null.h"
#include "val_vector.h"
#include "val_uint32.h"

class OperVector : public opr::OperCompare<Val_Vector> {
};

const opr::Oper* Val_Vector::oper_ = new OperVector();

VectorPtr Val_Vector::cast(ValuePtr v)
{

   switch(v->typeCode()) {
      case Value::VECTOR:
		{
		  return (static_cast<Val_Vector *>(v.get()))->V;
		default:
		  {
			throw Value::TypeError(v->typeCode(), Value::VECTOR);
		  }
		}
   }
}

// Marshal/Unmarshal essentially copied from Val_Tuple
void Val_Vector::xdr_marshal_subtype( XDR *x )
{
  ValPtrVector::const_iterator it;

  uint32_t sz = V->size();
  u_int32_t i = (u_int32_t)sz;
  xdr_uint32_t(x, &i);
  // Marshal the entries
  for (it = V->begin();  it != V->end(); ++it)
    { (*it)->xdr_marshal(x); }
}

ValuePtr Val_Vector::xdr_unmarshal( XDR *x )
{
  VectorPtr vp(new vector<ValuePtr>());
  u_int32_t ui;
  xdr_uint32_t(x, &ui);
  // Unmarshal the entries
  uint32_t sz = ui;
  for (uint32_t i = 0;
	   i < sz;
	   i++){
	vp->insert(i, Value::xdr_unmarshal(x));
  }
  return mk(vp);
}

string Val_Vector::toString() const
{
   ostringstream sb;

   sb << "[";

   ValPtrVector::const_iterator iter = V->begin();
   ValPtrVector::const_iterator end = V->end();
   ValPtrVector::const_iterator almost_end = V->end();
   almost_end--;

   while(iter != end) {
      sb << (*iter)->toString();

      if(iter != almost_end) {
         sb << ", ";
      }
      iter++;
   }

   sb << "]";

   return sb.str();

}

string Val_Vector::toConfString() const
{
   ostringstream sb;

   sb << "[";

   ValPtrVector::const_iterator iter = V->begin();
   ValPtrVector::const_iterator end = V->end();
   ValPtrVector::const_iterator almost_end = V->end();
   almost_end--;

   while(iter != end) {
      sb << (*iter)->toConfString();

      if(iter != almost_end) {
         sb << ", ";
      }
      iter++;
   }

   sb << "]";

   return sb.str();

}

// Vector comparison. Follow rules from Tuple
int Val_Vector::compareTo(ValuePtr other) const
{
   if(other->typeCode() < Value::VECTOR) {
      return -1;
   }
   else if(other->typeCode() > Value::VECTOR) {
      return 1;
   }
   else {
	 Val_Vector ov = cast(other);
	 if (size() == ov.V->size()) {
	   // same size
	   ValPtrVector::const_iterator myiter, oiter;
	   for (myiter = V->begin(), oiter = ov.V->begin();
			myiter != V->end(); myiter++, oiter++) {
		 int result = (*myiter)->compareTo(*oiter);
		 if (result != 0) {
		   // Found a field position for which we are different.  Return
		   // the difference.
		   return result;
		 }
	   }
	   // All fields are equal
	   return(0);
	 }
	 else if (size() < ov.V->size()) {
	   return -1;
	 }
	 else {
	   return 1;
	 }
   }
}
<|endoftext|>