Skip to content

Commit

Permalink
Adds basic extension parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
tinganho committed Nov 28, 2016
1 parent 6af1e3b commit 0072b95
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 68 deletions.
3 changes: 2 additions & 1 deletion Source/Extensions/JavaScript/Extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"Date",
"Number"
],
"ProgrammingLanguage": ["JavaScript", "TypeScript"],
"DependencyTest": "dep-test",
"Execute": "node bin/l10ns-ts.js"
"Execute": "node Executables/l10ns-ts.js"
}
59 changes: 36 additions & 23 deletions Source/Program/CommandController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#include "CommandParser.cpp"
#include "Configurations.h"
#include "Utils.cpp"
#include "json.hpp"

using namespace std;
using json = nlohmann::json;

namespace L10ns {

Expand Down Expand Up @@ -49,13 +51,13 @@ class TCPServer {
public:
tcp::endpoint endpoint;

TCPServer(boost::asio::io_service& service)
TCPServer(boost::asio::io_service& service, string command)
: endpoint(tcp::v4(), 0)
, local_endpoint(acceptor.local_endpoint())
, acceptor(service, endpoint) {

start_accept();
execute_command("L10NS_IS_USING_TCP_SERVER=1 L10NS_EXTENSION_SERVER_PORT=" + port() + " ./test");
execute_command("IS_USING_TCP_SERVER=1 EXTENSION_SERVER_PORT=" + port() + " " + command);
}

string port() {
Expand All @@ -82,14 +84,29 @@ class TCPServer {
}
};

void start_extension_server() {
void start_extension_server(Session* session) {
try {
vector<string> files = find_files(PROJECT_DIR "Source/Extensions/*/Extension.json");
string command;
bool found_matching_programming_language = false;
for (auto const& f : files) {
json package = json::parse(read_file(f));
vector<string> pl = package["ProgrammingLanguage"];
if (find(pl.begin(), pl.end(), *session->programming_language) != pl.end()) {
found_matching_programming_language = true;
command = package["Execute"];
break;
}
}
if (!found_matching_programming_language) {
throw invalid_argument("No matching programming language for" + *session->programming_language);
}
boost::asio::io_service service;
TCPServer server(service);
TCPServer server(service, command);
service.run();
}
catch (exception& e) {
std::cerr << e.what() << std::endl;
cerr << e.what() << endl;
}
}

Expand Down Expand Up @@ -139,8 +156,8 @@ inline Action* get_action(ActionKind action) {
throw logic_error("Could not get action name.");
}

inline void print_action_help_info(Command* command) {
auto a = get_action(command->action);
inline void print_action_help_info(Session* session) {
auto a = get_action(session->action);
auto w = new TextWriter();
w->write_line(*a->info);
w->newline();
Expand All @@ -149,7 +166,7 @@ inline void print_action_help_info(Command* command) {
w->add_tab(2);
w->add_tab(24);
w->newline();
for (const auto& flag : *get_action_flags(command->action)) {
for (const auto& flag : *get_action_flags(session->action)) {
w->tab();
if (flag.alias->length() != 0) {
w->write(*flag.name + ", " + *flag.alias);
Expand All @@ -163,39 +180,35 @@ inline void print_action_help_info(Command* command) {
w->print();
}

inline void print_command_help_info(Command* command) {
if (command->action == ActionKind::None) {
inline void print_command_help_info(Session* session) {
if (session->action == ActionKind::None) {
print_default_help_info();
}
else {
print_action_help_info(command);
print_action_help_info(session);
}
}

void sync_keys() {
start_extension_server();
}

inline void print_diagnostics(vector<Diagnostic*> diagnostics) {
for (auto const& d : diagnostics) {
cout << *d->message << endl;
}
}

int init(int argc, char* argv[]) {
auto command = parse_command_args(argc, argv);
if (command->diagnostics.size() > 0) {
print_diagnostics(command->diagnostics);
auto session = parse_command_args(argc, argv);
if (session->diagnostics.size() > 0) {
print_diagnostics(session->diagnostics);
return 1;
}
if (command->is_requesting_version) {
if (session->is_requesting_version) {
println("L10ns version ", VERSION, ".");
}
else if (command->is_requesting_help) {
print_command_help_info(command);
else if (session->is_requesting_help) {
print_command_help_info(session);
}
else if (command->action == ActionKind::Sync) {
sync_keys();
else if (session->action == ActionKind::Sync) {
start_extension_server(session);
}
return 0;
}
Expand Down
61 changes: 47 additions & 14 deletions Source/Program/CommandParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ namespace L10ns {

static Flag help_flag = Flag(FlagKind::Help, "--help", "-h", "Print help description.", /*has_value*/ false);
static Flag language_flag = Flag(FlagKind::Language, "--language", "-l", "Specify language.", false);
static Flag root_dir = Flag(FlagKind::Help, "--rootDir", "-rd", "Specify current root dir(Mainly for testing purposes).", /*has_value*/ true);

static vector<Flag> default_flags = {
help_flag,
root_dir,
Flag(FlagKind::Version, "--version", "", "Print current version.", /*has_value*/ false),
};

Expand Down Expand Up @@ -81,23 +83,50 @@ vector<Flag>* get_action_flags(ActionKind kind) {
}
}

void set_command_flag(Command* command, const Flag* flag, char* value = NULL) {
struct Session {
bool is_requesting_help;
bool is_requesting_version;
string* root_dir;
ActionKind action;
vector<Diagnostic*> diagnostics;
string* programming_language;

Session()
: is_requesting_help(false)
, is_requesting_version(false)
, action(ActionKind::None) {
}

void add_diagnostics(Diagnostic* diagnostic) {
diagnostics.push_back(diagnostic);
}

void write_file(string filename, string content) {
L10ns::write_file(filename, content, *root_dir);
}
};

void set_command_flag(Session* session, const Flag* flag, char* value = NULL) {
switch (flag->kind) {
case FlagKind::Help:
command->is_requesting_help = true;
session->is_requesting_help = true;
return;
case FlagKind::Version:
command->is_requesting_version = true;
session->is_requesting_version = true;
return;
case FlagKind::RootDir:
session->root_dir = new string(value);
return;
default:
throw invalid_argument("Unknwon command flag.");
throw invalid_argument("Unknown command flag.");
}
}

Command* parse_command_args(int argc, char* argv[]) {
Command * command = new Command();
Session* parse_command_args(int argc, char* argv[]) {
Session* session = new Session();
session->root_dir = get_cwd();

// Flag to optimize has action parsing.
// Flag to optimize parsing.
bool has_action = false;

// The option flag that is pending for a value.
Expand All @@ -111,14 +140,14 @@ Command* parse_command_args(int argc, char* argv[]) {
}
for (auto const& a : actions) {
if (strcmp(a.name->c_str(), arg) == 0) {
command->action = a.kind;
session->action = a.kind;
has_action = true;
current_flags = a.flags;
goto end_of_loop;
}
}
if (!has_action) {
command->add_diagnostics(create_diagnostic(D::Unknown_command, arg));
session->add_diagnostics(create_diagnostic(D::Unknown_command, arg));
goto end_of_loop;
}

Expand All @@ -132,23 +161,27 @@ Command* parse_command_args(int argc, char* argv[]) {
if (flag.has_value) {
flag_which_awaits_value = &flag;
}
set_command_flag(command, &flag);
set_command_flag(session, &flag);
is_known_flag = true;
}
}
if (!is_known_flag) {
command->add_diagnostics(create_diagnostic(D::Unknown_command_flag, arg));
return command;
session->add_diagnostics(create_diagnostic(D::Unknown_command_flag, arg));
return session;
}
}
else {
set_command_flag(command, flag_which_awaits_value, arg);
set_command_flag(session, flag_which_awaits_value, arg);
flag_which_awaits_value = NULL;
}

end_of_loop:;
}

return command;
if (!file_exists(*session->root_dir + "l10ns.json")) {
session->add_diagnostics(create_diagnostic(D::You_are_not_inside_a_L10ns_project));
}

return session;
}
} // L10ns
1 change: 1 addition & 0 deletions Source/Program/Diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ using namespace std;
namespace D {
auto Unknown_command = new DiagnosticTemplate("Unknown command '{0}'.");
auto Unknown_command_flag = new DiagnosticTemplate("Unknown command flag '{0}'.");
auto You_are_not_inside_a_L10ns_project = new DiagnosticTemplate("You are not inside a L10ns project.");
}
3 changes: 2 additions & 1 deletion Source/Program/Diagnostics.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"Unknown command flag '{0}'.": {},
"Unknown command '{0}'.": {}
"Unknown command '{0}'.": {},
"You are not inside a L10ns project.": {}
}
19 changes: 1 addition & 18 deletions Source/Program/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum class FlagKind {
Language,
Key,
Value,
RootDir,
};

struct DiagnosticTemplate {
Expand Down Expand Up @@ -76,22 +77,4 @@ struct Action : Argument {
}
};

struct Command {
bool is_requesting_help;
bool is_requesting_version;
ActionKind action;
vector<Diagnostic*> diagnostics;

Command()
: is_requesting_help(false)
, is_requesting_version(false)
, action(ActionKind::None) {

}

void add_diagnostics(Diagnostic* diagnostic) {
diagnostics.push_back(diagnostic);
}
};

#endif // TYPES_H
26 changes: 20 additions & 6 deletions Source/Program/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace fs = boost::filesystem;

namespace L10ns {

Diagnostic* create_diagnostic(DiagnosticTemplate* d) {
string* message = new string(d->message_template);
return new Diagnostic(message);
}

Diagnostic* create_diagnostic(DiagnosticTemplate* d, string arg1) {
string* message = new string(boost::regex_replace(d->message_template, boost::regex("\\{0\\}"), arg1));
return new Diagnostic(message);
Expand Down Expand Up @@ -151,12 +156,12 @@ class TextWriter {
}
};

inline bool file_exists(const string & filename) {
bool file_exists(const string filename) {
ifstream f(filename.c_str());
return f.good();
}

inline string read_file(string filename) {
string read_file(string filename) {
string line;
string result;
ifstream f(filename);
Expand All @@ -172,13 +177,17 @@ inline string read_file(string filename) {
}
}

inline void write_file(string filename, string content) {
void write_file(string filename, string content) {
ofstream f;
f.open(filename);
f << content;
f.close();
}

void write_file(string filename, string content, string cwd) {
write_file(cwd + filename, content);
}

void remove_all(string path) {
fs::remove_all(fs::path(path));
}
Expand Down Expand Up @@ -235,9 +244,9 @@ namespace Debug {
}
}

void recursively_create_folder(string folder) {
boost::filesystem::path dir(folder);
create_directories(dir);
void recursively_create_dir(string dir) {
boost::filesystem::path d(dir);
boost::filesystem::create_directories(d);
}

vector<string> find_files(string pattern) {
Expand All @@ -261,6 +270,11 @@ vector<string> find_files(string pattern, string cwd) {
return find_files(cwd + pattern);
}

string* get_cwd() {
boost::filesystem::path full_path(boost::filesystem::current_path());
return new string(full_path.string() + "/");
}

} // L10ns

#endif // UTILS_H
10 changes: 5 additions & 5 deletions Source/TestFramework/ProjectTestRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ void addProjectTests() {

for (auto const &p : paths) {
auto command = read_file(p + "/Command.cmd");
command = string(PROJECT_DIR) + "/Executables/l10ns " + command;
string current_dir = replace_string(p, "/Cases/", "/Current/");
recursively_create_dir(current_dir);
command = string(PROJECT_DIR) + "/Executables/l10ns --rootDir " + current_dir + " " + command;
string result = execute_command(command);
string current_folder = replace_string(p, "/Cases/", "/Current/");
recursively_create_folder(current_folder);
write_file(current_folder + "/stdout.out", result);
write_file(current_dir + "/Output.txt", result);
string test_name = p.substr(p.find_last_of("/") + 1);
test(test_name, [result, p](Test* t) {
string reference_file = replace_string(p, "/Cases/", "/Reference/");
string reference = read_file(reference_file + "/stdout.out");
string reference = read_file(reference_file + "/Output.txt");
if (result != reference) {
throw runtime_error("Assertion Error!");
}
Expand Down

0 comments on commit 0072b95

Please sign in to comment.