Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "nsICommandLineRunner.h"
6 :
7 : #include "nsICategoryManager.h"
8 : #include "nsICommandLineHandler.h"
9 : #include "nsICommandLineValidator.h"
10 : #include "nsIConsoleService.h"
11 : #include "nsIClassInfoImpl.h"
12 : #include "nsIDOMWindow.h"
13 : #include "nsIFile.h"
14 : #include "nsISimpleEnumerator.h"
15 : #include "nsIStringEnumerator.h"
16 :
17 : #include "nsCOMPtr.h"
18 : #include "mozilla/ModuleUtils.h"
19 : #include "nsISupportsImpl.h"
20 : #include "nsNativeCharsetUtils.h"
21 : #include "nsNetUtil.h"
22 : #include "nsIFileProtocolHandler.h"
23 : #include "nsIURI.h"
24 : #include "nsUnicharUtils.h"
25 : #include "nsTArray.h"
26 : #include "nsTextFormatter.h"
27 : #include "nsXPCOMCID.h"
28 : #include "plstr.h"
29 : #include "mozilla/Attributes.h"
30 :
31 : #ifdef MOZ_WIDGET_COCOA
32 : #include <CoreFoundation/CoreFoundation.h>
33 : #include "nsILocalFileMac.h"
34 : #elif defined(XP_WIN)
35 : #include <windows.h>
36 : #include <shlobj.h>
37 : #elif defined(XP_UNIX)
38 : #include <unistd.h>
39 : #endif
40 :
41 : #ifdef DEBUG_bsmedberg
42 : #define DEBUG_COMMANDLINE
43 : #endif
44 :
45 : #define NS_COMMANDLINE_CID \
46 : { 0x23bcc750, 0xdc20, 0x460b, { 0xb2, 0xd4, 0x74, 0xd8, 0xf5, 0x8d, 0x36, 0x15 } }
47 :
48 : class nsCommandLine final : public nsICommandLineRunner
49 : {
50 : public:
51 : NS_DECL_ISUPPORTS
52 : NS_DECL_NSICOMMANDLINE
53 : NS_DECL_NSICOMMANDLINERUNNER
54 :
55 : nsCommandLine();
56 :
57 : protected:
58 0 : ~nsCommandLine() = default;
59 :
60 : typedef nsresult (*EnumerateHandlersCallback)(nsICommandLineHandler* aHandler,
61 : nsICommandLine* aThis,
62 : void *aClosure);
63 : typedef nsresult (*EnumerateValidatorsCallback)(nsICommandLineValidator* aValidator,
64 : nsICommandLine* aThis,
65 : void *aClosure);
66 :
67 : void appendArg(const char* arg);
68 : MOZ_MUST_USE nsresult resolveShortcutURL(nsIFile* aFile, nsACString& outURL);
69 : nsresult EnumerateHandlers(EnumerateHandlersCallback aCallback, void *aClosure);
70 : nsresult EnumerateValidators(EnumerateValidatorsCallback aCallback, void *aClosure);
71 :
72 : nsTArray<nsString> mArgs;
73 : uint32_t mState;
74 : nsCOMPtr<nsIFile> mWorkingDir;
75 : nsCOMPtr<nsIDOMWindow> mWindowContext;
76 : bool mPreventDefault;
77 : };
78 :
79 1 : nsCommandLine::nsCommandLine() :
80 : mState(STATE_INITIAL_LAUNCH),
81 1 : mPreventDefault(false)
82 : {
83 :
84 1 : }
85 :
86 :
87 3 : NS_IMPL_CLASSINFO(nsCommandLine, nullptr, 0, NS_COMMANDLINE_CID)
88 106 : NS_IMPL_ISUPPORTS_CI(nsCommandLine,
89 : nsICommandLine,
90 : nsICommandLineRunner)
91 :
92 : NS_IMETHODIMP
93 2 : nsCommandLine::GetLength(int32_t *aResult)
94 : {
95 2 : *aResult = int32_t(mArgs.Length());
96 2 : return NS_OK;
97 : }
98 :
99 : NS_IMETHODIMP
100 1 : nsCommandLine::GetArgument(int32_t aIndex, nsAString& aResult)
101 : {
102 1 : NS_ENSURE_ARG_MIN(aIndex, 0);
103 1 : NS_ENSURE_ARG_MAX(aIndex, int32_t(mArgs.Length() - 1));
104 :
105 1 : aResult = mArgs[aIndex];
106 1 : return NS_OK;
107 : }
108 :
109 : NS_IMETHODIMP
110 29 : nsCommandLine::FindFlag(const nsAString& aFlag, bool aCaseSensitive, int32_t *aResult)
111 : {
112 29 : NS_ENSURE_ARG(!aFlag.IsEmpty());
113 :
114 29 : nsDefaultStringComparator caseCmp;
115 29 : nsCaseInsensitiveStringComparator caseICmp;
116 : nsStringComparator& c = aCaseSensitive ?
117 : static_cast<nsStringComparator&>(caseCmp) :
118 29 : static_cast<nsStringComparator&>(caseICmp);
119 :
120 58 : for (uint32_t f = 0; f < mArgs.Length(); f++) {
121 29 : const nsString &arg = mArgs[f];
122 :
123 29 : if (arg.Length() >= 2 && arg.First() == char16_t('-')) {
124 0 : if (aFlag.Equals(Substring(arg, 1), c)) {
125 0 : *aResult = f;
126 0 : return NS_OK;
127 : }
128 : }
129 : }
130 :
131 29 : *aResult = -1;
132 29 : return NS_OK;
133 : }
134 :
135 : NS_IMETHODIMP
136 0 : nsCommandLine::RemoveArguments(int32_t aStart, int32_t aEnd)
137 : {
138 0 : NS_ENSURE_ARG_MIN(aStart, 0);
139 0 : NS_ENSURE_ARG_MAX(uint32_t(aEnd) + 1, mArgs.Length());
140 :
141 0 : for (int32_t i = aEnd; i >= aStart; --i) {
142 0 : mArgs.RemoveElementAt(i);
143 : }
144 :
145 0 : return NS_OK;
146 : }
147 :
148 : NS_IMETHODIMP
149 12 : nsCommandLine::HandleFlag(const nsAString& aFlag, bool aCaseSensitive,
150 : bool *aResult)
151 : {
152 : nsresult rv;
153 :
154 : int32_t found;
155 12 : rv = FindFlag(aFlag, aCaseSensitive, &found);
156 12 : NS_ENSURE_SUCCESS(rv, rv);
157 :
158 12 : if (found == -1) {
159 12 : *aResult = false;
160 12 : return NS_OK;
161 : }
162 :
163 0 : *aResult = true;
164 0 : RemoveArguments(found, found);
165 :
166 0 : return NS_OK;
167 : }
168 :
169 : NS_IMETHODIMP
170 14 : nsCommandLine::HandleFlagWithParam(const nsAString& aFlag, bool aCaseSensitive,
171 : nsAString& aResult)
172 : {
173 : nsresult rv;
174 :
175 : int32_t found;
176 14 : rv = FindFlag(aFlag, aCaseSensitive, &found);
177 14 : NS_ENSURE_SUCCESS(rv, rv);
178 :
179 14 : if (found == -1) {
180 14 : aResult.SetIsVoid(true);
181 14 : return NS_OK;
182 : }
183 :
184 0 : if (found == int32_t(mArgs.Length()) - 1) {
185 0 : return NS_ERROR_INVALID_ARG;
186 : }
187 :
188 0 : ++found;
189 :
190 : { // scope for validity of |param|, which RemoveArguments call invalidates
191 0 : const nsString& param = mArgs[found];
192 0 : if (!param.IsEmpty() && param.First() == '-') {
193 0 : return NS_ERROR_INVALID_ARG;
194 : }
195 :
196 0 : aResult = param;
197 : }
198 :
199 0 : RemoveArguments(found - 1, found);
200 :
201 0 : return NS_OK;
202 : }
203 :
204 : NS_IMETHODIMP
205 1 : nsCommandLine::GetState(uint32_t *aResult)
206 : {
207 1 : *aResult = mState;
208 1 : return NS_OK;
209 : }
210 :
211 : NS_IMETHODIMP
212 1 : nsCommandLine::GetPreventDefault(bool *aResult)
213 : {
214 1 : *aResult = mPreventDefault;
215 1 : return NS_OK;
216 : }
217 :
218 : NS_IMETHODIMP
219 0 : nsCommandLine::SetPreventDefault(bool aValue)
220 : {
221 0 : mPreventDefault = aValue;
222 0 : return NS_OK;
223 : }
224 :
225 : NS_IMETHODIMP
226 0 : nsCommandLine::GetWorkingDirectory(nsIFile* *aResult)
227 : {
228 0 : NS_ENSURE_TRUE(mWorkingDir, NS_ERROR_NOT_INITIALIZED);
229 :
230 0 : NS_ADDREF(*aResult = mWorkingDir);
231 0 : return NS_OK;
232 : }
233 :
234 : NS_IMETHODIMP
235 0 : nsCommandLine::GetWindowContext(nsIDOMWindow* *aResult)
236 : {
237 0 : NS_IF_ADDREF(*aResult = mWindowContext);
238 0 : return NS_OK;
239 : }
240 :
241 : NS_IMETHODIMP
242 0 : nsCommandLine::SetWindowContext(nsIDOMWindow* aValue)
243 : {
244 0 : mWindowContext = aValue;
245 0 : return NS_OK;
246 : }
247 :
248 : NS_IMETHODIMP
249 0 : nsCommandLine::ResolveFile(const nsAString& aArgument, nsIFile* *aResult)
250 : {
251 0 : NS_ENSURE_TRUE(mWorkingDir, NS_ERROR_NOT_INITIALIZED);
252 :
253 : // This is some seriously screwed-up code. nsIFile.appendRelativeNativePath
254 : // explicitly does not accept .. or . path parts, but that is exactly what we
255 : // need here. So we hack around it.
256 :
257 : nsresult rv;
258 :
259 : #if defined(MOZ_WIDGET_COCOA)
260 : nsCOMPtr<nsILocalFileMac> lfm (do_QueryInterface(mWorkingDir));
261 : NS_ENSURE_TRUE(lfm, NS_ERROR_NO_INTERFACE);
262 :
263 : nsCOMPtr<nsILocalFileMac> newfile (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
264 : NS_ENSURE_TRUE(newfile, NS_ERROR_OUT_OF_MEMORY);
265 :
266 : CFURLRef baseurl;
267 : rv = lfm->GetCFURL(&baseurl);
268 : NS_ENSURE_SUCCESS(rv, rv);
269 :
270 : nsAutoCString path;
271 : NS_CopyUnicodeToNative(aArgument, path);
272 :
273 : CFURLRef newurl =
274 : CFURLCreateFromFileSystemRepresentationRelativeToBase(nullptr, (const UInt8*) path.get(),
275 : path.Length(),
276 : true, baseurl);
277 :
278 : CFRelease(baseurl);
279 :
280 : rv = newfile->InitWithCFURL(newurl);
281 : CFRelease(newurl);
282 : if (NS_FAILED(rv)) return rv;
283 :
284 : newfile.forget(aResult);
285 : return NS_OK;
286 :
287 : #elif defined(XP_UNIX)
288 0 : nsCOMPtr<nsIFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
289 0 : NS_ENSURE_TRUE(lf, NS_ERROR_OUT_OF_MEMORY);
290 :
291 0 : if (aArgument.First() == '/') {
292 : // absolute path
293 0 : rv = lf->InitWithPath(aArgument);
294 0 : if (NS_FAILED(rv)) return rv;
295 :
296 0 : NS_ADDREF(*aResult = lf);
297 0 : return NS_OK;
298 : }
299 :
300 0 : nsAutoCString nativeArg;
301 0 : NS_CopyUnicodeToNative(aArgument, nativeArg);
302 :
303 0 : nsAutoCString newpath;
304 0 : mWorkingDir->GetNativePath(newpath);
305 :
306 0 : newpath.Append('/');
307 0 : newpath.Append(nativeArg);
308 :
309 0 : rv = lf->InitWithNativePath(newpath);
310 0 : if (NS_FAILED(rv)) return rv;
311 :
312 0 : rv = lf->Normalize();
313 0 : if (NS_FAILED(rv)) return rv;
314 :
315 0 : lf.forget(aResult);
316 0 : return NS_OK;
317 :
318 : #elif defined(XP_WIN32)
319 : nsCOMPtr<nsIFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
320 : NS_ENSURE_TRUE(lf, NS_ERROR_OUT_OF_MEMORY);
321 :
322 : rv = lf->InitWithPath(aArgument);
323 : if (NS_FAILED(rv)) {
324 : // If it's a relative path, the Init is *going* to fail. We use string magic and
325 : // win32 _fullpath. Note that paths of the form "\Relative\To\CurDrive" are
326 : // going to fail, and I haven't figured out a way to work around this without
327 : // the PathCombine() function, which is not available in plain win95/nt4
328 :
329 : nsAutoString fullPath;
330 : mWorkingDir->GetPath(fullPath);
331 :
332 : fullPath.Append('\\');
333 : fullPath.Append(aArgument);
334 :
335 : WCHAR pathBuf[MAX_PATH];
336 : if (!_wfullpath(pathBuf, fullPath.get(), MAX_PATH))
337 : return NS_ERROR_FAILURE;
338 :
339 : rv = lf->InitWithPath(nsDependentString(pathBuf));
340 : if (NS_FAILED(rv)) return rv;
341 : }
342 : lf.forget(aResult);
343 : return NS_OK;
344 :
345 : #else
346 : #error Need platform-specific logic here.
347 : #endif
348 : }
349 :
350 : NS_IMETHODIMP
351 1 : nsCommandLine::ResolveURI(const nsAString& aArgument, nsIURI* *aResult)
352 : {
353 : nsresult rv;
354 :
355 : // First, we try to init the argument as an absolute file path. If this doesn't
356 : // work, it is an absolute or relative URI.
357 :
358 2 : nsCOMPtr<nsIIOService> io = do_GetIOService();
359 1 : NS_ENSURE_TRUE(io, NS_ERROR_OUT_OF_MEMORY);
360 :
361 2 : nsCOMPtr<nsIURI> workingDirURI;
362 1 : if (mWorkingDir) {
363 1 : io->NewFileURI(mWorkingDir, getter_AddRefs(workingDirURI));
364 : }
365 :
366 2 : nsCOMPtr<nsIFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
367 1 : rv = lf->InitWithPath(aArgument);
368 1 : if (NS_SUCCEEDED(rv)) {
369 0 : lf->Normalize();
370 0 : nsAutoCString url;
371 : // Try to resolve the url for .url files.
372 0 : rv = resolveShortcutURL(lf, url);
373 0 : if (NS_SUCCEEDED(rv) && !url.IsEmpty()) {
374 0 : return io->NewURI(url,
375 : nullptr,
376 : workingDirURI,
377 0 : aResult);
378 : }
379 :
380 0 : return io->NewFileURI(lf, aResult);
381 : }
382 :
383 3 : return io->NewURI(NS_ConvertUTF16toUTF8(aArgument),
384 : nullptr,
385 : workingDirURI,
386 2 : aResult);
387 : }
388 :
389 : void
390 1 : nsCommandLine::appendArg(const char* arg)
391 : {
392 : #ifdef DEBUG_COMMANDLINE
393 : printf("Adding XP arg: %s\n", arg);
394 : #endif
395 :
396 2 : nsAutoString warg;
397 : #ifdef XP_WIN
398 : CopyUTF8toUTF16(nsDependentCString(arg), warg);
399 : #else
400 1 : NS_CopyNativeToUnicode(nsDependentCString(arg), warg);
401 : #endif
402 :
403 1 : mArgs.AppendElement(warg);
404 1 : }
405 :
406 : nsresult
407 0 : nsCommandLine::resolveShortcutURL(nsIFile* aFile, nsACString& outURL)
408 : {
409 0 : nsCOMPtr<nsIFileProtocolHandler> fph;
410 0 : nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fph));
411 0 : if (NS_FAILED(rv))
412 0 : return rv;
413 :
414 0 : nsCOMPtr<nsIURI> uri;
415 0 : rv = fph->ReadURLFile(aFile, getter_AddRefs(uri));
416 0 : if (NS_FAILED(rv))
417 0 : return rv;
418 :
419 0 : return uri->GetSpec(outURL);
420 : }
421 :
422 : NS_IMETHODIMP
423 1 : nsCommandLine::Init(int32_t argc, const char* const* argv, nsIFile* aWorkingDir,
424 : uint32_t aState)
425 : {
426 1 : NS_ENSURE_ARG_MAX(aState, 2);
427 :
428 : int32_t i;
429 :
430 1 : mWorkingDir = aWorkingDir;
431 :
432 : // skip argv[0], we don't want it
433 2 : for (i = 1; i < argc; ++i) {
434 1 : const char* curarg = argv[i];
435 :
436 : #ifdef DEBUG_COMMANDLINE
437 : printf("Testing native arg %i: '%s'\n", i, curarg);
438 : #endif
439 : #if defined(XP_WIN)
440 : if (*curarg == '/') {
441 : char* dup = PL_strdup(curarg);
442 : if (!dup) return NS_ERROR_OUT_OF_MEMORY;
443 :
444 : *dup = '-';
445 : char* colon = PL_strchr(dup, ':');
446 : if (colon) {
447 : *colon = '\0';
448 : appendArg(dup);
449 : appendArg(colon+1);
450 : } else {
451 : appendArg(dup);
452 : }
453 : PL_strfree(dup);
454 : continue;
455 : }
456 : #endif
457 : #ifdef XP_UNIX
458 1 : if (*curarg == '-' &&
459 0 : *(curarg+1) == '-') {
460 0 : ++curarg;
461 :
462 0 : char* dup = PL_strdup(curarg);
463 0 : if (!dup) return NS_ERROR_OUT_OF_MEMORY;
464 :
465 0 : char* eq = PL_strchr(dup, '=');
466 0 : if (eq) {
467 0 : *eq = '\0';
468 0 : appendArg(dup);
469 0 : appendArg(eq + 1);
470 : } else {
471 0 : appendArg(dup);
472 : }
473 0 : PL_strfree(dup);
474 0 : continue;
475 : }
476 : #endif
477 :
478 1 : appendArg(curarg);
479 : }
480 :
481 1 : mState = aState;
482 :
483 1 : return NS_OK;
484 : }
485 :
486 : static void
487 0 : LogConsoleMessage(const char16_t* fmt, ...)
488 : {
489 : va_list args;
490 0 : va_start(args, fmt);
491 0 : char16_t* msg = nsTextFormatter::vsmprintf(fmt, args);
492 0 : va_end(args);
493 :
494 0 : nsCOMPtr<nsIConsoleService> cs = do_GetService("@mozilla.org/consoleservice;1");
495 0 : if (cs)
496 0 : cs->LogStringMessage(msg);
497 :
498 0 : free(msg);
499 0 : }
500 :
501 : nsresult
502 1 : nsCommandLine::EnumerateHandlers(EnumerateHandlersCallback aCallback, void *aClosure)
503 : {
504 : nsresult rv;
505 :
506 : nsCOMPtr<nsICategoryManager> catman
507 2 : (do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
508 1 : NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
509 :
510 2 : nsCOMPtr<nsISimpleEnumerator> entenum;
511 2 : rv = catman->EnumerateCategory("command-line-handler",
512 2 : getter_AddRefs(entenum));
513 1 : NS_ENSURE_SUCCESS(rv, rv);
514 :
515 2 : nsCOMPtr<nsIUTF8StringEnumerator> strenum (do_QueryInterface(entenum));
516 1 : NS_ENSURE_TRUE(strenum, NS_ERROR_UNEXPECTED);
517 :
518 2 : nsAutoCString entry;
519 : bool hasMore;
520 19 : while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
521 9 : strenum->GetNext(entry);
522 :
523 18 : nsCString contractID;
524 18 : rv = catman->GetCategoryEntry("command-line-handler",
525 : entry.get(),
526 18 : getter_Copies(contractID));
527 9 : if (NS_FAILED(rv))
528 0 : continue;
529 :
530 18 : nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get()));
531 9 : if (!clh) {
532 0 : LogConsoleMessage(u"Contract ID '%s' was registered as a command line handler for entry '%s', but could not be created.",
533 0 : contractID.get(), entry.get());
534 0 : continue;
535 : }
536 :
537 9 : rv = (aCallback)(clh, this, aClosure);
538 9 : if (rv == NS_ERROR_ABORT)
539 0 : break;
540 :
541 9 : rv = NS_OK;
542 : }
543 :
544 1 : return rv;
545 : }
546 :
547 : nsresult
548 1 : nsCommandLine::EnumerateValidators(EnumerateValidatorsCallback aCallback, void *aClosure)
549 : {
550 : nsresult rv;
551 :
552 : nsCOMPtr<nsICategoryManager> catman
553 2 : (do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
554 1 : NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
555 :
556 2 : nsCOMPtr<nsISimpleEnumerator> entenum;
557 2 : rv = catman->EnumerateCategory("command-line-validator",
558 2 : getter_AddRefs(entenum));
559 1 : NS_ENSURE_SUCCESS(rv, rv);
560 :
561 2 : nsCOMPtr<nsIUTF8StringEnumerator> strenum (do_QueryInterface(entenum));
562 1 : NS_ENSURE_TRUE(strenum, NS_ERROR_UNEXPECTED);
563 :
564 2 : nsAutoCString entry;
565 : bool hasMore;
566 3 : while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
567 1 : strenum->GetNext(entry);
568 :
569 2 : nsXPIDLCString contractID;
570 2 : rv = catman->GetCategoryEntry("command-line-validator",
571 : entry.get(),
572 2 : getter_Copies(contractID));
573 1 : if (!contractID)
574 0 : continue;
575 :
576 2 : nsCOMPtr<nsICommandLineValidator> clv(do_GetService(contractID.get()));
577 1 : if (!clv)
578 0 : continue;
579 :
580 1 : rv = (aCallback)(clv, this, aClosure);
581 1 : if (rv == NS_ERROR_ABORT)
582 0 : break;
583 :
584 1 : rv = NS_OK;
585 : }
586 :
587 1 : return rv;
588 : }
589 :
590 : static nsresult
591 1 : EnumValidate(nsICommandLineValidator* aValidator, nsICommandLine* aThis, void*)
592 : {
593 1 : return aValidator->Validate(aThis);
594 : }
595 :
596 : static nsresult
597 9 : EnumRun(nsICommandLineHandler* aHandler, nsICommandLine* aThis, void*)
598 : {
599 9 : return aHandler->Handle(aThis);
600 : }
601 :
602 : NS_IMETHODIMP
603 1 : nsCommandLine::Run()
604 : {
605 : nsresult rv;
606 :
607 1 : rv = EnumerateValidators(EnumValidate, nullptr);
608 1 : if (rv == NS_ERROR_ABORT)
609 0 : return rv;
610 :
611 1 : rv = EnumerateHandlers(EnumRun, nullptr);
612 1 : if (rv == NS_ERROR_ABORT)
613 0 : return rv;
614 :
615 1 : return NS_OK;
616 : }
617 :
618 : static nsresult
619 0 : EnumHelp(nsICommandLineHandler* aHandler, nsICommandLine* aThis, void* aClosure)
620 : {
621 : nsresult rv;
622 :
623 0 : nsCString text;
624 0 : rv = aHandler->GetHelpInfo(text);
625 0 : if (NS_SUCCEEDED(rv)) {
626 0 : NS_ASSERTION(text.Length() == 0 || text.Last() == '\n',
627 : "Help text from command line handlers should end in a newline.");
628 :
629 0 : nsACString* totalText = reinterpret_cast<nsACString*>(aClosure);
630 0 : totalText->Append(text);
631 : }
632 :
633 0 : return NS_OK;
634 : }
635 :
636 : NS_IMETHODIMP
637 0 : nsCommandLine::GetHelpText(nsACString& aResult)
638 : {
639 0 : EnumerateHandlers(EnumHelp, &aResult);
640 :
641 0 : return NS_OK;
642 : }
643 :
644 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsCommandLine)
645 :
646 : NS_DEFINE_NAMED_CID(NS_COMMANDLINE_CID);
647 :
648 : static const mozilla::Module::CIDEntry kCommandLineCIDs[] = {
649 : { &kNS_COMMANDLINE_CID, false, nullptr, nsCommandLineConstructor },
650 : { nullptr }
651 : };
652 :
653 : static const mozilla::Module::ContractIDEntry kCommandLineContracts[] = {
654 : { "@mozilla.org/toolkit/command-line;1", &kNS_COMMANDLINE_CID },
655 : { nullptr }
656 : };
657 :
658 : static const mozilla::Module kCommandLineModule = {
659 : mozilla::Module::kVersion,
660 : kCommandLineCIDs,
661 : kCommandLineContracts
662 : };
663 :
664 9 : NSMODULE_DEFN(CommandLineModule) = &kCommandLineModule;
|