Skip to content

Commit

Permalink
Makefile
Browse files Browse the repository at this point in the history
  • Loading branch information
SermetPekin committed Nov 6, 2024
1 parent 89223df commit 56f0865
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 194 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ build/
evdscpp
evdscpp.dSYM

*.txt
!example.txt

47 changes: 47 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Makefile for evdscpp
BUILD_DIR := build

# Compiler options
CXX := g++
CXXFLAGS := -std=c++20

# Default target
.PHONY: all
all: configure build

# Configure the project using CMake
.PHONY: configure
configure:
mkdir -p $(BUILD_DIR)
cd $(BUILD_DIR) && cmake ..

# Build the project
.PHONY: build
build: configure
cd $(BUILD_DIR) && make

# Run the executable
.PHONY: run
run: build
./$(BUILD_DIR)/bin/evdscpp
./$(BUILD_DIR)/bin/evdscpp ./example.txt --cache true


# Run tests
.PHONY: test
test: build
cd $(BUILD_DIR) && ctest --output-on-failure

# Clean the build directory
.PHONY: clean
clean:
rm -rf $(BUILD_DIR)

# Valgrind memory check (requires Valgrind)
.PHONY: valgrind
valgrind: build
if command -v valgrind >/dev/null 2>&1; then \
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose ./$(BUILD_DIR)/bin/evdscpp; \
else \
echo "Valgrind not found. Skipping memory check."; \
fi
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ You can obtain a free EVDS API key by registering on the EVDS website provided b
# this will create two different files. One for the first index `bie_yssk` and one for these indexes TP.DK.USD.A-TP.DK.EUR.A
./evdscpp bie_yssk,TP.DK.USD.A-TP.DK.EUR.A --cache true

# indexes can be read from a text file as well
./evdscpp example.txt --cache true



