hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
formatter.cpp
Go to the documentation of this file.
1#include "share/defines.h"
6#include <iostream>
7#include <fstream>
8#include <filesystem>
9#include <sstream>
10
11namespace fs = std::filesystem;
12
13void printUsage(const char* programName) {
14 std::cerr << "hoshi-format tool\n";
15 std::cout << "Usage: " << programName << " [options] <input_file>\n"
16 << "Options:\n"
17 << " -o <path> Set output file path. If not specified, prints to stdout.\n"
18 << " --indent-size <n> Set indentation size (default: 4).\n"
19 << " --indent-type <space|tab> Set indentation type (default: space).\n"
20 << " --brace-style <attached|newline> Set brace style (default: attached).\n"
21 << " --max-width <n> Set maximum line width (default: 80).\n"
22 << " -h, --help Display this help message.\n";
23}
24
25int main(int argc, const char **argv) {
26 std::string inputFile;
27 std::string outputPath;
29
30 for (int i = 1; i < argc; ++i) {
31 std::string arg = argv[i];
32 if (arg == "-o") {
33 if (i + 1 < argc) outputPath = argv[++i];
34 else { std::cerr << "Error: -o requires a path.\n"; return 1; }
35 } else if (arg == "--indent-size") {
36 if (i + 1 < argc) opt.indentSize = std::stoul(argv[++i]);
37 else { std::cerr << "Error: --indent-size requires a number.\n"; return 1; }
38 } else if (arg == "--indent-type") {
39 if (i + 1 < argc) {
40 std::string type = argv[++i];
41 if (type == "space") opt.indentType = yoi::FormatOption::IndentType::Space;
42 else if (type == "tab") opt.indentType = yoi::FormatOption::IndentType::Tab;
43 else { std::cerr << "Error: Invalid indent-type '" << type << "'.\n"; return 1; }
44 } else { std::cerr << "Error: --indent-type requires space|tab.\n"; return 1; }
45 } else if (arg == "--brace-style") {
46 if (i + 1 < argc) {
47 std::string style = argv[++i];
48 if (style == "attached") opt.braceType = yoi::FormatOption::BraceType::Attached;
49 else if (style == "newline") opt.braceType = yoi::FormatOption::BraceType::NewLine;
50 else { std::cerr << "Error: Invalid brace-style '" << style << "'.\n"; return 1; }
51 } else { std::cerr << "Error: --brace-style requires attached|newline.\n"; return 1; }
52 } else if (arg == "--max-width") {
53 if (i + 1 < argc) opt.maxWidth = std::stoul(argv[++i]);
54 else { std::cerr << "Error: --max-width requires a number.\n"; return 1; }
55 } else if (arg == "-h" || arg == "--help") {
56 printUsage(argv[0]);
57 return 0;
58 } else if (!arg.starts_with("-")) {
59 if (inputFile.empty()) inputFile = arg;
60 else { std::cerr << "Error: Multiple input files specified.\n"; return 1; }
61 } else {
62 std::cerr << "Error: Unknown argument '" << arg << "'.\n";
63 printUsage(argv[0]);
64 return 1;
65 }
66 }
67
68 if (inputFile.empty()) {
69 std::cerr << "Error: No input file provided.\n";
70 printUsage(argv[0]);
71 return 1;
72 }
73
74 if (!fs::exists(inputFile)) {
75 std::cerr << "Error: Input file '" << inputFile << "' does not exist.\n";
76 return 1;
77 }
78
79 try {
80 std::ifstream ifs(inputFile, std::ios::binary);
81 if (!ifs.is_open()) {
82 std::cerr << "Error: Could not open input file '" << inputFile << "'.\n";
83 return 1;
84 }
85 std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
86 ifs.close();
87
88 yoi::wstr wcontent = yoi::string2wstring(content);
89 yoi::lexer l{std::wstringstream(wcontent)};
90 l.scan();
91
92 yoi::hoshiModule *mod = nullptr;
93 yoi::parse(mod, l);
94
95 if (!mod) {
96 std::cerr << "Error: Parsing failed for '" << inputFile << "'.\n";
97 return 1;
98 }
99
100 if (outputPath.empty()) {
101 yoi::Formatter formatter(std::wcout, opt, l.comments);
102 formatter.format(mod);
103 std::wcout << std::endl;
104 } else {
105 std::wofstream ofs(outputPath);
106 if (!ofs.is_open()) {
107 std::cerr << "Error: Could not open output file '" << outputPath << "'.\n";
108 return 1;
109 }
110 yoi::Formatter formatter(ofs, opt, l.comments);
111 formatter.format(mod);
112 ofs << std::endl;
113 ofs.close();
114 std::cout << "Formatted output written to '" << outputPath << "'.\n";
115 }
116
117 } catch (const std::exception &e) {
118 std::cerr << "Error during formatting: " << e.what() << std::endl;
119 return 1;
120 }
121
122 return 0;
123}
void format(const lexer::token &token)
token scan()
Definition lexer.cpp:29
void printUsage(const char *programName)
Definition formatter.cpp:13
int main()
Definition loop.cpp:3
std::wstring string2wstring(const std::string &v)
Definition def.cpp:178
std::wstring wstr
Definition def.hpp:48
void parse(yoi::basicLiterals *&o, yoi::lexer &lex)
Definition parser.cpp:25