LMMS
Loading...
Searching...
No Matches
juce_ConsoleApplication.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
27{
29}
30
31static File checkFileExists (const File& f)
32{
33 if (! f.exists())
34 ConsoleApplication::fail ("Could not find file: " + f.getFullPathName());
35
36 return f;
37}
38
40{
41 if (! f.isDirectory())
42 ConsoleApplication::fail ("Could not find folder: " + f.getFullPathName());
43
44 return f;
45}
46
48{
49 if (filename.isEmpty())
50 {
52 ConsoleApplication::fail ("Expected a filename after the " + option + " option");
53 }
54
56}
57
62
67
69{
70 auto f = resolveAsFile();
71
72 if (! f.isDirectory())
73 ConsoleApplication::fail ("Could not find folder: " + f.getFullPathName());
74
75 return f;
76}
77
78static bool isShortOptionFormat (StringRef s) { return s[0] == '-' && s[1] != '-'; }
79static bool isLongOptionFormat (StringRef s) { return s[0] == '-' && s[1] == '-' && s[2] != '-'; }
80static bool isOptionFormat (StringRef s) { return s[0] == '-'; }
81
85
87{
89 {
90 jassert (! isShortOptionFormat (option)); // this will always fail to match
91 return isLongOption ("--" + option);
92 }
93
94 return text.upToFirstOccurrenceOf ("=", false, false) == option;
95}
96
98{
99 if (isLongOption())
100 {
101 auto equalsIndex = text.indexOfChar ('=');
102
103 if (equalsIndex > 0)
104 return text.substring (equalsIndex + 1);
105 }
106
107 return {};
108}
109
111{
112 jassert (option != '-'); // this is probably not what you intended to pass in
113
114 return isShortOption() && text.containsChar (String (option)[0]);
115}
116
117bool ArgumentList::Argument::operator== (StringRef wildcard) const
118{
119 for (auto& o : StringArray::fromTokens (wildcard, "|", {}))
120 {
121 if (text == o)
122 return true;
123
124 if (isShortOptionFormat (o) && o.length() == 2 && isShortOption ((char) o[1]))
125 return true;
126
127 if (isLongOptionFormat (o) && isLongOption (o))
128 return true;
129 }
130
131 return false;
132}
133
134bool ArgumentList::Argument::operator!= (StringRef s) const { return ! operator== (s); }
135
136//==============================================================================
138 : executableName (std::move (exeName))
139{
140 args.trim();
141 args.removeEmptyStrings();
142
143 for (auto& a : args)
144 arguments.add ({ a.unquoted() });
145}
146
148 : ArgumentList (argv[0], StringArray (argv + 1, argc - 1))
149{
150}
151
152ArgumentList::ArgumentList (const String& exeName, const String& args)
153 : ArgumentList (exeName, StringArray::fromTokens (args, true))
154{
155}
156
157int ArgumentList::size() const { return arguments.size(); }
158ArgumentList::Argument ArgumentList::operator[] (int index) const { return arguments[index]; }
159
160void ArgumentList::checkMinNumArguments (int expectedMinNumberOfArgs) const
161{
162 if (size() < expectedMinNumberOfArgs)
163 ConsoleApplication::fail ("Not enough arguments!");
164}
165
167{
168 jassert (option == String (option).trim()); // passing non-trimmed strings will always fail to find a match!
169
170 for (int i = 0; i < arguments.size(); ++i)
171 if (arguments.getReference (i) == option)
172 return i;
173
174 return -1;
175}
176
178{
179 return indexOfOption (option) >= 0;
180}
181
183{
184 auto i = indexOfOption (option);
185
186 if (i >= 0)
187 arguments.remove (i);
188
189 return i >= 0;
190}
191
193{
194 if (indexOfOption (option) < 0)
195 ConsoleApplication::fail ("Expected the option " + option);
196}
197
199{
200 jassert (isOptionFormat (option)); // the thing you're searching for must be an option
201
202 for (int i = 0; i < arguments.size(); ++i)
203 {
204 auto& arg = arguments.getReference(i);
205
206 if (arg == option)
207 {
208 if (arg.isShortOption())
209 {
210 if (i < arguments.size() - 1 && ! arguments.getReference (i + 1).isOption())
211 return arguments.getReference (i + 1).text;
212
213 return {};
214 }
215
216 if (arg.isLongOption())
217 return arg.getLongOptionValue();
218 }
219 }
220
221 return {};
222}
223
225{
226 jassert (isOptionFormat (option)); // the thing you're searching for must be an option
227
228 for (int i = 0; i < arguments.size(); ++i)
229 {
230 auto& arg = arguments.getReference(i);
231
232 if (arg == option)
233 {
234 if (arg.isShortOption())
235 {
236 if (i < arguments.size() - 1 && ! arguments.getReference (i + 1).isOption())
237 {
238 auto result = arguments.getReference (i + 1).text;
239 arguments.removeRange (i, 2);
240 return result;
241 }
242
243 arguments.remove (i);
244 return {};
245 }
246
247 if (arg.isLongOption())
248 {
249 auto result = arg.getLongOptionValue();
250 arguments.remove (i);
251 return result;
252 }
253 }
254 }
255
256 return {};
257}
258
263
268
273
278
283
288
289//==============================================================================
295
296void ConsoleApplication::fail (String errorMessage, int returnCode)
297{
298 throw ConsoleAppFailureCode { std::move (errorMessage), returnCode };
299}
300
302{
303 int returnCode = 0;
304
305 try
306 {
307 returnCode = f();
308 }
309 catch (const ConsoleAppFailureCode& error)
310 {
311 std::cerr << error.errorMessage << std::endl;
312 returnCode = error.returnCode;
313 }
314
315 return returnCode;
316}
317
318const ConsoleApplication::Command* ConsoleApplication::findCommand (const ArgumentList& args, bool optionMustBeFirstArg) const
319{
320 for (auto& c : commands)
321 {
322 auto index = args.indexOfOption (c.commandOption);
323
324 if (optionMustBeFirstArg ? (index == 0) : (index >= 0))
325 return &c;
326 }
327
329 return &commands[(size_t) commandIfNoOthersRecognised];
330
331 return {};
332}
333
334int ConsoleApplication::findAndRunCommand (const ArgumentList& args, bool optionMustBeFirstArg) const
335{
336 return invokeCatchingFailures ([&args, optionMustBeFirstArg, this]
337 {
338 if (auto c = findCommand (args, optionMustBeFirstArg))
339 c->command (args);
340 else
341 fail ("Unrecognised arguments");
342
343 return 0;
344 });
345}
346
348{
350}
351
353{
354 commands.emplace_back (std::move (c));
355}
356
362
363void ConsoleApplication::addHelpCommand (String arg, String helpMessage, bool makeDefaultCommand)
364{
365 Command c { arg, arg, "Prints the list of commands", {},
366 [this, helpMessage] (const ArgumentList& args)
367 {
368 std::cout << helpMessage << std::endl;
369 printCommandList (args);
370 }};
371
372 if (makeDefaultCommand)
373 addDefaultCommand (std::move (c));
374 else
375 addCommand (std::move (c));
376}
377
379{
380 addCommand ({ arg, arg, "Prints the current version number", {},
381 [versionText] (const ArgumentList&)
382 {
383 std::cout << versionText << std::endl;
384 }});
385}
386
387const std::vector<ConsoleApplication::Command>& ConsoleApplication::getCommands() const
388{
389 return commands;
390}
391
393{
394 auto exeName = args.executableName.fromLastOccurrenceOf ("/", false, false)
395 .fromLastOccurrenceOf ("\\", false, false);
396
397 return " " + exeName + " " + command.argumentDescription;
398}
399
400static void printCommandDescription (const ArgumentList& args, const ConsoleApplication::Command& command,
401 int descriptionIndent)
402{
403 auto nameAndArgs = getExeNameAndArgs (args, command);
404
405 if (nameAndArgs.length() > descriptionIndent)
406 std::cout << nameAndArgs << std::endl << String().paddedRight (' ', descriptionIndent);
407 else
408 std::cout << nameAndArgs.paddedRight (' ', descriptionIndent);
409
410 std::cout << command.shortDescription << std::endl;
411}
412
414{
415 int descriptionIndent = 0;
416
417 for (auto& c : commands)
418 descriptionIndent = std::max (descriptionIndent, getExeNameAndArgs (args, c).length());
419
420 descriptionIndent = std::min (descriptionIndent + 2, 40);
421
422 for (auto& c : commands)
423 printCommandDescription (args, c, descriptionIndent);
424
425 std::cout << std::endl;
426}
427
428void ConsoleApplication::printCommandDetails (const ArgumentList& args, const Command& command) const
429{
430 auto len = getExeNameAndArgs (args, command).length();
431
432 printCommandDescription (args, command, std::min (len + 3, 40));
433
434 if (command.longDescription.isNotEmpty())
435 std::cout << std::endl << command.longDescription << std::endl;
436}
437
438
439} // namespace juce
uint8_t a
Definition Spc_Cpu.h:141
static File getCurrentWorkingDirectory()
Definition File.cpp:1395
Definition juce_File.h:45
File getChildFile(StringRef relativeOrAbsolutePath) const
Definition juce_File.cpp:412
Definition juce_StringArray.h:35
void removeEmptyStrings(bool removeWhitespaceStrings=true)
Definition juce_StringArray.cpp:250
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Definition juce_StringArray.cpp:387
void trim()
Definition juce_StringArray.cpp:266
Definition juce_String.h:53
String paddedRight(juce_wchar padCharacter, int minimumLength) const
Definition juce_String.cpp:1188
String fromLastOccurrenceOf(StringRef substringToFind, bool includeSubStringInResult, bool ignoreCase) const
Definition juce_String.cpp:1575
bool isNotEmpty() const noexcept
Definition juce_String.h:316
Definition juce_StringRef.h:62
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned f
Definition inflate.c:1572
static char filename[]
Definition features.c:5
char * argv[]
Definition unzip.c:738
static const char * name
Definition pugl.h:1582
#define jassert(expression)
Definition carla_juce.cpp:31
jack_client_t client jack_client_t client jack_client_t client jack_client_t JackInfoShutdownCallback void * arg
Definition juce_linux_JackAudio.cpp:63
static bool isOptionFormat(StringRef s)
Definition juce_ConsoleApplication.cpp:80
static File checkFileExists(const File &f)
Definition juce_ConsoleApplication.cpp:31
static File resolveFilename(const String &name)
Definition juce_ConsoleApplication.cpp:26
static String getExeNameAndArgs(const ArgumentList &args, const ConsoleApplication::Command &command)
Definition juce_ConsoleApplication.cpp:392
static bool isShortOptionFormat(StringRef s)
Definition juce_ConsoleApplication.cpp:78
static File resolveFilenameForOption(const ArgumentList &args, StringRef option, const String &filename)
Definition juce_ConsoleApplication.cpp:47
static void printCommandDescription(const ArgumentList &args, const ConsoleApplication::Command &command, int descriptionIndent)
Definition juce_ConsoleApplication.cpp:400
static File checkFolderExists(const File &f)
Definition juce_ConsoleApplication.cpp:39
static bool isLongOptionFormat(StringRef s)
Definition juce_ConsoleApplication.cpp:79
Definition juce_Uuid.h:141
#define true
Definition ordinals.h:82
png_uint_32 length
Definition png.c:2247
Definition juce_ConsoleApplication.h:59
File resolveAsExistingFile() const
Definition juce_ConsoleApplication.cpp:63
String text
Definition juce_ConsoleApplication.h:61
bool isLongOption() const
Definition juce_ConsoleApplication.cpp:82
bool isLongOption(const String &optionRoot) const
Definition juce_ConsoleApplication.cpp:86
File resolveAsExistingFolder() const
Definition juce_ConsoleApplication.cpp:68
bool isShortOption() const
Definition juce_ConsoleApplication.cpp:83
File resolveAsFile() const
Definition juce_ConsoleApplication.cpp:58
String getLongOptionValue() const
Definition juce_ConsoleApplication.cpp:97
bool isOption() const
Definition juce_ConsoleApplication.cpp:84
Definition juce_ConsoleApplication.h:39
File getExistingFileForOptionAndRemove(StringRef option)
Definition juce_ConsoleApplication.cpp:274
String removeValueForOption(StringRef option)
Definition juce_ConsoleApplication.cpp:224
File getExistingFileForOption(StringRef option) const
Definition juce_ConsoleApplication.cpp:269
bool removeOptionIfFound(StringRef option)
Definition juce_ConsoleApplication.cpp:182
File getExistingFolderForOption(StringRef option) const
Definition juce_ConsoleApplication.cpp:279
int indexOfOption(StringRef option) const
Definition juce_ConsoleApplication.cpp:166
String executableName
Definition juce_ConsoleApplication.h:200
File getFileForOption(StringRef option) const
Definition juce_ConsoleApplication.cpp:259
void failIfOptionIsMissing(StringRef option) const
Definition juce_ConsoleApplication.cpp:192
Array< Argument > arguments
Definition juce_ConsoleApplication.h:203
bool containsOption(StringRef option) const
Definition juce_ConsoleApplication.cpp:177
void checkMinNumArguments(int expectedMinNumberOfArgs) const
Definition juce_ConsoleApplication.cpp:160
String getValueForOption(StringRef option) const
Definition juce_ConsoleApplication.cpp:198
int size() const
Definition juce_ConsoleApplication.cpp:157
ArgumentList(String executable, StringArray arguments)
Definition juce_ConsoleApplication.cpp:137
File getFileForOptionAndRemove(StringRef option)
Definition juce_ConsoleApplication.cpp:264
File getExistingFolderForOptionAndRemove(StringRef option)
Definition juce_ConsoleApplication.cpp:284
Definition juce_ConsoleApplication.cpp:291
String errorMessage
Definition juce_ConsoleApplication.cpp:292
int returnCode
Definition juce_ConsoleApplication.cpp:293
Definition juce_ConsoleApplication.h:247
String argumentDescription
Definition juce_ConsoleApplication.h:256
String shortDescription
Definition juce_ConsoleApplication.h:261
String longDescription
Definition juce_ConsoleApplication.h:264
void printCommandDetails(const ArgumentList &, const Command &) const
Definition juce_ConsoleApplication.cpp:428
int findAndRunCommand(const ArgumentList &, bool optionMustBeFirstArg=false) const
Definition juce_ConsoleApplication.cpp:334
void addDefaultCommand(Command)
Definition juce_ConsoleApplication.cpp:357
void printCommandList(const ArgumentList &) const
Definition juce_ConsoleApplication.cpp:413
const Command * findCommand(const ArgumentList &, bool optionMustBeFirstArg) const
Definition juce_ConsoleApplication.cpp:318
int commandIfNoOthersRecognised
Definition juce_ConsoleApplication.h:350
void addCommand(Command)
Definition juce_ConsoleApplication.cpp:352
static int invokeCatchingFailures(std::function< int()> &&functionToCall)
Definition juce_ConsoleApplication.cpp:301
void addHelpCommand(String helpArgument, String helpMessage, bool makeDefaultCommand)
Definition juce_ConsoleApplication.cpp:363
void addVersionCommand(String versionArgument, String versionText)
Definition juce_ConsoleApplication.cpp:378
std::vector< Command > commands
Definition juce_ConsoleApplication.h:349
static void fail(String errorMessage, int returnCode=1)
Definition juce_ConsoleApplication.cpp:296
const std::vector< Command > & getCommands() const
Definition juce_ConsoleApplication.cpp:387
Definition mygetopt.h:88
return c
Definition crypt.c:175
int error
Definition extract.c:1038
ulg size
Definition extract.c:2350
int result
Definition process.c:1455
typedef int(UZ_EXP MsgFn)()
int argc
Definition zipinfo.c:455