```


Expand Down
2 changes: 2 additions & 0 deletions example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bie_yssk
TP.DK.USD.A-TP.DK.EUR.A
182 changes: 182 additions & 0 deletions include/e_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <functional>
#include <fstream>

#include <type_traits>

struct ParseArgsOptions
{
int argc;
char **argv;
std::vector<std::string> &indexes;
};

std::vector<std::string> indexes_from_file(const std::string &file_path);


template <typename T>
bool looks_like_filename(const T &name, const std::string& extension = ".txt") {
static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view>,
"T must be either std::string or std::string_view");
return name.find(extension) != std::string::npos;
}


std::unordered_map<std::string, std::string> parseArgs(ParseArgsOptions &options)
{
std::unordered_map<std::string, std::string> args;

bool namedArgsFound = false;

for (int i = 1; i < options.argc; ++i)
{
std::string arg = options.argv[i];

if (arg.rfind("--", 0) == 0)
{
namedArgsFound = true;
std::string key = arg.substr(2);
if (i + 1 < options.argc)
{
args[key] = options.argv[++i];
}
else
{
args[key] = "true";
}
}
else if (!namedArgsFound)
{

std::istringstream iss(arg);
std::string index;
while (std::getline(iss, index, ','))
{
if (looks_like_filename(index))
options.indexes = indexes_from_file(index);
else
options.indexes.push_back(index);
}
}
}

return args;
}




std::vector<std::string> indexes_from_file(const std::string &file_path)
{
std::vector<std::string> indexes;
std::ifstream file(file_path);

if (!file.is_open())
{
std::cerr << "Error: Could not open file " << file_path << std::endl;
return indexes;
}

std::string line;

while (std::getline(file, line))
{
indexes.push_back(line);
}

file.close();
return indexes;
}


void setConfigOptions(const std::unordered_map<std::string, std::string> &args, Config &config)
{
std::unordered_map<std::string, std::function<void(const std::string &)>> configSetters = {
{"cache", [&](const std::string &val)
{ config.cache = (val == "true"); }},
{"test", [&](const std::string &val)
{ config.test = (val == "true"); }},

// auto_confirm
{"confirm", [&](const std::string &val)
{ config.auto_confirm = (val == "true"); }},

{"auto_confirm", [&](const std::string &val)
{ config.auto_confirm = (val == "true"); }},

{"verbose", [&](const std::string &val)
{ config.verbose = (val == "true"); }},

{"start_date", [&](const std::string &val)
{ config.start_date = val; }},
{"end_date", [&](const std::string &val)
{ config.end_date = val; }},
{"frequency", [&](const std::string &val)
{ config.frequency = val; }},
{"formulas", [&](const std::string &val)
{ config.formulas = val; }},
{"aggregation", [&](const std::string &val)
{ config.aggregation = val; }}};

for (const auto &arg : args)
{
if (configSetters.count(arg.first))
{
configSetters[arg.first](arg.second);
}
}
}



void show_usage()
{
std::cout << "Usage:\n";
std::cout << " evdscpp <indexes> [options]\n\n";
std::cout << "Description:\n";
std::cout << " evdscpp is a command-line tool for requesting data from the EVDS API.\n\n";

std::cout << "Arguments:\n";
std::cout << " <indexes> Comma-separated list of indexes to request.\n";
std::cout << " Example: TP.DK.USD.A,TP.DK.EUR.A\n";
std::cout << " Use hyphen (-) to group indexes in a single file.\n\n";

std::cout << "Options:\n";
std::cout << " --start_date <date> Specify the start date (format: DD-MM-YYYY).\n";
std::cout << " Example: --start_date 01-01-2021\n";
std::cout << " --end_date <date> Specify the end date (format: DD-MM-YYYY).\n";
std::cout << " Example: --end_date 31-12-2021\n";
std::cout << " --cache <true|false> Enable or disable caching.\n";
std::cout << " Example: --cache true\n";
std::cout << " --frequency <frequency> Set the frequency (e.g., daily, monthly, annual).\n";
std::cout << " Example: --frequency monthly\n";
std::cout << " --formulas <formulas> Set the formulas (e.g., avg, sum).\n";
std::cout << " Example: --formulas avg\n";
std::cout << " --aggregation <type> Set the aggregation type.\n";
std::cout << " Example: --aggregation avg\n\n";

std::cout << "Examples:\n";
std::cout << " # 1. Each index will have its own file:\n";
std::cout << " ./evdscpp TP.DK.USD.A,TP.DK.EUR.A\n\n";

std::cout << " # 2. Two indexes in the same file:\n";
std::cout << " ./evdscpp TP.DK.USD.A-TP.DK.EUR.A\n\n";

std::cout << " # 3. Using indexes with named arguments:\n";
std::cout << " ./evdscpp TP.DK.USD.A,TP.DK.EUR.A --start_date 01-01-2021 --end_date 31-12-2021 --cache true\n\n";

std::cout << " # Another example with a different index:\n";
std::cout << " ./evdscpp bie_yssk --cache true\n\n";

std::cout << " # Another example with three different indexes:\n";
std::cout << " # This will create two different files. One for `bie_yssk` and one for `TP.DK.USD.A-TP.DK.EUR.A`\n";
std::cout << " ./evdscpp bie_yssk,TP.DK.USD.A-TP.DK.EUR.A --cache true\n\n";

std::cout << "Notes:\n";
std::cout << " - The <indexes> argument is required.\n";
std::cout << " - Options are optional but provide more control over the query.\n";
std::cout << " - examples and code on https://github.com/SermetPekin/evdscpp\n";
}
24 changes: 13 additions & 11 deletions include/get.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
/*
* evdscpp: An open-source data wrapper for accessing the EVDS API.
* Author: Sermet Pekin
*
*
* MIT License
*
*
* Copyright (c) 2024 Sermet Pekin
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -25,7 +25,6 @@
* SOFTWARE.
*/


#include "dotenv_.h"

#include <curl/curl.h>
Expand Down Expand Up @@ -119,7 +118,7 @@ std::enable_if_t<is_cstring<T>::value, const char *> get_proxy_for_url(T url, T
return "";
}

std::string get_request_real(const GetParams &params, bool test);
std::string get_request_real(const GetParams &params, bool test, bool auto_confirm);

std::string get_request(const GetParams &params, const Config &config)
{
Expand All @@ -143,16 +142,19 @@ std::string get_request(const GetParams &params, const Config &config)
return cached_result;
}

auto res = get_request_real(params, config.test);
if (!config.auto_confirm)
throw std::runtime_error("[2]Something is wrong with auto confirm");

auto res = get_request_real(params, config.test, config.auto_confirm);
if (cache_option)
cache.save_cache(fnc_name, res, params_str);
return res;
}
std::string get_request_real(const GetParams &params, bool test)
std::string get_request_real(const GetParams &params, bool test, bool auto_confirm)
{
// if (config.test)


if (!test & !evds::confirm("Request?", params.url, params.verbose))
if (!auto_confirm && !test && !evds::confirm("Request?", params.url, params.verbose))
{
std::cout << "Not requesting ...";
throw std::runtime_error("Request was cancelled ");
Expand Down
Loading

0 comments on commit 56f0865

Please sign in to comment.