LCOV - app.info - toolkit/components/commandlines/nsCommandLine.cpp

LCOV - code coverage report
| Current view: | directory - toolkit/components/commandlines - nsCommandLine.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 231 | 13 | 5.6 %
| Date: | 2012-04-21 | Functions: | 32 | 9 | 28.1 %

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

Generated by: LCOV version 1.7