зеркало из https://github.com/mozilla/pjs.git
Bug 297315 - sorts the XPCOM implementation of nsICategoryManager.enumerateCategory alphabetically r=darin a=asa
This commit is contained in:
Родитель
2a00981737
Коммит
77d8b16997
|
@ -85,8 +85,12 @@ public:
|
||||||
protected:
|
protected:
|
||||||
~nsCommandLine() { }
|
~nsCommandLine() { }
|
||||||
|
|
||||||
|
typedef nsresult (*EnumerateCallback)(nsICommandLineHandler* aHandler,
|
||||||
|
nsICommandLine* aThis,
|
||||||
|
void *aClosure);
|
||||||
|
|
||||||
void appendArg(const char* arg);
|
void appendArg(const char* arg);
|
||||||
nsresult getHandlers(nsCStringArray& handlers, nsICategoryManager* catman);
|
nsresult EnumerateHandlers(EnumerateCallback aCallback, void *aClosure);
|
||||||
|
|
||||||
nsStringArray mArgs;
|
nsStringArray mArgs;
|
||||||
PRUint32 mState;
|
PRUint32 mState;
|
||||||
|
@ -532,10 +536,14 @@ nsCommandLine::Init(PRInt32 argc, char** argv, nsIFile* aWorkingDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsCommandLine::getHandlers(nsCStringArray &handlers, nsICategoryManager* catman)
|
nsCommandLine::EnumerateHandlers(EnumerateCallback aCallback, void *aClosure)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsICategoryManager> catman
|
||||||
|
(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
||||||
|
NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> entenum;
|
nsCOMPtr<nsISimpleEnumerator> entenum;
|
||||||
rv = catman->EnumerateCategory("command-line-handler",
|
rv = catman->EnumerateCategory("command-line-handler",
|
||||||
getter_AddRefs(entenum));
|
getter_AddRefs(entenum));
|
||||||
|
@ -548,37 +556,32 @@ nsCommandLine::getHandlers(nsCStringArray &handlers, nsICategoryManager* catman)
|
||||||
PRBool hasMore;
|
PRBool hasMore;
|
||||||
while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
|
while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
|
||||||
strenum->GetNext(entry);
|
strenum->GetNext(entry);
|
||||||
handlers.AppendCString(entry);
|
|
||||||
|
nsXPIDLCString contractID;
|
||||||
|
rv = catman->GetCategoryEntry("command-line-handler",
|
||||||
|
entry.get(),
|
||||||
|
getter_Copies(contractID));
|
||||||
|
if (!contractID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get()));
|
||||||
|
if (!clh)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rv = (aCallback)(clh, this, aClosure);
|
||||||
|
if (rv = NS_ERROR_ABORT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
rv = NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers.Sort();
|
return rv;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RunClosure
|
static nsresult
|
||||||
|
EnumRun(nsICommandLineHandler* aHandler, nsICommandLine* aThis, void*)
|
||||||
{
|
{
|
||||||
nsICommandLine* cl;
|
return aHandler->Handle(aThis);
|
||||||
nsICategoryManager* catman;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
EnumRun(nsCString& aEntry, void* aData)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
RunClosure* closure = NS_STATIC_CAST(RunClosure*, aData);
|
|
||||||
|
|
||||||
nsXPIDLCString value;
|
|
||||||
rv = closure->catman->GetCategoryEntry("command-line-handler",
|
|
||||||
aEntry.get(),
|
|
||||||
getter_Copies(value));
|
|
||||||
NS_ENSURE_SUCCESS(rv, PR_TRUE);
|
|
||||||
|
|
||||||
nsCOMPtr<nsICommandLineHandler> clh (do_GetService(value));
|
|
||||||
NS_ENSURE_TRUE(clh, PR_TRUE);
|
|
||||||
|
|
||||||
rv = clh->Handle(closure->cl);
|
|
||||||
return rv != NS_ERROR_ABORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -586,74 +589,36 @@ nsCommandLine::Run()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsICategoryManager> catman
|
rv = EnumerateHandlers(EnumRun, nsnull);
|
||||||
(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
if (rv == NS_ERROR_ABORT)
|
||||||
NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
|
return rv;
|
||||||
|
|
||||||
nsCStringArray handlers;
|
|
||||||
rv = getHandlers(handlers, catman);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
RunClosure closure = { this, catman };
|
|
||||||
|
|
||||||
if (!handlers.EnumerateForwards(&EnumRun, &closure))
|
|
||||||
return NS_ERROR_ABORT;
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HelpClosure
|
|
||||||
{
|
|
||||||
HelpClosure(nsACString& aText, nsICategoryManager* aCatman) :
|
|
||||||
text(aText), catman(aCatman) { }
|
|
||||||
|
|
||||||
nsACString& text;
|
|
||||||
nsICategoryManager* catman;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
EnumHelp(nsCString& aEntry, void* aData)
|
EnumHelp(nsICommandLineHandler* aHandler, nsICommandLine* aThis, void* aClosure)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
HelpClosure* closure = NS_STATIC_CAST(HelpClosure*, aData);
|
|
||||||
|
|
||||||
nsXPIDLCString value;
|
|
||||||
rv = closure->catman->GetCategoryEntry("command-line-handler",
|
|
||||||
aEntry.get(),
|
|
||||||
getter_Copies(value));
|
|
||||||
NS_ENSURE_SUCCESS(rv, PR_TRUE);
|
|
||||||
|
|
||||||
nsCOMPtr<nsICommandLineHandler> clh (do_GetService(value));
|
|
||||||
NS_ENSURE_TRUE(clh, PR_TRUE);
|
|
||||||
|
|
||||||
nsCString text;
|
nsCString text;
|
||||||
rv = clh->GetHelpInfo(text);
|
rv = aHandler->GetHelpInfo(text);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
NS_ASSERTION(text.Length() == 0 || text.Last() == '\n',
|
NS_ASSERTION(text.Length() == 0 || text.Last() == '\n',
|
||||||
"Help text from command line handlers should end in a newline.");
|
"Help text from command line handlers should end in a newline.");
|
||||||
closure->text.Append(text);
|
|
||||||
|
nsACString* totalText = NS_REINTERPRET_CAST(nsACString*, aClosure);
|
||||||
|
totalText->Append(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PR_TRUE;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCommandLine::GetHelpText(nsACString& aResult)
|
nsCommandLine::GetHelpText(nsACString& aResult)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
EnumerateHandlers(EnumRun, &aResult);
|
||||||
|
|
||||||
nsCOMPtr<nsICategoryManager> catman
|
|
||||||
(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
|
||||||
NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
|
|
||||||
|
|
||||||
nsCStringArray handlers;
|
|
||||||
rv = getHandlers(handlers, catman);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
HelpClosure closure (aResult, catman);
|
|
||||||
|
|
||||||
handlers.EnumerateForwards(EnumHelp, &closure);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,9 @@
|
||||||
* XPCOM Category Manager Contract ID
|
* XPCOM Category Manager Contract ID
|
||||||
* The contract supports the nsICategoryManager interface. The
|
* The contract supports the nsICategoryManager interface. The
|
||||||
* category manager is a singleton.
|
* category manager is a singleton.
|
||||||
|
* The "enumerateCategory" method of nsICategoryManager will return an object
|
||||||
|
* that implements nsIUTF8StringEnumerator. In addition, the enumerator will
|
||||||
|
* return the entries in sorted order (sorted by byte comparison).
|
||||||
*/
|
*/
|
||||||
#define NS_CATEGORYMANAGER_CONTRACTID "@mozilla.org/categorymanager;1"
|
#define NS_CATEGORYMANAGER_CONTRACTID "@mozilla.org/categorymanager;1"
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
|
#include "nsQuickSort.h"
|
||||||
#include "nsEnumeratorUtils.h"
|
#include "nsEnumeratorUtils.h"
|
||||||
|
|
||||||
class nsIComponentLoaderManager;
|
class nsIComponentLoaderManager;
|
||||||
|
@ -90,6 +91,9 @@ public:
|
||||||
NS_DECL_NSIUTF8STRINGENUMERATOR
|
NS_DECL_NSIUTF8STRINGENUMERATOR
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Callback function for NS_QuickSort to sort mArray
|
||||||
|
static int SortCallback(const void *, const void *, void *);
|
||||||
|
|
||||||
BaseStringEnumerator()
|
BaseStringEnumerator()
|
||||||
: mArray(nsnull),
|
: mArray(nsnull),
|
||||||
mCount(0),
|
mCount(0),
|
||||||
|
@ -105,6 +109,8 @@ protected:
|
||||||
delete[] mArray;
|
delete[] mArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sort();
|
||||||
|
|
||||||
const char** mArray;
|
const char** mArray;
|
||||||
PRUint32 mCount;
|
PRUint32 mCount;
|
||||||
PRUint32 mSimpleCurItem;
|
PRUint32 mSimpleCurItem;
|
||||||
|
@ -155,6 +161,21 @@ BaseStringEnumerator::GetNext(nsACString& _retval)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
BaseStringEnumerator::SortCallback(const void *e1, const void *e2,
|
||||||
|
void * /*unused*/)
|
||||||
|
{
|
||||||
|
char const *const *s1 = NS_REINTERPRET_CAST(char const *const *, e1);
|
||||||
|
char const *const *s2 = NS_REINTERPRET_CAST(char const *const *, e2);
|
||||||
|
|
||||||
|
return strcmp(*s1, *s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseStringEnumerator::Sort()
|
||||||
|
{
|
||||||
|
NS_QuickSort(mArray, mCount, sizeof(mArray[0]), SortCallback, nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// EntryEnumerator is the wrapper that allows nsICategoryManager::EnumerateCategory
|
// EntryEnumerator is the wrapper that allows nsICategoryManager::EnumerateCategory
|
||||||
|
@ -195,6 +216,8 @@ EntryEnumerator::Create(nsTHashtable<CategoryLeaf>& aTable)
|
||||||
|
|
||||||
aTable.EnumerateEntries(enumfunc_createenumerator, enumObj);
|
aTable.EnumerateEntries(enumfunc_createenumerator, enumObj);
|
||||||
|
|
||||||
|
enumObj->Sort();
|
||||||
|
|
||||||
return enumObj;
|
return enumObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,11 +80,27 @@ NS_IMETHODIMP EmptyEnumeratorImpl::HasMoreElements(PRBool* aResult)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP EmptyEnumeratorImpl::HasMore(PRBool* aResult)
|
||||||
|
{
|
||||||
|
*aResult = PR_FALSE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsISupports** aResult)
|
NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsISupports** aResult)
|
||||||
{
|
{
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsACString& aResult)
|
||||||
|
{
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsAString& aResult)
|
||||||
|
{
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
static EmptyEnumeratorImpl* gEmptyEnumerator = nsnull;
|
static EmptyEnumeratorImpl* gEmptyEnumerator = nsnull;
|
||||||
|
|
||||||
extern "C" NS_COM nsresult
|
extern "C" NS_COM nsresult
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is mozilla.org code.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Netscape Communications Corporation.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* L. David Baron <dbaron@dbaron.org>
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
||||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
An empty enumerator.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nsIEnumerator.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class EmptyEnumeratorImpl : public nsISimpleEnumerator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EmptyEnumeratorImpl(void);
|
|
||||||
|
|
||||||
// nsISupports interface
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED // not really inherited, but no mRefCnt
|
|
||||||
|
|
||||||
// nsISimpleEnumerator
|
|
||||||
NS_DECL_NSISIMPLEENUMERATOR
|
|
||||||
|
|
||||||
static void Shutdown();
|
|
||||||
|
|
||||||
private:
|
|
||||||
~EmptyEnumeratorImpl(void);
|
|
||||||
};
|
|
Загрузка…
Ссылка в новой задаче