inLimbo
TUI Music Player that keeps you in Limbo.
 
Loading...
Searching...
No Matches
cmd-line-args.hpp
Go to the documentation of this file.
1
11#pragma once
12
14#include <iostream>
15#include <map>
16
26{
27private:
28 std::map<std::string, std::string> args;
29 std::vector<std::string> positionalArgs;
30 bool hasError = false;
31 std::string errorMessage;
32
33public:
37 static const std::vector<std::string> validFlags;
47 CommandLineArgs(int argc, char* argv[])
48 {
49 parseArgs(argc, argv);
50 if (hasError)
51 {
52 std::cerr << "\033[31mError: " << errorMessage << "\033[0m\n\n";
53 printUsage(argv[0]);
54 exit(1);
55 }
56 }
57
66 [[nodiscard]]
67 auto get(const std::string& flag, const std::string& defaultValue = "") const -> std::string
68 {
69 auto it = args.find(flag);
70 return (it != args.end()) ? it->second : defaultValue;
71 }
72
79 [[nodiscard]]
80 auto hasFlag(const std::string& flag) const -> bool
81 {
82 return args.find(flag) != args.end();
83 }
84
89 [[nodiscard]]
90 auto getPositionalArgs() const -> const std::vector<std::string>&
91 {
92 return positionalArgs;
93 }
94
103 void printUsage(const std::string& programName) const
104 {
105 std::cout << "\033[1mMusic player that keeps you in Limbo.\033[0m\n";
106 std::cout << "\033[1mUsage:\033[0m " << programName << " [options] [positional arguments]\n\n";
107
108 if (!validFlags.empty())
109 {
110 std::cout << "\033[1mValid options:\033[0m\n";
111 for (const auto& flag : validFlags)
112 {
113 std::cout << " " << flag << "\n";
114 }
115 }
116
117 std::cout << "\n";
118
119 // Project details and additional information
120 std::cout << "\033[1mProject Information:\033[0m\n";
121 std::cout << "- Name: inLimbo - Terminal-based Music Player\n";
122 std::cout << "- Author: Siddharth Karnam (nots1dd)\n";
123 std::cout << "- License: GNU GPL v3\n";
124 std::cout << "- Website: https://nots1dd.github.io/inLimbo/ (has Doxygen documentation)\n";
125 std::cout << "For any issues visit <https://github.com/nots1dd/inLimbo>\n";
126 std::cout << std::endl;
127
128 std::cout << "\033[1mDescription:\033[0m\n";
129 std::cout << " inLimbo is a TUI music player that supports seamless playback and efficient "
130 "metadata handling.\n Designed for minimalism and ease of use.\n";
131 std::cout << "\n";
132 }
133
134private:
145 void parseArgs(int argc, char* argv[])
146 {
147 for (int i = 1; i < argc; ++i)
148 {
149 std::string arg = argv[i];
150
151 if (arg[0] == '-')
152 {
153 std::string flag, value;
154 size_t eqPos = arg.find('=');
155
156 if (eqPos != std::string::npos)
157 {
158 // Handle --flag=value format
159 flag = arg.substr(0, eqPos);
160 value = arg.substr(eqPos + 1);
161 }
162 else
163 {
164 // Handle --flag value format
165 flag = arg;
166 if (i + 1 < argc && argv[i + 1][0] != '-')
167 {
168 value = argv[++i];
169 }
170 }
171
172 // Find closest matching flag for error message
173 if (std::find(validFlags.begin(), validFlags.end(), flag) == validFlags.end())
174 {
175 hasError = true;
176
177 // Find the closest matching flag for a helpful suggestion
178 std::string closestMatch = findClosestMatch(flag);
179 if (!closestMatch.empty())
180 {
181 errorMessage = "Invalid flag: '" + flag + "'. Did you mean '" + closestMatch + "'?";
182 }
183 else
184 {
185 errorMessage = "Invalid flag: '" + flag + "'";
186 }
187 return;
188 }
189
190 args[flag] = value; // Store the flag and its associated value (if any)
191 }
192 else
193 {
194 positionalArgs.push_back(arg);
195 }
196 }
197 }
198
209 [[nodiscard]]
210 auto findClosestMatch(const std::string& invalidFlag) const -> std::string
211 {
212 std::string bestMatch;
213 size_t minDist = std::string::npos;
214
215 for (const auto& validFlag : validFlags)
216 {
217 // Compute Levenshtein distance
218 size_t dist = levenshteinDistance(invalidFlag, validFlag);
219
220 // Track the flag with the smallest distance
221 if (dist < minDist)
222 {
223 minDist = dist;
224 bestMatch = validFlag;
225 }
226 }
227
228 // Only suggest if the match is reasonably close (for example, max 3 edits away)
229 return (minDist <= 3) ? bestMatch : "";
230 }
231};
232
233// Define valid flags globally
234const std::vector<std::string> CommandLineArgs::validFlags = {"--help",
235 "--show-dbus-name",
236 "--version",
237 "--clear-cache",
238 "--show-config-file",
239 "--show-log-dir",
240 "--update-cache-run",
241 "--print-song-tree",
242 "--print-songs-by-artist",
243 "--print-songs-by-genre-all",
244 "--print-song-info",
245 "--print-artists-all"};
auto getPositionalArgs() const -> const std::vector< std::string > &
Retrieves the list of positional arguments.
Definition cmd-line-args.hpp:90
CommandLineArgs(int argc, char *argv[])
Constructs a CommandLineArgs object and parses command-line arguments.
Definition cmd-line-args.hpp:47
void printUsage(const std::string &programName) const
Prints usage information and program details.
Definition cmd-line-args.hpp:103
static const std::vector< std::string > validFlags
List of valid flags supported by the application.
Definition cmd-line-args.hpp:234
auto hasFlag(const std::string &flag) const -> bool
Checks if a specific flag was provided.
Definition cmd-line-args.hpp:80
auto get(const std::string &flag, const std::string &defaultValue="") const -> std::string
Retrieves the value associated with a flag.
Definition cmd-line-args.hpp:67
auto levenshteinDistance(const std::string &s1, const std::string &s2) -> size_t
Computes the Levenshtein distance between two strings.
Definition levenshtein.hpp:36