commands/kerninfo/kerninfo.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // kerninfo.cpp
       
     2 // 
       
     3 // Copyright (c) 2008 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <fshell/ioutils.h>
       
    14 #include <fshell/memoryaccesscmd.h>
       
    15 #include <fshell/qr3dll.h>
       
    16 #include <fshell/ltkutils.h>
       
    17 #include <fshell/descriptorutils.h>
       
    18 #ifdef FSHELL_SPCRE_SUPPORT
       
    19 #include <fshell/pcre/cregex.h>
       
    20 #endif
       
    21 
       
    22 using namespace IoUtils;
       
    23 class CRegEx;
       
    24 
       
    25 class CCmdKerninfo : public CMemoryAccessCommandBase
       
    26 	{
       
    27 public:
       
    28 	static CCommandBase* NewLC();
       
    29 	~CCmdKerninfo();
       
    30 private:
       
    31 	CCmdKerninfo();
       
    32 	TInt InfoL(TInt aIndex, TBool aUseId, TBool aVerbose);
       
    33 	void PrintInfoForL(TInt aIndex, TBool aUseId=EFalse);
       
    34 	static TBool SupportsIds(TKernelObjectType aType);
       
    35 	static void ChompBlankLines(TDes& aDes);
       
    36 
       
    37 private: // From CCommandBase.
       
    38 	virtual const TDesC& Name() const;
       
    39 	virtual void DoRunL();
       
    40 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
       
    41 	virtual void OptionsL(RCommandOptionList& aOptions);
       
    42 private:
       
    43 	TKernelObjectType iType; 
       
    44 	TInt iObjectIndex;
       
    45 	TBool iVerbose;
       
    46 	TBool iVerboseMatch;
       
    47 	HBufC* iMatch;
       
    48 	HBufC* iRegexMatch;
       
    49 
       
    50 	CKernelObjectList* iModel;
       
    51 	RBuf iTitle, iInfo;
       
    52 	LtkUtils::RLtkBuf8 iNarrowBuf;
       
    53 	CRegEx* iRegex;
       
    54 	};
       
    55 
       
    56 
       
    57 CCommandBase* CCmdKerninfo::NewLC()
       
    58 	{
       
    59 	CCmdKerninfo* self = new(ELeave) CCmdKerninfo();
       
    60 	CleanupStack::PushL(self);
       
    61 	self->BaseConstructL();
       
    62 	return self;
       
    63 	}
       
    64 
       
    65 CCmdKerninfo::~CCmdKerninfo()
       
    66 	{
       
    67 	delete iModel;
       
    68 	iTitle.Close();
       
    69 	iInfo.Close();
       
    70 	iNarrowBuf.Close();
       
    71 	delete iMatch;
       
    72 	delete iRegexMatch;
       
    73 #ifdef FSHELL_SPCRE_SUPPORT
       
    74 	delete iRegex;
       
    75 #endif
       
    76 	}
       
    77 
       
    78 CCmdKerninfo::CCmdKerninfo()
       
    79 	{
       
    80 	}
       
    81 
       
    82 const TDesC& CCmdKerninfo::Name() const
       
    83 	{
       
    84 	_LIT(KName, "kerninfo");	
       
    85 	return KName;
       
    86 	}
       
    87 
       
    88 void CCmdKerninfo::ArgumentsL(RCommandArgumentList& aArguments)
       
    89 	{
       
    90 	aArguments.AppendEnumL((TInt&)iType, _L("object-type"));
       
    91 	aArguments.AppendIntL(iObjectIndex, _L("object-index"));
       
    92 	}
       
    93 
       
    94 void CCmdKerninfo::OptionsL(RCommandOptionList& aOptions)
       
    95 	{
       
    96 	aOptions.AppendStringL(iMatch, _L("match"));
       
    97 #ifdef FSHELL_SPCRE_SUPPORT
       
    98 	aOptions.AppendStringL(iRegexMatch, _L("regex-match"));
       
    99 #endif
       
   100 	aOptions.AppendBoolL(iVerbose, _L("verbose"));
       
   101 	aOptions.AppendBoolL(iVerboseMatch, _L("verbosematch"));
       
   102 	}
       
   103 
       
   104 EXE_BOILER_PLATE(CCmdKerninfo)
       
   105 
       
   106 void CCmdKerninfo::DoRunL()
       
   107 	{
       
   108 	LoadMemoryAccessL();
       
   109 
       
   110 	iModel = CKernelObjectList::NewL(&iMemAccess);
       
   111 	
       
   112 	iModel->SetCurrentType(iType);
       
   113 	TRAPL(iModel->RefreshDataL(), _L("Couldn't get model data"));
       
   114 
       
   115 	iTitle.CreateL(256);
       
   116 	iInfo.CreateL(256);
       
   117 
       
   118 #ifdef FSHELL_SPCRE_SUPPORT
       
   119 	if (iRegexMatch)
       
   120 		{
       
   121 		if (iMatch) LeaveIfErr(KErrArgument, _L("Can't specify both --match and --regex-match, use one or the other"));
       
   122 		iRegex = CRegEx::NewL(*iRegexMatch, TRegExOptions(EPcreExtended|EPcreNewlineAny));
       
   123 		}
       
   124 #endif
       
   125 	if (iVerboseMatch) iVerbose = ETrue; // verbosematch implies verbose
       
   126 
       
   127 	const TInt n = iModel->Count();
       
   128 	TBool listAll = !iArguments.IsPresent(&iObjectIndex);
       
   129 	if (listAll)
       
   130 		{
       
   131 		for (TInt i = 0; i < n; i++)
       
   132 			{
       
   133 			PrintInfoForL(i);
       
   134 			}
       
   135 		}
       
   136 	else
       
   137 		{
       
   138 		TBool usingId = SupportsIds(iType);
       
   139 		if (!usingId && (iObjectIndex < 0 || iObjectIndex >= n))
       
   140 			{
       
   141 			LeaveIfErr(KErrArgument, _L("Bad argument %d. Number of objects in this category: %d"), iObjectIndex, n);
       
   142 			}
       
   143 		PrintInfoForL(iObjectIndex, usingId);
       
   144 		}
       
   145 	}
       
   146 
       
   147 TInt CCmdKerninfo::InfoL(TInt aIndex, TBool aUseId, TBool aVerbose)
       
   148 	{
       
   149 	TInt err = KErrNone;
       
   150 	TInt itemid = 0;
       
   151 	if (aUseId)
       
   152 		{
       
   153 		TRAP(err, iModel->GetInfoByIdL(aIndex, aVerbose, iTitle, iInfo));
       
   154 		}
       
   155 	else
       
   156 		{
       
   157 		TRAP(err, itemid = iModel->GetInfoByIndexL(aIndex, aVerbose, iTitle, iInfo));
       
   158 		}
       
   159 	LeaveIfErr(err, _L("Couldn't get info for item %d"), aIndex);
       
   160 	return itemid;
       
   161 	}
       
   162 
       
   163 void CCmdKerninfo::PrintInfoForL(TInt aIndex, TBool aUseId /* =EFalse */)
       
   164 	{
       
   165 	TInt itemid = 0;
       
   166 
       
   167 	if (iMatch || iRegexMatch)
       
   168 		{
       
   169 		// Filter out anything not matching iMatch/iRegexMatch
       
   170 		// Unless --verbosematch is specified, match on the non-verbose (but display the verbose if specified). This is because calculating the verbose can be really slow so don't do it until we know we match.
       
   171 		itemid = InfoL(aIndex, aUseId, (TBool)iVerboseMatch);
       
   172 		const TDesC& toMatchAgainst = iVerboseMatch ? iInfo : iTitle;
       
   173 
       
   174 		TBool match = EFalse;
       
   175 		if (iMatch)
       
   176 			{
       
   177 			match = (toMatchAgainst.MatchF(*iMatch) != KErrNotFound);
       
   178 			}
       
   179 #ifdef FSHELL_SPCRE_SUPPORT
       
   180 		else if (iRegexMatch)
       
   181 			{
       
   182 			iNarrowBuf.Zero();
       
   183 			iNarrowBuf.AppendL(toMatchAgainst);
       
   184 			match = iRegex->PartialMatchL(iNarrowBuf);
       
   185 			}
       
   186 #endif
       
   187 		if (!match) return;
       
   188 		}
       
   189 	
       
   190 	if ((!iMatch && !iRegexMatch) || (iVerbose && !iVerboseMatch))
       
   191 		{
       
   192 		// Need to get info for first time (if !iMatch) or re-get the verbose info (in the case of we just did a match on the non-verbose info)
       
   193 		itemid = InfoL(aIndex, aUseId, iVerbose);
       
   194 		}
       
   195 
       
   196 	TInt idxToDisplay = (SupportsIds(iType) && !aUseId) ? itemid : aIndex;
       
   197 	if (iVerbose)
       
   198 		{
       
   199 		// In verbose mode the title is always just "Process info" (etc) so no point displaying it
       
   200 		Printf(_L("%d:\n"), idxToDisplay);
       
   201 		ChompBlankLines(iInfo); // When doing a verbose listing (specially multiple ones) it's easier to remove the blank lines that the model adds for readability in the QResources dialog
       
   202 		Write(iInfo);
       
   203 		Write(_L("\n\n"));
       
   204 		}
       
   205 	else
       
   206 		{
       
   207 		Printf(_L("%d: %S\t%S\n"), idxToDisplay, &iTitle, &iInfo);
       
   208 		}
       
   209 	}
       
   210 
       
   211 TBool CCmdKerninfo::SupportsIds(TKernelObjectType aType)
       
   212 	{
       
   213 	// These types can (and should) be looked up directly by id and not by index into the list.
       
   214 	return (aType == EListThread || aType == EListProcess || aType == EListHal);
       
   215 	}
       
   216 
       
   217 void CCmdKerninfo::ChompBlankLines(TDes& aDes)
       
   218 	{
       
   219 	_LIT(KLfLf, "\n\n");
       
   220 	TInt found;
       
   221 	while ((found = aDes.Find(KLfLf)) != KErrNotFound)
       
   222 		{
       
   223 		aDes.Delete(found, 1); // Nuke one of the newlines
       
   224 		}
       
   225 	}
       
   226