Page MenuHome GnuPG

No OneTemporary

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 7839bc6..07dd332 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,703 +1,705 @@
<?php
/**
* This file is automatically generated. Use 'arc liberate' to rebuild it.
* @generated
* @phutil-library-version 2
*/
phutil_register_library_map(array(
'__library_version__' => 2,
'class' =>
array(
'AASTNode' => 'parser/aast/api/AASTNode.php',
'AASTNodeList' => 'parser/aast/api/AASTNodeList.php',
'AASTToken' => 'parser/aast/api/AASTToken.php',
'AASTTree' => 'parser/aast/api/AASTTree.php',
'AbstractDirectedGraph' => 'utils/AbstractDirectedGraph.php',
'AbstractDirectedGraphTestCase' => 'utils/__tests__/AbstractDirectedGraphTestCase.php',
'AphrontDatabaseConnection' => 'aphront/storage/connection/AphrontDatabaseConnection.php',
'AphrontDatabaseTransactionState' => 'aphront/storage/connection/AphrontDatabaseTransactionState.php',
'AphrontIsolatedDatabaseConnection' => 'aphront/storage/connection/AphrontIsolatedDatabaseConnection.php',
'AphrontMySQLDatabaseConnection' => 'aphront/storage/connection/mysql/AphrontMySQLDatabaseConnection.php',
'AphrontMySQLDatabaseConnectionBase' => 'aphront/storage/connection/mysql/AphrontMySQLDatabaseConnectionBase.php',
'AphrontMySQLiDatabaseConnection' => 'aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php',
'AphrontQueryAccessDeniedException' => 'aphront/storage/exception/AphrontQueryAccessDeniedException.php',
'AphrontQueryCharacterSetException' => 'aphront/storage/exception/AphrontQueryCharacterSetException.php',
'AphrontQueryConnectionException' => 'aphront/storage/exception/AphrontQueryConnectionException.php',
'AphrontQueryConnectionLostException' => 'aphront/storage/exception/AphrontQueryConnectionLostException.php',
'AphrontQueryCountException' => 'aphront/storage/exception/AphrontQueryCountException.php',
'AphrontQueryDeadlockException' => 'aphront/storage/exception/AphrontQueryDeadlockException.php',
'AphrontQueryDuplicateKeyException' => 'aphront/storage/exception/AphrontQueryDuplicateKeyException.php',
'AphrontQueryException' => 'aphront/storage/exception/AphrontQueryException.php',
'AphrontQueryNotSupportedException' => 'aphront/storage/exception/AphrontQueryNotSupportedException.php',
'AphrontQueryObjectMissingException' => 'aphront/storage/exception/AphrontQueryObjectMissingException.php',
'AphrontQueryParameterException' => 'aphront/storage/exception/AphrontQueryParameterException.php',
'AphrontQueryRecoverableException' => 'aphront/storage/exception/AphrontQueryRecoverableException.php',
'AphrontQuerySchemaException' => 'aphront/storage/exception/AphrontQuerySchemaException.php',
'AphrontScopedUnguardedWriteCapability' => 'aphront/writeguard/AphrontScopedUnguardedWriteCapability.php',
'AphrontWriteGuard' => 'aphront/writeguard/AphrontWriteGuard.php',
'AphrontWriteGuardExitEventListener' => 'aphront/writeguard/event/AphrontWriteGuardExitEventListener.php',
'BaseHTTPFuture' => 'future/http/BaseHTTPFuture.php',
'CommandException' => 'future/exec/CommandException.php',
'ConduitClient' => 'conduit/ConduitClient.php',
'ConduitClientException' => 'conduit/ConduitClientException.php',
'ConduitFuture' => 'conduit/ConduitFuture.php',
'ExecFuture' => 'future/exec/ExecFuture.php',
'ExecFutureTestCase' => 'future/exec/__tests__/ExecFutureTestCase.php',
'ExecPassthruTestCase' => 'future/exec/__tests__/ExecPassthruTestCase.php',
'FileFinder' => 'filesystem/FileFinder.php',
'FileFinderTestCase' => 'filesystem/__tests__/FileFinderTestCase.php',
'FileList' => 'filesystem/FileList.php',
'Filesystem' => 'filesystem/Filesystem.php',
'FilesystemException' => 'filesystem/FilesystemException.php',
'FilesystemTestCase' => 'filesystem/__tests__/FilesystemTestCase.php',
'Future' => 'future/Future.php',
'FutureIterator' => 'future/FutureIterator.php',
'FutureIteratorTestCase' => 'future/__tests__/FutureIteratorTestCase.php',
'FutureProxy' => 'future/FutureProxy.php',
'HTTPFuture' => 'future/http/HTTPFuture.php',
'HTTPFutureResponseStatus' => 'future/http/status/HTTPFutureResponseStatus.php',
'HTTPFutureResponseStatusCURL' => 'future/http/status/HTTPFutureResponseStatusCURL.php',
'HTTPFutureResponseStatusHTTP' => 'future/http/status/HTTPFutureResponseStatusHTTP.php',
'HTTPFutureResponseStatusParse' => 'future/http/status/HTTPFutureResponseStatusParse.php',
'HTTPFutureResponseStatusTransport' => 'future/http/status/HTTPFutureResponseStatusTransport.php',
'HTTPSFuture' => 'future/http/HTTPSFuture.php',
'ImmediateFuture' => 'future/ImmediateFuture.php',
'LinesOfALarge' => 'filesystem/linesofalarge/LinesOfALarge.php',
'LinesOfALargeExecFuture' => 'filesystem/linesofalarge/LinesOfALargeExecFuture.php',
'LinesOfALargeExecFutureTestCase' => 'filesystem/linesofalarge/__tests__/LinesOfALargeExecFutureTestCase.php',
'LinesOfALargeFile' => 'filesystem/linesofalarge/LinesOfALargeFile.php',
'LinesOfALargeFileTestCase' => 'filesystem/linesofalarge/__tests__/LinesOfALargeFileTestCase.php',
'MFilterTestHelper' => 'utils/__tests__/MFilterTestHelper.php',
'PHPASTParserTestCase' => 'parser/xhpast/__tests__/PHPASTParserTestCase.php',
'PhageAgentBootloader' => 'phage/bootloader/PhageAgentBootloader.php',
'PhageAgentTestCase' => 'phage/__tests__/PhageAgentTestCase.php',
'PhagePHPAgent' => 'phage/agent/PhagePHPAgent.php',
'PhagePHPAgentBootloader' => 'phage/bootloader/PhagePHPAgentBootloader.php',
'Phobject' => 'object/Phobject.php',
'PhutilAWSEC2Future' => 'future/aws/PhutilAWSEC2Future.php',
'PhutilAWSException' => 'future/aws/PhutilAWSException.php',
'PhutilAWSFuture' => 'future/aws/PhutilAWSFuture.php',
'PhutilAggregateException' => 'error/PhutilAggregateException.php',
'PhutilArgumentParser' => 'parser/argument/PhutilArgumentParser.php',
'PhutilArgumentParserException' => 'parser/argument/exception/PhutilArgumentParserException.php',
'PhutilArgumentParserTestCase' => 'parser/argument/__tests__/PhutilArgumentParserTestCase.php',
'PhutilArgumentSpecification' => 'parser/argument/PhutilArgumentSpecification.php',
'PhutilArgumentSpecificationException' => 'parser/argument/exception/PhutilArgumentSpecificationException.php',
'PhutilArgumentSpecificationTestCase' => 'parser/argument/__tests__/PhutilArgumentSpecificationTestCase.php',
'PhutilArgumentUsageException' => 'parser/argument/exception/PhutilArgumentUsageException.php',
'PhutilArgumentWorkflow' => 'parser/argument/workflow/PhutilArgumentWorkflow.php',
'PhutilArray' => 'utils/PhutilArray.php',
'PhutilArrayTestCase' => 'utils/__tests__/PhutilArrayTestCase.php',
'PhutilArrayWithDefaultValue' => 'utils/PhutilArrayWithDefaultValue.php',
'PhutilAsanaFuture' => 'future/asana/PhutilAsanaFuture.php',
'PhutilAuthAdapter' => 'auth/PhutilAuthAdapter.php',
'PhutilAuthAdapterEmpty' => 'auth/PhutilAuthAdapterEmpty.php',
'PhutilAuthAdapterLDAP' => 'auth/PhutilAuthAdapterLDAP.php',
'PhutilAuthAdapterOAuth' => 'auth/PhutilAuthAdapterOAuth.php',
'PhutilAuthAdapterOAuth1' => 'auth/PhutilAuthAdapterOAuth1.php',
'PhutilAuthAdapterOAuthAmazon' => 'auth/PhutilAuthAdapterOAuthAmazon.php',
'PhutilAuthAdapterOAuthAsana' => 'auth/PhutilAuthAdapterOAuthAsana.php',
'PhutilAuthAdapterOAuthBitbucket' => 'auth/PhutilAuthAdapterOAuthBitbucket.php',
'PhutilAuthAdapterOAuthDisqus' => 'auth/PhutilAuthAdapterOAuthDisqus.php',
'PhutilAuthAdapterOAuthFacebook' => 'auth/PhutilAuthAdapterOAuthFacebook.php',
'PhutilAuthAdapterOAuthGitHub' => 'auth/PhutilAuthAdapterOAuthGitHub.php',
'PhutilAuthAdapterOAuthGoogle' => 'auth/PhutilAuthAdapterOAuthGoogle.php',
'PhutilAuthAdapterOAuthJIRA' => 'auth/PhutilAuthAdapterOAuthJIRA.php',
'PhutilAuthAdapterOAuthTwitch' => 'auth/PhutilAuthAdapterOAuthTwitch.php',
'PhutilAuthAdapterOAuthTwitter' => 'auth/PhutilAuthAdapterOAuthTwitter.php',
'PhutilAuthAdapterOAuthWordPress' => 'auth/PhutilAuthAdapterOAuthWordPress.php',
'PhutilAuthAdapterPersona' => 'auth/PhutilAuthAdapterPersona.php',
'PhutilAuthConfigurationException' => 'auth/exception/PhutilAuthConfigurationException.php',
'PhutilAuthCredentialException' => 'auth/exception/PhutilAuthCredentialException.php',
'PhutilAuthException' => 'auth/exception/PhutilAuthException.php',
'PhutilAuthUserAbortedException' => 'auth/exception/PhutilAuthUserAbortedException.php',
'PhutilBallOfPHP' => 'phage/util/PhutilBallOfPHP.php',
'PhutilBufferedIterator' => 'utils/PhutilBufferedIterator.php',
'PhutilBufferedIteratorExample' => 'utils/PhutilBufferedIteratorExample.php',
'PhutilBufferedIteratorTestCase' => 'utils/__tests__/PhutilBufferedIteratorTestCase.php',
'PhutilBugtraqParser' => 'parser/PhutilBugtraqParser.php',
'PhutilBugtraqParserTestCase' => 'parser/__tests__/PhutilBugtraqParserTestCase.php',
'PhutilCLikeCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilCLikeCodeSnippetContextFreeGrammar.php',
'PhutilCallbackFilterIterator' => 'utils/PhutilCallbackFilterIterator.php',
'PhutilChannel' => 'channel/PhutilChannel.php',
'PhutilChannelChannel' => 'channel/PhutilChannelChannel.php',
'PhutilChannelTestCase' => 'channel/__tests__/PhutilChannelTestCase.php',
'PhutilChunkedIterator' => 'utils/PhutilChunkedIterator.php',
'PhutilChunkedIteratorTestCase' => 'utils/__tests__/PhutilChunkedIteratorTestCase.php',
'PhutilCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilCodeSnippetContextFreeGrammar.php',
'PhutilCommandString' => 'xsprintf/PhutilCommandString.php',
'PhutilConsole' => 'console/PhutilConsole.php',
'PhutilConsoleFormatter' => 'console/PhutilConsoleFormatter.php',
'PhutilConsoleMessage' => 'console/PhutilConsoleMessage.php',
'PhutilConsoleProgressBar' => 'console/PhutilConsoleProgressBar.php',
'PhutilConsoleServer' => 'console/PhutilConsoleServer.php',
'PhutilConsoleServerChannel' => 'console/PhutilConsoleServerChannel.php',
'PhutilConsoleStdinNotInteractiveException' => 'console/PhutilConsoleStdinNotInteractiveException.php',
'PhutilConsoleSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilConsoleSyntaxHighlighter.php',
'PhutilConsoleTable' => 'console/PhutilConsoleTable.php',
'PhutilConsoleWrapTestCase' => 'console/__tests__/PhutilConsoleWrapTestCase.php',
'PhutilContextFreeGrammar' => 'grammar/PhutilContextFreeGrammar.php',
+ 'PhutilCsprintfTestCase' => 'xsprintf/__tests__/PhutilCsprintfTestCase.php',
'PhutilDaemon' => 'daemon/PhutilDaemon.php',
'PhutilDaemonOverseer' => 'daemon/PhutilDaemonOverseer.php',
'PhutilDefaultSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilDefaultSyntaxHighlighter.php',
'PhutilDefaultSyntaxHighlighterEngine' => 'markup/syntax/engine/PhutilDefaultSyntaxHighlighterEngine.php',
'PhutilDefaultSyntaxHighlighterEnginePygmentsFuture' => 'markup/syntax/highlighter/pygments/PhutilDefaultSyntaxHighlighterEnginePygmentsFuture.php',
'PhutilDefaultSyntaxHighlighterEngineTestCase' => 'markup/syntax/engine/__tests__/PhutilDefaultSyntaxHighlighterEngineTestCase.php',
'PhutilDeferredLog' => 'filesystem/PhutilDeferredLog.php',
'PhutilDeferredLogTestCase' => 'filesystem/__tests__/PhutilDeferredLogTestCase.php',
'PhutilDirectedScalarGraph' => 'utils/PhutilDirectedScalarGraph.php',
'PhutilDirectoryFixture' => 'filesystem/PhutilDirectoryFixture.php',
'PhutilDivinerSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilDivinerSyntaxHighlighter.php',
'PhutilDocblockParser' => 'parser/PhutilDocblockParser.php',
'PhutilDocblockParserTestCase' => 'parser/__tests__/PhutilDocblockParserTestCase.php',
'PhutilEditDistanceMatrix' => 'utils/PhutilEditDistanceMatrix.php',
'PhutilEditDistanceMatrixTestCase' => 'utils/__tests__/PhutilEditDistanceMatrixTestCase.php',
'PhutilEmailAddress' => 'parser/PhutilEmailAddress.php',
'PhutilEmailAddressTestCase' => 'parser/__tests__/PhutilEmailAddressTestCase.php',
'PhutilErrorHandler' => 'error/PhutilErrorHandler.php',
'PhutilErrorHandlerTestCase' => 'error/__tests__/PhutilErrorHandlerTestCase.php',
'PhutilErrorTrap' => 'error/PhutilErrorTrap.php',
'PhutilEvent' => 'events/PhutilEvent.php',
'PhutilEventConstants' => 'events/constant/PhutilEventConstants.php',
'PhutilEventEngine' => 'events/PhutilEventEngine.php',
'PhutilEventListener' => 'events/PhutilEventListener.php',
'PhutilEventType' => 'events/constant/PhutilEventType.php',
'PhutilExcessiveServiceCallsDaemon' => 'daemon/torture/PhutilExcessiveServiceCallsDaemon.php',
'PhutilExecChannel' => 'channel/PhutilExecChannel.php',
'PhutilExecPassthru' => 'future/exec/PhutilExecPassthru.php',
'PhutilExtensionsTestCase' => 'moduleutils/__tests__/PhutilExtensionsTestCase.php',
'PhutilFatalDaemon' => 'daemon/torture/PhutilFatalDaemon.php',
'PhutilFileLock' => 'filesystem/PhutilFileLock.php',
'PhutilFileLockTestCase' => 'filesystem/__tests__/PhutilFileLockTestCase.php',
'PhutilFileTree' => 'filesystem/PhutilFileTree.php',
'PhutilGitURI' => 'parser/PhutilGitURI.php',
'PhutilGitURITestCase' => 'parser/__tests__/PhutilGitURITestCase.php',
'PhutilHangForeverDaemon' => 'daemon/torture/PhutilHangForeverDaemon.php',
'PhutilHelpArgumentWorkflow' => 'parser/argument/workflow/PhutilHelpArgumentWorkflow.php',
+ 'PhutilHgsprintfTestCase' => 'xsprintf/__tests__/PhutilHgsprintfTestCase.php',
'PhutilInfrastructureTestCase' => '__tests__/PhutilInfrastructureTestCase.php',
'PhutilInteractiveEditor' => 'console/PhutilInteractiveEditor.php',
'PhutilInvisibleSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilInvisibleSyntaxHighlighter.php',
'PhutilJSON' => 'parser/PhutilJSON.php',
'PhutilJSONParser' => 'parser/PhutilJSONParser.php',
'PhutilJSONParserException' => 'parser/exception/PhutilJSONParserException.php',
'PhutilJSONParserTestCase' => 'parser/__tests__/PhutilJSONParserTestCase.php',
'PhutilJSONProtocolChannel' => 'channel/PhutilJSONProtocolChannel.php',
'PhutilJSONProtocolChannelTestCase' => 'channel/__tests__/PhutilJSONProtocolChannelTestCase.php',
'PhutilJSONTestCase' => 'parser/__tests__/PhutilJSONTestCase.php',
'PhutilJavaCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilJavaCodeSnippetContextFreeGrammar.php',
'PhutilKeyValueCache' => 'cache/PhutilKeyValueCache.php',
'PhutilKeyValueCacheAPC' => 'cache/PhutilKeyValueCacheAPC.php',
'PhutilKeyValueCacheDirectory' => 'cache/PhutilKeyValueCacheDirectory.php',
'PhutilKeyValueCacheInRequest' => 'cache/PhutilKeyValueCacheInRequest.php',
'PhutilKeyValueCacheMemcache' => 'cache/PhutilKeyValueCacheMemcache.php',
'PhutilKeyValueCacheNamespace' => 'cache/PhutilKeyValueCacheNamespace.php',
'PhutilKeyValueCacheOnDisk' => 'cache/PhutilKeyValueCacheOnDisk.php',
'PhutilKeyValueCacheProfiler' => 'cache/PhutilKeyValueCacheProfiler.php',
'PhutilKeyValueCacheProxy' => 'cache/PhutilKeyValueCacheProxy.php',
'PhutilKeyValueCacheStack' => 'cache/PhutilKeyValueCacheStack.php',
'PhutilKeyValueCacheTestCase' => 'cache/__tests__/PhutilKeyValueCacheTestCase.php',
'PhutilLanguageGuesser' => 'parser/PhutilLanguageGuesser.php',
'PhutilLanguageGuesserTestCase' => 'parser/__tests__/PhutilLanguageGuesserTestCase.php',
'PhutilLexer' => 'lexer/PhutilLexer.php',
'PhutilLexerSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilLexerSyntaxHighlighter.php',
'PhutilLipsumContextFreeGrammar' => 'grammar/PhutilLipsumContextFreeGrammar.php',
'PhutilLock' => 'filesystem/PhutilLock.php',
'PhutilLockException' => 'filesystem/PhutilLockException.php',
'PhutilLogfileChannel' => 'channel/PhutilLogfileChannel.php',
'PhutilLunarPhase' => 'utils/PhutilLunarPhase.php',
'PhutilLunarPhaseTestCase' => 'utils/__tests__/PhutilLunarPhaseTestCase.php',
'PhutilMarkupEngine' => 'markup/PhutilMarkupEngine.php',
'PhutilMarkupTestCase' => 'markup/__tests__/PhutilMarkupTestCase.php',
'PhutilMetricsChannel' => 'channel/PhutilMetricsChannel.php',
'PhutilMissingSymbolException' => 'symbols/exception/PhutilMissingSymbolException.php',
'PhutilNiceDaemon' => 'daemon/torture/PhutilNiceDaemon.php',
'PhutilNumber' => 'internationalization/PhutilNumber.php',
'PhutilOAuth1Future' => 'future/oauth/PhutilOAuth1Future.php',
'PhutilOAuth1FutureTestCase' => 'future/oauth/__tests__/PhutilOAuth1FutureTestCase.php',
'PhutilOpaqueEnvelope' => 'error/PhutilOpaqueEnvelope.php',
'PhutilOpaqueEnvelopeKey' => 'error/PhutilOpaqueEnvelopeKey.php',
'PhutilOpaqueEnvelopeTestCase' => 'error/__tests__/PhutilOpaqueEnvelopeTestCase.php',
'PhutilPHPCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilPHPCodeSnippetContextFreeGrammar.php',
'PhutilPHPFragmentLexer' => 'lexer/PhutilPHPFragmentLexer.php',
'PhutilPHPFragmentLexerHighlighterTestCase' => 'markup/syntax/highlighter/__tests__/PhutilPHPFragmentLexerHighlighterTestCase.php',
'PhutilPHPFragmentLexerTestCase' => 'lexer/__tests__/PhutilPHPFragmentLexerTestCase.php',
'PhutilPHPObjectProtocolChannel' => 'channel/PhutilPHPObjectProtocolChannel.php',
'PhutilPHPObjectProtocolChannelTestCase' => 'channel/__tests__/PhutilPHPObjectProtocolChannelTestCase.php',
'PhutilPHTTestCase' => 'internationalization/__tests__/PhutilPHTTestCase.php',
'PhutilParserGenerator' => 'parser/PhutilParserGenerator.php',
'PhutilParserGeneratorException' => 'parser/generator/exception/PhutilParserGeneratorException.php',
'PhutilParserGeneratorInvalidRuleException' => 'parser/generator/exception/PhutilParserGeneratorInvalidRuleException.php',
'PhutilParserGeneratorIrreducibleRuleException' => 'parser/generator/exception/PhutilParserGeneratorIrreducibleRuleException.php',
'PhutilParserGeneratorTestCase' => 'parser/__tests__/PhutilParserGeneratorTestCase.php',
'PhutilParserGeneratorUnknownSymbolException' => 'parser/generator/exception/PhutilParserGeneratorUnknownSymbolException.php',
'PhutilParserGeneratorUnreachableRuleException' => 'parser/generator/exception/PhutilParserGeneratorUnreachableRuleException.php',
'PhutilParserGeneratorUnreachableTerminalException' => 'parser/generator/exception/PhutilParserGeneratorUnreachableTerminalException.php',
'PhutilPayPalAPIFuture' => 'future/paypal/PhutilPayPalAPIFuture.php',
'PhutilPerson' => 'internationalization/PhutilPerson.php',
'PhutilPersonTest' => 'internationalization/__tests__/PhutilPersonTest.php',
'PhutilPhobjectTestCase' => 'object/__tests__/PhutilPhobjectTestCase.php',
'PhutilProcessGroupDaemon' => 'daemon/torture/PhutilProcessGroupDaemon.php',
'PhutilProtocolChannel' => 'channel/PhutilProtocolChannel.php',
'PhutilProxyException' => 'error/PhutilProxyException.php',
'PhutilPygmentsSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilPygmentsSyntaxHighlighter.php',
'PhutilPythonFragmentLexer' => 'lexer/PhutilPythonFragmentLexer.php',
'PhutilQsprintfInterface' => 'xsprintf/PhutilQsprintfInterface.php',
'PhutilQueryStringParser' => 'parser/PhutilQueryStringParser.php',
'PhutilQueryStringParserTestCase' => 'parser/__tests__/PhutilQueryStringParserTestCase.php',
'PhutilRainbowSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilRainbowSyntaxHighlighter.php',
'PhutilReadableSerializer' => 'readableserializer/PhutilReadableSerializer.php',
'PhutilReadableSerializerTestCase' => 'readableserializer/__tests__/PhutilReadableSerializerTestCase.php',
'PhutilRealnameContextFreeGrammar' => 'grammar/PhutilRealnameContextFreeGrammar.php',
'PhutilRemarkupBlockInterpreter' => 'markup/engine/remarkup/blockrule/PhutilRemarkupBlockInterpreter.php',
'PhutilRemarkupBlockStorage' => 'markup/engine/remarkup/PhutilRemarkupBlockStorage.php',
'PhutilRemarkupEngine' => 'markup/engine/PhutilRemarkupEngine.php',
'PhutilRemarkupEngineBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineBlockRule.php',
'PhutilRemarkupEngineRemarkupCodeBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupCodeBlockRule.php',
'PhutilRemarkupEngineRemarkupDefaultBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupDefaultBlockRule.php',
'PhutilRemarkupEngineRemarkupHeaderBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupHeaderBlockRule.php',
'PhutilRemarkupEngineRemarkupHorizontalRuleBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupHorizontalRuleBlockRule.php',
'PhutilRemarkupEngineRemarkupInlineBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupInlineBlockRule.php',
'PhutilRemarkupEngineRemarkupInterpreterRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupInterpreterRule.php',
'PhutilRemarkupEngineRemarkupListBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupListBlockRule.php',
'PhutilRemarkupEngineRemarkupLiteralBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupLiteralBlockRule.php',
'PhutilRemarkupEngineRemarkupNoteBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupNoteBlockRule.php',
'PhutilRemarkupEngineRemarkupQuotesBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupQuotesBlockRule.php',
'PhutilRemarkupEngineRemarkupReplyBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupReplyBlockRule.php',
'PhutilRemarkupEngineRemarkupSimpleTableBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupSimpleTableBlockRule.php',
'PhutilRemarkupEngineRemarkupTableBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupTableBlockRule.php',
'PhutilRemarkupEngineRemarkupTestInterpreterRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupTestInterpreterRule.php',
'PhutilRemarkupEngineTestCase' => 'markup/engine/__tests__/PhutilRemarkupEngineTestCase.php',
'PhutilRemarkupRule' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRule.php',
'PhutilRemarkupRuleBold' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleBold.php',
'PhutilRemarkupRuleDel' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleDel.php',
'PhutilRemarkupRuleDocumentLink' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleDocumentLink.php',
'PhutilRemarkupRuleEscapeRemarkup' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleEscapeRemarkup.php',
'PhutilRemarkupRuleHyperlink' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleHyperlink.php',
'PhutilRemarkupRuleItalic' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleItalic.php',
'PhutilRemarkupRuleLinebreaks' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleLinebreaks.php',
'PhutilRemarkupRuleMonospace' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleMonospace.php',
'PhutilRemarkupRuleUnderline' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleUnderline.php',
'PhutilRope' => 'utils/PhutilRope.php',
'PhutilRopeTestCase' => 'utils/__tests__/PhutilRopeTestCase.php',
'PhutilSafeHTML' => 'markup/PhutilSafeHTML.php',
'PhutilSafeHTMLProducerInterface' => 'markup/PhutilSafeHTMLProducerInterface.php',
'PhutilSafeHTMLTestCase' => 'markup/__tests__/PhutilSafeHTMLTestCase.php',
'PhutilSaturateStdoutDaemon' => 'daemon/torture/PhutilSaturateStdoutDaemon.php',
'PhutilServiceProfiler' => 'serviceprofiler/PhutilServiceProfiler.php',
'PhutilShellLexer' => 'lexer/PhutilShellLexer.php',
'PhutilShellLexerTestCase' => 'lexer/__tests__/PhutilShellLexerTestCase.php',
'PhutilSimpleOptions' => 'parser/PhutilSimpleOptions.php',
'PhutilSimpleOptionsLexer' => 'lexer/PhutilSimpleOptionsLexer.php',
'PhutilSimpleOptionsLexerTestCase' => 'lexer/__tests__/PhutilSimpleOptionsLexerTestCase.php',
'PhutilSimpleOptionsTestCase' => 'parser/__tests__/PhutilSimpleOptionsTestCase.php',
'PhutilSocketChannel' => 'channel/PhutilSocketChannel.php',
'PhutilSprite' => 'sprites/PhutilSprite.php',
'PhutilSpriteSheet' => 'sprites/PhutilSpriteSheet.php',
'PhutilSymbolLoader' => 'symbols/PhutilSymbolLoader.php',
'PhutilSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilSyntaxHighlighter.php',
'PhutilSyntaxHighlighterEngine' => 'markup/syntax/engine/PhutilSyntaxHighlighterEngine.php',
'PhutilSyntaxHighlighterException' => 'markup/syntax/highlighter/PhutilSyntaxHighlighterException.php',
'PhutilTestCase' => 'infrastructure/testing/PhutilTestCase.php',
'PhutilTestPhobject' => 'object/__tests__/PhutilTestPhobject.php',
'PhutilTortureTestDaemon' => 'daemon/torture/PhutilTortureTestDaemon.php',
'PhutilTranslator' => 'internationalization/PhutilTranslator.php',
'PhutilTranslatorTestCase' => 'internationalization/__tests__/PhutilTranslatorTestCase.php',
'PhutilTwitchFuture' => 'future/twitch/PhutilTwitchFuture.php',
'PhutilTypeCheckException' => 'parser/exception/PhutilTypeCheckException.php',
'PhutilTypeExtraParametersException' => 'parser/exception/PhutilTypeExtraParametersException.php',
'PhutilTypeLexer' => 'lexer/PhutilTypeLexer.php',
'PhutilTypeMissingParametersException' => 'parser/exception/PhutilTypeMissingParametersException.php',
'PhutilTypeSpec' => 'parser/PhutilTypeSpec.php',
'PhutilTypeSpecTestCase' => 'parser/__tests__/PhutilTypeSpecTestCase.php',
'PhutilURI' => 'parser/PhutilURI.php',
'PhutilURITestCase' => 'parser/__tests__/PhutilURITestCase.php',
'PhutilUTF8StringTruncator' => 'utils/PhutilUTF8StringTruncator.php',
'PhutilUTF8TestCase' => 'utils/__tests__/PhutilUTF8TestCase.php',
+ 'PhutilUrisprintfTestCase' => 'xsprintf/__tests__/PhutilUrisprintfTestCase.php',
'PhutilUtilsTestCase' => 'utils/__tests__/PhutilUtilsTestCase.php',
'PhutilWordPressFuture' => 'future/wordpress/PhutilWordPressFuture.php',
'PhutilXHPASTSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilXHPASTSyntaxHighlighter.php',
'PhutilXHPASTSyntaxHighlighterFuture' => 'markup/syntax/highlighter/xhpast/PhutilXHPASTSyntaxHighlighterFuture.php',
'PhutilXHPASTSyntaxHighlighterTestCase' => 'markup/syntax/highlighter/__tests__/PhutilXHPASTSyntaxHighlighterTestCase.php',
- 'PhutilcsprintfTestCase' => 'xsprintf/__tests__/PhutilcsprintfTestCase.php',
- 'PhutilurisprintfTestCase' => 'xsprintf/__tests__/PhutilurisprintfTestCase.php',
- 'PhutilxsprintfTestCase' => 'xsprintf/__tests__/PhutilxsprintfTestCase.php',
'QueryFuture' => 'future/query/QueryFuture.php',
'TempFile' => 'filesystem/TempFile.php',
'TestAbstractDirectedGraph' => 'utils/__tests__/TestAbstractDirectedGraph.php',
'XHPASTNode' => 'parser/xhpast/api/XHPASTNode.php',
'XHPASTNodeTestCase' => 'parser/xhpast/api/__tests__/XHPASTNodeTestCase.php',
'XHPASTSyntaxErrorException' => 'parser/xhpast/api/XHPASTSyntaxErrorException.php',
'XHPASTToken' => 'parser/xhpast/api/XHPASTToken.php',
'XHPASTTree' => 'parser/xhpast/api/XHPASTTree.php',
'XHPASTTreeTestCase' => 'parser/xhpast/api/__tests__/XHPASTTreeTestCase.php',
+ 'XsprintfUnknownConversionException' => 'xsprintf/exception/XsprintfUnknownConversionException.php',
),
'function' =>
array(
'Futures' => 'future/functions.php',
'_qsprintf_check_scalar_type' => 'xsprintf/qsprintf.php',
'_qsprintf_check_type' => 'xsprintf/qsprintf.php',
'array_fuse' => 'utils/utils.php',
'array_interleave' => 'utils/utils.php',
'array_mergev' => 'utils/utils.php',
'array_select_keys' => 'utils/utils.php',
'assert_instances_of' => 'utils/utils.php',
'assert_stringlike' => 'utils/utils.php',
'coalesce' => 'utils/utils.php',
'csprintf' => 'xsprintf/csprintf.php',
'exec_manual' => 'future/exec/execx.php',
'execx' => 'future/exec/execx.php',
'head' => 'utils/utils.php',
'head_key' => 'utils/utils.php',
'hgsprintf' => 'xsprintf/hgsprintf.php',
'hsprintf' => 'markup/render.php',
'id' => 'utils/utils.php',
'idx' => 'utils/utils.php',
'ifilter' => 'utils/utils.php',
'igroup' => 'utils/utils.php',
'ipull' => 'utils/utils.php',
'isort' => 'utils/utils.php',
'jsprintf' => 'xsprintf/jsprintf.php',
'last' => 'utils/utils.php',
'last_key' => 'utils/utils.php',
'ldap_sprintf' => 'xsprintf/ldapsprintf.php',
'mfilter' => 'utils/utils.php',
'mgroup' => 'utils/utils.php',
'mpull' => 'utils/utils.php',
'msort' => 'utils/utils.php',
'newv' => 'utils/utils.php',
'nonempty' => 'utils/utils.php',
'phlog' => 'error/phlog.php',
'pht' => 'internationalization/pht.php',
'phutil_censor_credentials' => 'utils/utils.php',
'phutil_console_confirm' => 'console/format.php',
'phutil_console_format' => 'console/format.php',
'phutil_console_get_terminal_width' => 'console/format.php',
'phutil_console_prompt' => 'console/format.php',
'phutil_console_require_tty' => 'console/format.php',
'phutil_console_wrap' => 'console/format.php',
'phutil_deprecated' => 'moduleutils/moduleutils.php',
'phutil_error_listener_example' => 'error/phlog.php',
'phutil_escape_html' => 'markup/render.php',
'phutil_escape_html_newlines' => 'markup/render.php',
'phutil_escape_uri' => 'markup/render.php',
'phutil_escape_uri_path_component' => 'markup/render.php',
'phutil_exit' => 'utils/utils.php',
'phutil_fwrite_nonblocking_stream' => 'utils/utils.php',
'phutil_get_library_name_for_root' => 'moduleutils/moduleutils.php',
'phutil_get_library_root' => 'moduleutils/moduleutils.php',
'phutil_get_library_root_for_path' => 'moduleutils/moduleutils.php',
'phutil_get_signal_name' => 'future/exec/execx.php',
'phutil_implode_html' => 'markup/render.php',
'phutil_is_hiphop_runtime' => 'utils/utils.php',
'phutil_is_utf8' => 'utils/utf8.php',
'phutil_is_utf8_slowly' => 'utils/utf8.php',
'phutil_is_utf8_with_only_bmp_characters' => 'utils/utf8.php',
'phutil_is_windows' => 'utils/utils.php',
'phutil_json_decode' => 'utils/utils.php',
'phutil_loggable_string' => 'utils/utils.php',
'phutil_passthru' => 'future/exec/execx.php',
'phutil_safe_html' => 'markup/render.php',
'phutil_split_lines' => 'utils/utils.php',
'phutil_tag' => 'markup/render.php',
'phutil_tag_div' => 'markup/render.php',
'phutil_unescape_uri_path_component' => 'markup/render.php',
'phutil_units' => 'utils/utils.php',
'phutil_utf8_console_strlen' => 'utils/utf8.php',
'phutil_utf8_convert' => 'utils/utf8.php',
'phutil_utf8_hard_wrap' => 'utils/utf8.php',
'phutil_utf8_hard_wrap_html' => 'utils/utf8.php',
'phutil_utf8_is_combining_character' => 'utils/utf8.php',
'phutil_utf8_shorten' => 'utils/utf8.php',
'phutil_utf8_strlen' => 'utils/utf8.php',
'phutil_utf8_strtolower' => 'utils/utf8.php',
'phutil_utf8_strtoupper' => 'utils/utf8.php',
'phutil_utf8_strtr' => 'utils/utf8.php',
'phutil_utf8_ucwords' => 'utils/utf8.php',
'phutil_utf8ize' => 'utils/utf8.php',
'phutil_utf8v' => 'utils/utf8.php',
'phutil_utf8v_codepoints' => 'utils/utf8.php',
'phutil_utf8v_combined' => 'utils/utf8.php',
'ppull' => 'utils/utils.php',
'qsprintf' => 'xsprintf/qsprintf.php',
'queryfx' => 'xsprintf/queryfx.php',
'queryfx_all' => 'xsprintf/queryfx.php',
'queryfx_one' => 'xsprintf/queryfx.php',
'urisprintf' => 'xsprintf/urisprintf.php',
'vcsprintf' => 'xsprintf/csprintf.php',
'vjsprintf' => 'xsprintf/jsprintf.php',
'vqsprintf' => 'xsprintf/qsprintf.php',
'vqueryfx' => 'xsprintf/queryfx.php',
'vqueryfx_all' => 'xsprintf/queryfx.php',
'vurisprintf' => 'xsprintf/urisprintf.php',
'xhp_parser_node_constants' => 'parser/xhpast/parser_nodes.php',
'xhpast_build' => 'parser/xhpast/bin/xhpast_parse.php',
'xhpast_get_binary_path' => 'parser/xhpast/bin/xhpast_parse.php',
'xhpast_get_build_instructions' => 'parser/xhpast/bin/xhpast_parse.php',
'xhpast_get_parser_future' => 'parser/xhpast/bin/xhpast_parse.php',
'xhpast_is_available' => 'parser/xhpast/bin/xhpast_parse.php',
'xhpast_parser_token_constants' => 'parser/xhpast/parser_tokens.php',
'xsprintf' => 'xsprintf/xsprintf.php',
'xsprintf_callback_example' => 'xsprintf/xsprintf.php',
'xsprintf_command' => 'xsprintf/csprintf.php',
'xsprintf_javascript' => 'xsprintf/jsprintf.php',
'xsprintf_ldap' => 'xsprintf/ldapsprintf.php',
'xsprintf_mercurial' => 'xsprintf/hgsprintf.php',
'xsprintf_query' => 'xsprintf/qsprintf.php',
'xsprintf_uri' => 'xsprintf/urisprintf.php',
),
'xmap' =>
array(
'AASTNodeList' =>
array(
0 => 'Iterator',
1 => 'Countable',
),
'AbstractDirectedGraphTestCase' => 'PhutilTestCase',
'AphrontDatabaseConnection' => 'PhutilQsprintfInterface',
'AphrontIsolatedDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontMySQLDatabaseConnection' => 'AphrontMySQLDatabaseConnectionBase',
'AphrontMySQLDatabaseConnectionBase' => 'AphrontDatabaseConnection',
'AphrontMySQLiDatabaseConnection' => 'AphrontMySQLDatabaseConnectionBase',
'AphrontQueryAccessDeniedException' => 'AphrontQueryRecoverableException',
'AphrontQueryCharacterSetException' => 'AphrontQueryException',
'AphrontQueryConnectionException' => 'AphrontQueryException',
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
'AphrontQueryCountException' => 'AphrontQueryException',
'AphrontQueryDeadlockException' => 'AphrontQueryRecoverableException',
'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
'AphrontQueryException' => 'Exception',
'AphrontQueryNotSupportedException' => 'AphrontQueryException',
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontQuerySchemaException' => 'AphrontQueryException',
'AphrontWriteGuardExitEventListener' => 'PhutilEventListener',
'BaseHTTPFuture' => 'Future',
'CommandException' => 'Exception',
'ConduitClientException' => 'Exception',
'ConduitFuture' => 'FutureProxy',
'ExecFuture' => 'Future',
'ExecFutureTestCase' => 'PhutilTestCase',
'ExecPassthruTestCase' => 'PhutilTestCase',
'FileFinderTestCase' => 'PhutilTestCase',
'FilesystemException' => 'Exception',
'FilesystemTestCase' => 'PhutilTestCase',
'FutureIterator' => 'Iterator',
'FutureIteratorTestCase' => 'PhutilTestCase',
'FutureProxy' => 'Future',
'HTTPFuture' => 'BaseHTTPFuture',
'HTTPFutureResponseStatus' => 'Exception',
'HTTPFutureResponseStatusCURL' => 'HTTPFutureResponseStatus',
'HTTPFutureResponseStatusHTTP' => 'HTTPFutureResponseStatus',
'HTTPFutureResponseStatusParse' => 'HTTPFutureResponseStatus',
'HTTPFutureResponseStatusTransport' => 'HTTPFutureResponseStatus',
'HTTPSFuture' => 'BaseHTTPFuture',
'ImmediateFuture' => 'Future',
'LinesOfALarge' => 'Iterator',
'LinesOfALargeExecFuture' => 'LinesOfALarge',
'LinesOfALargeExecFutureTestCase' => 'PhutilTestCase',
'LinesOfALargeFile' => 'LinesOfALarge',
'LinesOfALargeFileTestCase' => 'PhutilTestCase',
'PHPASTParserTestCase' => 'PhutilTestCase',
'PhageAgentTestCase' => 'PhutilTestCase',
'PhagePHPAgentBootloader' => 'PhageAgentBootloader',
'Phobject' => 'Iterator',
'PhutilAWSEC2Future' => 'PhutilAWSFuture',
'PhutilAWSException' => 'Exception',
'PhutilAWSFuture' => 'FutureProxy',
'PhutilAggregateException' => 'Exception',
'PhutilArgumentParserException' => 'Exception',
'PhutilArgumentParserTestCase' => 'PhutilTestCase',
'PhutilArgumentSpecificationException' => 'PhutilArgumentParserException',
'PhutilArgumentSpecificationTestCase' => 'PhutilTestCase',
'PhutilArgumentUsageException' => 'PhutilArgumentParserException',
'PhutilArray' =>
array(
0 => 'Phobject',
1 => 'Countable',
2 => 'ArrayAccess',
3 => 'Iterator',
),
'PhutilArrayTestCase' => 'PhutilTestCase',
'PhutilArrayWithDefaultValue' => 'PhutilArray',
'PhutilAsanaFuture' => 'FutureProxy',
'PhutilAuthAdapterEmpty' => 'PhutilAuthAdapter',
'PhutilAuthAdapterLDAP' => 'PhutilAuthAdapter',
'PhutilAuthAdapterOAuth' => 'PhutilAuthAdapter',
'PhutilAuthAdapterOAuth1' => 'PhutilAuthAdapter',
'PhutilAuthAdapterOAuthAmazon' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthAsana' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthBitbucket' => 'PhutilAuthAdapterOAuth1',
'PhutilAuthAdapterOAuthDisqus' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthFacebook' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthGitHub' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthGoogle' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthJIRA' => 'PhutilAuthAdapterOAuth1',
'PhutilAuthAdapterOAuthTwitch' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthTwitter' => 'PhutilAuthAdapterOAuth1',
'PhutilAuthAdapterOAuthWordPress' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterPersona' => 'PhutilAuthAdapter',
'PhutilAuthConfigurationException' => 'PhutilAuthException',
'PhutilAuthCredentialException' => 'PhutilAuthException',
'PhutilAuthException' => 'Exception',
'PhutilAuthUserAbortedException' => 'PhutilAuthException',
'PhutilBufferedIterator' => 'Iterator',
'PhutilBufferedIteratorExample' => 'PhutilBufferedIterator',
'PhutilBufferedIteratorTestCase' => 'PhutilTestCase',
'PhutilBugtraqParserTestCase' => 'PhutilTestCase',
'PhutilCLikeCodeSnippetContextFreeGrammar' => 'PhutilCodeSnippetContextFreeGrammar',
'PhutilCallbackFilterIterator' => 'FilterIterator',
'PhutilChannelChannel' => 'PhutilChannel',
'PhutilChannelTestCase' => 'PhutilTestCase',
'PhutilChunkedIterator' => 'Iterator',
'PhutilChunkedIteratorTestCase' => 'PhutilTestCase',
'PhutilCodeSnippetContextFreeGrammar' => 'PhutilContextFreeGrammar',
'PhutilCommandString' => 'Phobject',
'PhutilConsoleProgressBar' => 'Phobject',
'PhutilConsoleServerChannel' => 'PhutilChannelChannel',
'PhutilConsoleStdinNotInteractiveException' => 'Exception',
'PhutilConsoleTable' => 'Phobject',
'PhutilConsoleWrapTestCase' => 'PhutilTestCase',
+ 'PhutilCsprintfTestCase' => 'ArcanistTestCase',
'PhutilDefaultSyntaxHighlighterEngine' => 'PhutilSyntaxHighlighterEngine',
'PhutilDefaultSyntaxHighlighterEnginePygmentsFuture' => 'FutureProxy',
'PhutilDefaultSyntaxHighlighterEngineTestCase' => 'PhutilTestCase',
'PhutilDeferredLogTestCase' => 'PhutilTestCase',
'PhutilDirectedScalarGraph' => 'AbstractDirectedGraph',
'PhutilDocblockParserTestCase' => 'PhutilTestCase',
'PhutilEditDistanceMatrixTestCase' => 'PhutilTestCase',
'PhutilEmailAddressTestCase' => 'PhutilTestCase',
'PhutilErrorHandlerTestCase' => 'PhutilTestCase',
'PhutilErrorTrap' => 'Phobject',
'PhutilEventType' => 'PhutilEventConstants',
'PhutilExcessiveServiceCallsDaemon' => 'PhutilTortureTestDaemon',
'PhutilExecChannel' => 'PhutilChannel',
'PhutilExecPassthru' => 'Phobject',
'PhutilExtensionsTestCase' => 'PhutilTestCase',
'PhutilFatalDaemon' => 'PhutilTortureTestDaemon',
'PhutilFileLock' => 'PhutilLock',
'PhutilFileLockTestCase' => 'PhutilTestCase',
'PhutilGitURITestCase' => 'PhutilTestCase',
'PhutilHangForeverDaemon' => 'PhutilTortureTestDaemon',
'PhutilHelpArgumentWorkflow' => 'PhutilArgumentWorkflow',
+ 'PhutilHgsprintfTestCase' => 'ArcanistTestCase',
'PhutilInfrastructureTestCase' => 'PhutilTestCase',
'PhutilJSONParserException' => 'Exception',
'PhutilJSONParserTestCase' => 'PhutilTestCase',
'PhutilJSONProtocolChannel' => 'PhutilProtocolChannel',
'PhutilJSONProtocolChannelTestCase' => 'PhutilTestCase',
'PhutilJSONTestCase' => 'PhutilTestCase',
'PhutilJavaCodeSnippetContextFreeGrammar' => 'PhutilCLikeCodeSnippetContextFreeGrammar',
'PhutilKeyValueCacheAPC' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheDirectory' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheInRequest' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheMemcache' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheNamespace' => 'PhutilKeyValueCacheProxy',
'PhutilKeyValueCacheOnDisk' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheProfiler' => 'PhutilKeyValueCacheProxy',
'PhutilKeyValueCacheProxy' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheStack' => 'PhutilKeyValueCache',
'PhutilKeyValueCacheTestCase' => 'ArcanistPhutilTestCase',
'PhutilLanguageGuesserTestCase' => 'PhutilTestCase',
'PhutilLexerSyntaxHighlighter' => 'PhutilSyntaxHighlighter',
'PhutilLipsumContextFreeGrammar' => 'PhutilContextFreeGrammar',
'PhutilLockException' => 'Exception',
'PhutilLogfileChannel' => 'PhutilChannelChannel',
'PhutilLunarPhaseTestCase' => 'PhutilTestCase',
'PhutilMarkupTestCase' => 'PhutilTestCase',
'PhutilMetricsChannel' => 'PhutilChannelChannel',
'PhutilMissingSymbolException' => 'Exception',
'PhutilNiceDaemon' => 'PhutilTortureTestDaemon',
'PhutilOAuth1Future' => 'FutureProxy',
'PhutilOAuth1FutureTestCase' => 'PhutilTestCase',
'PhutilOpaqueEnvelopeTestCase' => 'PhutilTestCase',
'PhutilPHPCodeSnippetContextFreeGrammar' => 'PhutilCLikeCodeSnippetContextFreeGrammar',
'PhutilPHPFragmentLexer' => 'PhutilLexer',
'PhutilPHPFragmentLexerHighlighterTestCase' => 'PhutilTestCase',
'PhutilPHPFragmentLexerTestCase' => 'PhutilTestCase',
'PhutilPHPObjectProtocolChannel' => 'PhutilProtocolChannel',
'PhutilPHPObjectProtocolChannelTestCase' => 'PhutilTestCase',
'PhutilPHTTestCase' => 'PhutilTestCase',
'PhutilParserGeneratorException' => 'Exception',
'PhutilParserGeneratorInvalidRuleException' => 'PhutilParserGeneratorException',
'PhutilParserGeneratorIrreducibleRuleException' => 'PhutilParserGeneratorException',
'PhutilParserGeneratorTestCase' => 'PhutilTestCase',
'PhutilParserGeneratorUnknownSymbolException' => 'PhutilParserGeneratorException',
'PhutilParserGeneratorUnreachableRuleException' => 'PhutilParserGeneratorException',
'PhutilParserGeneratorUnreachableTerminalException' => 'PhutilParserGeneratorException',
'PhutilPayPalAPIFuture' => 'FutureProxy',
'PhutilPersonTest' => 'PhutilPerson',
'PhutilPhobjectTestCase' => 'PhutilTestCase',
'PhutilProcessGroupDaemon' => 'PhutilTortureTestDaemon',
'PhutilProtocolChannel' => 'PhutilChannelChannel',
'PhutilProxyException' => 'Exception',
'PhutilPythonFragmentLexer' => 'PhutilLexer',
'PhutilQueryStringParserTestCase' => 'PhutilTestCase',
'PhutilReadableSerializerTestCase' => 'PhutilTestCase',
'PhutilRealnameContextFreeGrammar' => 'PhutilContextFreeGrammar',
'PhutilRemarkupEngine' => 'PhutilMarkupEngine',
'PhutilRemarkupEngineRemarkupCodeBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupDefaultBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupHeaderBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupHorizontalRuleBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupInlineBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupInterpreterRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupListBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupLiteralBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupNoteBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupQuotesBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupReplyBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupSimpleTableBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupTableBlockRule' => 'PhutilRemarkupEngineBlockRule',
'PhutilRemarkupEngineRemarkupTestInterpreterRule' => 'PhutilRemarkupBlockInterpreter',
'PhutilRemarkupEngineTestCase' => 'PhutilTestCase',
'PhutilRemarkupRuleBold' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleDel' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleDocumentLink' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleEscapeRemarkup' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleHyperlink' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleItalic' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleLinebreaks' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleMonospace' => 'PhutilRemarkupRule',
'PhutilRemarkupRuleUnderline' => 'PhutilRemarkupRule',
'PhutilRope' => 'Phobject',
'PhutilRopeTestCase' => 'PhutilTestCase',
'PhutilSafeHTMLTestCase' => 'PhutilTestCase',
'PhutilSaturateStdoutDaemon' => 'PhutilTortureTestDaemon',
'PhutilShellLexer' => 'PhutilLexer',
'PhutilShellLexerTestCase' => 'PhutilTestCase',
'PhutilSimpleOptionsLexer' => 'PhutilLexer',
'PhutilSimpleOptionsLexerTestCase' => 'PhutilTestCase',
'PhutilSimpleOptionsTestCase' => 'PhutilTestCase',
'PhutilSocketChannel' => 'PhutilChannel',
'PhutilSyntaxHighlighterException' => 'Exception',
'PhutilTestCase' => 'ArcanistPhutilTestCase',
'PhutilTestPhobject' => 'Phobject',
'PhutilTortureTestDaemon' => 'PhutilDaemon',
'PhutilTranslatorTestCase' => 'PhutilTestCase',
'PhutilTwitchFuture' => 'FutureProxy',
'PhutilTypeCheckException' => 'Exception',
'PhutilTypeExtraParametersException' => 'Exception',
'PhutilTypeLexer' => 'PhutilLexer',
'PhutilTypeMissingParametersException' => 'Exception',
'PhutilTypeSpecTestCase' => 'PhutilTestCase',
'PhutilURITestCase' => 'PhutilTestCase',
'PhutilUTF8StringTruncator' => 'Phobject',
'PhutilUTF8TestCase' => 'PhutilTestCase',
+ 'PhutilUrisprintfTestCase' => 'ArcanistTestCase',
'PhutilUtilsTestCase' => 'PhutilTestCase',
'PhutilWordPressFuture' => 'FutureProxy',
'PhutilXHPASTSyntaxHighlighterFuture' => 'FutureProxy',
'PhutilXHPASTSyntaxHighlighterTestCase' => 'PhutilTestCase',
- 'PhutilcsprintfTestCase' => 'ArcanistTestCase',
- 'PhutilurisprintfTestCase' => 'ArcanistTestCase',
- 'PhutilxsprintfTestCase' => 'ArcanistTestCase',
'QueryFuture' => 'Future',
'TestAbstractDirectedGraph' => 'AbstractDirectedGraph',
'XHPASTNode' => 'AASTNode',
'XHPASTNodeTestCase' => 'PhutilTestCase',
'XHPASTSyntaxErrorException' => 'Exception',
'XHPASTToken' => 'AASTToken',
'XHPASTTree' => 'AASTTree',
'XHPASTTreeTestCase' => 'PhutilTestCase',
+ 'XsprintfUnknownConversionException' => 'InvalidArgumentException',
),
));
diff --git a/src/xsprintf/PhutilCommandString.php b/src/xsprintf/PhutilCommandString.php
index 72ca0a8..0da7af0 100644
--- a/src/xsprintf/PhutilCommandString.php
+++ b/src/xsprintf/PhutilCommandString.php
@@ -1,36 +1,36 @@
<?php
final class PhutilCommandString extends Phobject {
private $argv;
public function __construct(array $argv) {
$this->argv = $argv;
// This makes sure we throw immediately if there are errors in the
// parameters.
$this->getMaskedString();
}
public function __toString() {
return $this->getMaskedString();
}
public function getUnmaskedString() {
- return $this->renderString($unmasked = true);
+ return $this->renderString(true);
}
public function getMaskedString() {
- return $this->renderString($unmasked = false);
+ return $this->renderString(false);
}
private function renderString($unmasked) {
return xsprintf(
'xsprintf_command',
array(
'unmasked' => $unmasked,
),
$this->argv);
}
}
diff --git a/src/xsprintf/__tests__/PhutilcsprintfTestCase.php b/src/xsprintf/__tests__/PhutilCsprintfTestCase.php
similarity index 67%
rename from src/xsprintf/__tests__/PhutilcsprintfTestCase.php
rename to src/xsprintf/__tests__/PhutilCsprintfTestCase.php
index 324f3c3..4383b59 100644
--- a/src/xsprintf/__tests__/PhutilcsprintfTestCase.php
+++ b/src/xsprintf/__tests__/PhutilCsprintfTestCase.php
@@ -1,58 +1,59 @@
<?php
-final class PhutilcsprintfTestCase extends PhutilTestCase {
+final class PhutilCsprintfTestCase extends PhutilTestCase {
public function testCommandReadableEscapes() {
// For arguments comprised of only characters which are safe in any context,
// %R this should avoid adding quotes.
- $this->assertTrue(('ab' === (string)csprintf('%R', 'ab')));
+ $this->assertEqual('ab', (string)csprintf('%R', 'ab'));
// For arguments which have any characters which are not safe in some
// context, %R should apply standard escaping.
- $this->assertFalse(('a b' === (string)csprintf('%R', 'a b')));
+ $this->assertFalse('a b' === (string)csprintf('%R', 'a b'));
}
public function testPasswords() {
-
// Normal "%s" doesn't do anything special.
$command = csprintf('echo %s', 'hunter2trustno1');
$this->assertTrue(strpos($command, 'hunter2trustno1') !== false);
// "%P" takes a PhutilOpaqueEnvelope.
$caught = null;
try {
csprintf('echo %P', 'hunter2trustno1');
} catch (Exception $ex) {
$caught = $ex;
}
- $this->assertTrue($caught instanceof Exception);
+ $this->assertTrue($caught instanceof InvalidArgumentException);
// "%P" masks the provided value.
$command = csprintf('echo %P', new PhutilOpaqueEnvelope('hunter2trustno1'));
$this->assertFalse(strpos($command, 'hunter2trustno1'));
// Executing the command works as expected.
list($out) = execx('%C', $command);
$this->assertTrue(strpos($out, 'hunter2trustno1') !== false);
+ }
+ public function testEscapingIsRobust() {
+ if (phutil_is_windows()) {
+ $this->assertSkipped("This test doesn't work on Windows.");
+ }
// Escaping should be robust even when used to escape commands which take
// other commands.
- if (!phutil_is_windows()) {
- list($out) = execx(
+ list($out) = execx(
+ 'sh -c %s',
+ csprintf(
'sh -c %s',
csprintf(
'sh -c %s',
csprintf(
- 'sh -c %s',
- csprintf(
- 'echo %P',
- new PhutilOpaqueEnvelope('!@#$%^&*()')))));
- $this->assertTrue(strpos($out, '!@#$%^&*()') !== false);
- }
-
+ 'echo %P',
+ new PhutilOpaqueEnvelope('!@#$%^&*()')))));
+ $this->assertTrue(strpos($out, '!@#$%^&*()') !== false);
}
}
diff --git a/src/xsprintf/__tests__/PhutilxsprintfTestCase.php b/src/xsprintf/__tests__/PhutilHgsprintfTestCase.php
similarity index 79%
rename from src/xsprintf/__tests__/PhutilxsprintfTestCase.php
rename to src/xsprintf/__tests__/PhutilHgsprintfTestCase.php
index c7ccc48..7babefb 100644
--- a/src/xsprintf/__tests__/PhutilxsprintfTestCase.php
+++ b/src/xsprintf/__tests__/PhutilHgsprintfTestCase.php
@@ -1,23 +1,23 @@
<?php
-final class PhutilxsprintfTestCase extends PhutilTestCase {
+final class PhutilHgsprintfTestCase extends PhutilTestCase {
- public function testhgsprintf() {
+ public function testHgsprintf() {
$this->assertEqual(
"'version-1'",
hgsprintf('%s', 'version-1'));
$this->assertEqual(
"'single\\'quote'",
hgsprintf('%s', "single'quote"));
$this->assertEqual(
"'back\\\\slash'",
hgsprintf('%s', 'back\\slash'));
$this->assertEqual(
"'33%'",
hgsprintf('%R', hgsprintf('%s', '33%')));
}
}
diff --git a/src/xsprintf/__tests__/PhutilurisprintfTestCase.php b/src/xsprintf/__tests__/PhutilUrisprintfTestCase.php
similarity index 75%
rename from src/xsprintf/__tests__/PhutilurisprintfTestCase.php
rename to src/xsprintf/__tests__/PhutilUrisprintfTestCase.php
index 6207ce3..c12c51d 100644
--- a/src/xsprintf/__tests__/PhutilurisprintfTestCase.php
+++ b/src/xsprintf/__tests__/PhutilUrisprintfTestCase.php
@@ -1,21 +1,19 @@
<?php
-final class PhutilurisprintfTestCase extends PhutilTestCase {
-
- public function testurisprintf() {
+final class PhutilUrisprintfTestCase extends PhutilTestCase {
+ public function testUrisprintf() {
$this->assertEqual(
'x.com?a=huh%3F',
urisprintf('x.com?a=%s', 'huh?'));
$this->assertEqual(
'/a/origin%252Fmaster/z/',
urisprintf('/a/%p/z/', 'origin/master'));
$this->assertEqual(
'y.com?%21&%23',
vurisprintf('y.com?%s&%s', array('!', '#')));
-
}
}
diff --git a/src/xsprintf/csprintf.php b/src/xsprintf/csprintf.php
index 718b935..8a40805 100644
--- a/src/xsprintf/csprintf.php
+++ b/src/xsprintf/csprintf.php
@@ -1,135 +1,135 @@
<?php
/**
- * Format a shell command string. This function behaves like sprintf(), except
- * that all the normal conversions (like %s) will be properly escaped, and
+ * Format a shell command string. This function behaves like `sprintf`, except
+ * that all the normal conversions (like "%s") will be properly escaped, and
* additional conversions are supported:
*
* %Ls
* List of strings that will be escaped. They will be space separated.
*
* %LR
* List of "readable" strings. They will be space separated.
*
* %P
* Password (or other sensitive parameter) to escape. Pass a
- * PhutilOpaqueEnvelope.
+ * @{class:PhutilOpaqueEnvelope}.
*
* %C (Raw Command)
* Passes the argument through without escaping. Dangerous!
*
* %R
* A more "readable" version of "%s". This will try to print the command
* without any escaping if it contains only characters which are safe
* in any context. The intent is to produce prettier human-readable
* commands.
*
- * Generally, you should invoke shell commands via execx() rather than by
- * calling csprintf() directly.
+ * Generally, you should invoke shell commands via @{function:execx} rather
+ * than by calling @{function:csprintf} directly.
*
* @param string sprintf()-style format string.
* @param ... Zero or more arguments.
* @return string Formatted string, escaped appropriately for shell contexts.
* @group exec
*/
function csprintf($pattern/* , ... */) {
$args = func_get_args();
return new PhutilCommandString($args);
}
/**
- * Version of csprintf() that takes a vector of arguments.
+ * Version of @{function:csprintf} that takes a vector of arguments.
*
* @param string sprintf()-style format string.
* @param list List of zero or more arguments to csprintf().
* @return string Formatted string, escaped appropriately for shell contexts.
* @group exec
*/
function vcsprintf($pattern, array $argv) {
array_unshift($argv, $pattern);
return call_user_func_array('csprintf', $argv);
}
-
/**
- * xsprintf() callback for csprintf().
+ * @{function:xsprintf} callback for @{function:csprintf}.
* @group exec
*/
function xsprintf_command($userdata, &$pattern, &$pos, &$value, &$length) {
$type = $pattern[$pos];
$next = (strlen($pattern) > $pos + 1) ? $pattern[$pos + 1] : null;
$is_unmasked = !empty($userdata['unmasked']);
if ($value instanceof PhutilCommandString) {
if ($is_unmasked) {
$value = $value->getUnmaskedString();
} else {
$value = $value->getMaskedString();
}
}
switch ($type) {
case 'L':
// Remove the L.
$pattern = substr_replace($pattern, '', $pos, 1);
$length = strlen($pattern);
$type = 's';
// Check that the value is a non-empty array.
if (!is_array($value)) {
- throw new Exception("Expected an array for %L{$next} conversion.");
+ throw new InvalidArgumentException(
+ "Expected an array for %L{$next} conversion.");
}
switch ($next) {
case 's':
$values = array();
foreach ($value as $val) {
$values[] = csprintf('%s', $val);
}
$value = implode(' ', $values);
break;
case 'R':
$values = array();
foreach ($value as $val) {
$values[] = csprintf('%R', $val);
}
$value = implode(' ', $values);
break;
default:
- throw new Exception("Unknown conversion %L{$next}.");
+ throw new XsprintfUnknownConversionException("%L{$next}");
}
break;
case 'R':
if (!preg_match('(^[a-zA-Z0-9:/@._-]+$)', $value)) {
$value = escapeshellarg($value);
}
$type = 's';
break;
case 's':
$value = escapeshellarg($value);
$type = 's';
break;
case 'P':
if (!($value instanceof PhutilOpaqueEnvelope)) {
- throw new Exception(
+ throw new InvalidArgumentException(
'Expected PhutilOpaqueEnvelope for %P conversion.');
}
if ($is_unmasked) {
$value = $value->openEnvelope();
} else {
$value = 'xxxxx';
}
$value = escapeshellarg($value);
$type = 's';
break;
case 'C':
$type = 's';
break;
}
$pattern[$pos] = $type;
}
diff --git a/src/xsprintf/exception/XsprintfUnknownConversionException.php b/src/xsprintf/exception/XsprintfUnknownConversionException.php
new file mode 100644
index 0000000..afe746b
--- /dev/null
+++ b/src/xsprintf/exception/XsprintfUnknownConversionException.php
@@ -0,0 +1,10 @@
+<?php
+
+final class XsprintfUnknownConversionException
+ extends InvalidArgumentException {
+
+ public function __construct($conversion) {
+ parent::__construct("Unknown conversion {$conversion}.");
+ }
+
+}
diff --git a/src/xsprintf/hgsprintf.php b/src/xsprintf/hgsprintf.php
index da45664..4f4f730 100644
--- a/src/xsprintf/hgsprintf.php
+++ b/src/xsprintf/hgsprintf.php
@@ -1,39 +1,37 @@
<?php
/**
* Format a Mercurial revset expression. Supports the following conversions:
*
* %s Symbol
* Escapes a Mercurial symbol, like a branch or bookmark name.
*
* %R Rrraw Rreferrrence / Rrrrevset
* Passes text through unescaped (e.g., an already-escaped revset).
*
* @group mercurial
*/
function hgsprintf($pattern /* , ... */) {
$args = func_get_args();
return xsprintf('xsprintf_mercurial', null, $args);
}
-
/**
- * xsprintf() callback for Mercurial encoding.
+ * @{function:xsprintf} callback for Mercurial encoding.
*
* @group mercurial
*/
function xsprintf_mercurial($userdata, &$pattern, &$pos, &$value, &$length) {
-
$type = $pattern[$pos];
switch ($type) {
case 's':
$value = "'".addcslashes($value, "'\\")."'";
break;
case 'R':
$type = 's';
break;
}
- $pattern[$pos] = $type;
+ $pattern[$pos] = $type;
}
diff --git a/src/xsprintf/jsprintf.php b/src/xsprintf/jsprintf.php
index 96b64ab..15daaf7 100644
--- a/src/xsprintf/jsprintf.php
+++ b/src/xsprintf/jsprintf.php
@@ -1,96 +1,93 @@
<?php
/**
* Format a Javascript string, using JSON to export complex values. This
- * function behaves like sprintf(), except that all the normal conversions
- * (like %s) will be properly escaped, and additional conversions are
+ * function behaves like `sprintf`, except that all the normal conversions
+ * (like "%s") will be properly escaped, and additional conversions are
* supported:
*
* %O (Object)
* Converts the argument to a JSON object.
*
* %A (Array)
* Converts the argument to a JSON array.
*
* %b (Boolean)
* Converts a value to either `true' or `false'.
*
* %# (FBID)
* JavaScript has issues with 64-bit numbers so we use this as our
* transport mechanism from PHP to JavaScript
*
* %J (Javascript)
* Inserts raw, unescaped Javascript. This is DANGEROUS because it WILL
* NOT BE ESCAPED.
*
* @group markup
*/
function jsprintf($pattern /* , ... */) {
$args = func_get_args();
return xsprintf('xsprintf_javascript', null, $args);
}
-
/**
* @group markup
*/
function vjsprintf($pattern, array $argv) {
array_unshift($argv, $pattern);
return xsprintf('xsprintf_javascript', null, $argv);
}
-
/**
- * xsprintf() callback for javascript encoding.
+ * @{function:xsprintf} callback for JavaScript encoding.
* @group markup
*/
function xsprintf_javascript($userdata, &$pattern, &$pos, &$value, &$length) {
-
$type = $pattern[$pos];
switch ($type) {
case '#':
case 's':
$value = json_encode((string)$value);
$type = 's';
break;
case 'A':
if (!is_array($value)) {
$value = array();
}
$value = json_encode(array_values($value));
$type = 's';
break;
case 'O':
if ($value !== null) {
$value = (object)$value;
}
$value = json_encode($value);
$type = 's';
break;
case 'J':
$type = 's';
break;
case 'b':
$value = $value ? 'true' : 'false';
$type = 's';
break;
case 'd':
if ($value > 0x1FFFFFFFFFFFFF) {
- throw new Exception(
+ throw new RangeException(
"You are passing an integer to jsprintf() which is so large it can ".
"not be represented without loss of precision by Javascript's ".
"native Number class. Use %# instead.");
}
break;
}
- $pattern[$pos] = $type;
+ $pattern[$pos] = $type;
}
diff --git a/src/xsprintf/ldapsprintf.php b/src/xsprintf/ldapsprintf.php
index a0475c5..99fd398 100644
--- a/src/xsprintf/ldapsprintf.php
+++ b/src/xsprintf/ldapsprintf.php
@@ -1,50 +1,49 @@
<?php
/**
- * Format an LDAP string. This function behaves like sprintf(), except that all
- * the normal conversions (like %s) will be properly escaped, and additional
+ * Format an LDAP string. This function behaves like `sprintf`, except that all
+ * the normal conversions (like "%s") will be properly escaped, and additional
* conversions are supported:
*
* %S (Search Filter)
* Escapes text for use in a search filter.
*
* %Q (Raw Query)
* Inserts raw, unescaped text. DANGEROUS!
*
*/
function ldap_sprintf($pattern /* , ... */) {
$args = func_get_args();
return xsprintf('xsprintf_ldap', null, $args);
}
/**
- * ldap_sprintf() callback for LDAP encoding.
+ * @{function:ldap_sprintf} callback for LDAP encoding.
* @group markup
*/
function xsprintf_ldap($userdata, &$pattern, &$pos, &$value, &$length) {
-
$type = $pattern[$pos];
// https://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java
switch ($type) {
case 'S':
$value = str_replace(
array('\\', '*', '(', ')', "\0"),
array('\\5c', '\\2a', '\\28', '\\29', '\\00'),
$value);
$type = 's';
break;
case 's':
$value = addcslashes($value, ',\\#+<>;"= ');
$type = 's';
break;
case 'Q':
$type = 's';
break;
}
- $pattern[$pos] = $type;
+ $pattern[$pos] = $type;
}
diff --git a/src/xsprintf/qsprintf.php b/src/xsprintf/qsprintf.php
index 99e5cff..10bbb14 100644
--- a/src/xsprintf/qsprintf.php
+++ b/src/xsprintf/qsprintf.php
@@ -1,309 +1,321 @@
<?php
/**
- * Format an SQL query. This function behaves like sprintf(), except that
- * all the normal conversions (like %s) will be properly escaped, and
- * additional conversions are supported:
+ * Format an SQL query. This function behaves like `sprintf`, except that all
+ * the normal conversions (like "%s") will be properly escaped, and additional
+ * conversions are supported:
*
* %nd, %ns, %nf, %nB
* "Nullable" versions of %d, %s, %f and %B. Will produce 'NULL' if the
* argument is a strict null.
*
* %=d, %=s, %=f
* "Nullable Test" versions of %d, %s and %f. If you pass a value, you
* get "= 3"; if you pass null, you get "IS NULL". For instance, this
* will work properly if `hatID' is a nullable column and $hat is null.
*
* qsprintf($escaper, 'WHERE hatID %=d', $hat);
*
* %Ld, %Ls, %Lf, %LB
* "List" versions of %d, %s, %f and %B. These are appropriate for use in
* an "IN" clause. For example:
*
* qsprintf($escaper, 'WHERE hatID IN(%Ld)', $list_of_hats);
*
* %B ("Binary String")
* Escapes a string for insertion into a pure binary column, ignoring
* tests for characters outside of the basic multilingual plane.
*
* %T ("Table")
* Escapes a table name.
*
* %C, %LC
* Escapes a column name or a list of column names.
*
* %K ("Comment")
* Escapes a comment.
*
* %Q ("Query Fragment")
* Injects a raw query fragment. Extremely dangerous! Not escaped!
*
* %~ ("Substring")
* Escapes a substring query for a LIKE (or NOT LIKE) clause. For example:
*
* // Find all rows with $search as a substing of `name`.
* qsprintf($escaper, 'WHERE name LIKE %~', $search);
*
* See also %> and %<.
*
* %> ("Prefix")
* Escapes a prefix query for a LIKE clause. For example:
*
* // Find all rows where `name` starts with $prefix.
* qsprintf($escaper, 'WHERE name LIKE %>', $prefix);
*
* %< ("Suffix")
* Escapes a suffix query for a LIKE clause. For example:
*
* // Find all rows where `name` ends with $suffix.
* qsprintf($escaper, 'WHERE name LIKE %<', $suffix);
*
* @group storage
*/
function qsprintf(PhutilQsprintfInterface $escaper, $pattern/* , ... */) {
$args = func_get_args();
array_shift($args);
return xsprintf('xsprintf_query', $escaper, $args);
}
/**
* @group storage
*/
function vqsprintf(PhutilQsprintfInterface $escaper, $pattern, array $argv) {
array_unshift($argv, $pattern);
return xsprintf('xsprintf_query', $escaper, $argv);
}
-
/**
- * xsprintf() callback for encoding SQL queries. See qsprintf().
+ * @{function:xsprintf} callback for encoding SQL queries. See
+ * @{function:qsprintf}.
+ *
* @group storage
*/
function xsprintf_query($userdata, &$pattern, &$pos, &$value, &$length) {
$type = $pattern[$pos];
$escaper = $userdata;
$next = (strlen($pattern) > $pos + 1) ? $pattern[$pos + 1] : null;
$nullable = false;
$done = false;
$prefix = '';
if (!($escaper instanceof PhutilQsprintfInterface)) {
- throw new Exception('Invalid database escaper!');
+ throw new InvalidArgumentException('Invalid database escaper.');
}
switch ($type) {
case '=': // Nullable test
switch ($next) {
case 'd':
case 'f':
case 's':
$pattern = substr_replace($pattern, '', $pos, 1);
$length = strlen($pattern);
- $type = 's';
+ $type = 's';
if ($value === null) {
$value = 'IS NULL';
$done = true;
} else {
$prefix = '= ';
$type = $next;
}
break;
default:
throw new Exception('Unknown conversion, try %=d, %=s, or %=f.');
}
break;
case 'n': // Nullable...
switch ($next) {
case 'd': // ...integer.
case 'f': // ...float.
case 's': // ...string.
case 'B': // ...binary string.
$pattern = substr_replace($pattern, '', $pos, 1);
$length = strlen($pattern);
$type = $next;
$nullable = true;
break;
default:
- throw new Exception('Unknown conversion, try %nd or %ns.');
+ throw new XsprintfUnknownConversionException("%n{$next}");
}
break;
case 'L': // List of..
_qsprintf_check_type($value, "L{$next}", $pattern);
$pattern = substr_replace($pattern, '', $pos, 1);
$length = strlen($pattern);
$type = 's';
$done = true;
switch ($next) {
case 'd': // ...integers.
$value = implode(', ', array_map('intval', $value));
break;
case 's': // ...strings.
foreach ($value as $k => $v) {
$value[$k] = "'".$escaper->escapeUTF8String((string)$v)."'";
}
$value = implode(', ', $value);
break;
case 'B': // ...binary strings.
foreach ($value as $k => $v) {
$value[$k] = "'".$escaper->escapeBinaryString((string)$v)."'";
}
$value = implode(', ', $value);
break;
case 'C': // ...columns.
foreach ($value as $k => $v) {
$value[$k] = $escaper->escapeColumnName($v);
}
$value = implode(', ', $value);
break;
default:
- throw new Exception("Unknown conversion %L{$next}.");
+ throw new XsprintfUnknownConversionException("%L{$next}");
}
break;
}
if (!$done) {
_qsprintf_check_type($value, $type, $pattern);
switch ($type) {
case 's': // String
if ($nullable && $value === null) {
$value = 'NULL';
} else {
$value = "'".$escaper->escapeUTF8String((string)$value)."'";
}
$type = 's';
break;
case 'B': // Binary String
if ($nullable && $value === null) {
$value = 'NULL';
} else {
$value = "'".$escaper->escapeBinaryString((string)$value)."'";
}
$type = 's';
break;
case 'Q': // Query Fragment
$type = 's';
break;
case '~': // Like Substring
case '>': // Like Prefix
case '<': // Like Suffix
$value = $escaper->escapeStringForLikeClause($value);
switch ($type) {
case '~': $value = "'%".$value."%'"; break;
case '>': $value = "'".$value."%'"; break;
case '<': $value = "'%".$value."'"; break;
}
$type = 's';
break;
case 'f': // Float
if ($nullable && $value === null) {
$value = 'NULL';
} else {
$value = (float)$value;
}
$type = 's';
break;
case 'd': // Integer
if ($nullable && $value === null) {
$value = 'NULL';
} else {
$value = (int)$value;
}
$type = 's';
break;
case 'T': // Table
case 'C': // Column
$value = $escaper->escapeColumnName($value);
$type = 's';
break;
case 'K': // Komment
$value = $escaper->escapeMultilineComment($value);
$type = 's';
break;
default:
- throw new Exception("Unknown conversion '%{$type}'.");
-
+ throw new XsprintfUnknownConversionException($type);
}
}
if ($prefix) {
$value = $prefix.$value;
}
$pattern[$pos] = $type;
}
-
/**
* @group storage
*/
function _qsprintf_check_type($value, $type, $query) {
switch ($type) {
- case 'Ld': case 'Ls': case 'LC': case 'LB':
+ case 'Ld':
+ case 'Ls':
+ case 'LC':
+ case 'LB':
if (!is_array($value)) {
throw new AphrontQueryParameterException(
$query,
"Expected array argument for %{$type} conversion.");
}
if (empty($value)) {
throw new AphrontQueryParameterException(
$query,
"Array for %{$type} conversion is empty.");
}
foreach ($value as $scalar) {
_qsprintf_check_scalar_type($scalar, $type, $query);
}
break;
default:
_qsprintf_check_scalar_type($value, $type, $query);
break;
}
}
-
/**
* @group storage
*/
function _qsprintf_check_scalar_type($value, $type, $query) {
switch ($type) {
- case 'Q': case 'LC': case 'T': case 'C':
+ case 'Q':
+ case 'LC':
+ case 'T':
+ case 'C':
if (!is_string($value)) {
throw new AphrontQueryParameterException(
$query,
"Expected a string for %{$type} conversion.");
}
break;
- case 'Ld': case 'd': case 'f':
+ case 'Ld':
+ case 'd':
+ case 'f':
if (!is_null($value) && !is_numeric($value)) {
throw new AphrontQueryParameterException(
$query,
"Expected a numeric scalar or null for %{$type} conversion.");
}
break;
- case 'Ls': case 's': case 'LB': case 'B':
- case '~': case '>': case '<': case 'K':
+ case 'Ls':
+ case 's':
+ case 'LB':
+ case 'B':
+ case '~':
+ case '>':
+ case '<':
+ case 'K':
if (!is_null($value) && !is_scalar($value)) {
throw new AphrontQueryParameterException(
$query,
"Expected a scalar or null for %{$type} conversion.");
}
break;
default:
- throw new Exception("Unknown conversion '{$type}'.");
+ throw new XsprintfUnknownConversionException($type);
}
}
diff --git a/src/xsprintf/queryfx.php b/src/xsprintf/queryfx.php
index b94cf2a..27c859e 100644
--- a/src/xsprintf/queryfx.php
+++ b/src/xsprintf/queryfx.php
@@ -1,51 +1,50 @@
<?php
/**
* @group storage
*/
function queryfx(AphrontDatabaseConnection $conn, $sql/* , ... */) {
$argv = func_get_args();
$query = call_user_func_array('qsprintf', $argv);
$conn->executeRawQuery($query);
}
/**
* @group storage
*/
function vqueryfx(AphrontDatabaseConnection $conn, $sql, array $argv) {
array_unshift($argv, $conn, $sql);
call_user_func_array('queryfx', $argv);
}
/**
* @group storage
*/
function queryfx_all(AphrontDatabaseConnection $conn, $sql/* , ... */) {
$argv = func_get_args();
call_user_func_array('queryfx', $argv);
return $conn->selectAllResults();
}
/**
* @group storage
*/
function queryfx_one(AphrontDatabaseConnection $conn, $sql/* , ... */) {
$argv = func_get_args();
$ret = call_user_func_array('queryfx_all', $argv);
if (count($ret) > 1) {
- throw new AphrontQueryCountException(
- 'Query returned more than one row.');
+ throw new AphrontQueryCountException('Query returned more than one row.');
} else if (count($ret)) {
return reset($ret);
}
return null;
}
/**
* @group storage
*/
function vqueryfx_all(AphrontDatabaseConnection $conn, $sql, array $argv) {
array_unshift($argv, $conn, $sql);
call_user_func_array('queryfx', $argv);
return $conn->selectAllResults();
}
diff --git a/src/xsprintf/urisprintf.php b/src/xsprintf/urisprintf.php
index 0a7c738..6c7e2a5 100644
--- a/src/xsprintf/urisprintf.php
+++ b/src/xsprintf/urisprintf.php
@@ -1,52 +1,51 @@
<?php
/**
- * Format a URI. This function behaves like sprintf(), except that all the
- * normal conversions (like %s) will be properly escaped, and additional
+ * Format a URI. This function behaves like `sprintf`, except that all the
+ * normal conversions (like "%s") will be properly escaped, and additional
* conversions are supported:
*
* %s (String)
* Escapes text for use in a URI.
*
* %p (Path Component)
* Escapes text for use in a URI path component.
*
* %R (Raw String)
* Inserts raw, unescaped text. DANGEROUS!
*/
function urisprintf($pattern /* , ... */) {
$args = func_get_args();
return xsprintf('xsprintf_uri', null, $args);
}
function vurisprintf($pattern, array $argv) {
array_unshift($argv, $pattern);
return call_user_func_array('urisprintf', $argv);
}
/**
- * uri_sprintf() callback for URI encoding.
+ * @{function:urisprintf} callback for URI encoding.
* @group markup
*/
function xsprintf_uri($userdata, &$pattern, &$pos, &$value, &$length) {
-
$type = $pattern[$pos];
switch ($type) {
case 's':
$value = phutil_escape_uri($value);
$type = 's';
break;
case 'p':
$value = phutil_escape_uri_path_component($value);
$type = 's';
break;
case 'R':
$type = 's';
break;
}
- $pattern[$pos] = $type;
+ $pattern[$pos] = $type;
}
diff --git a/src/xsprintf/xsprintf.php b/src/xsprintf/xsprintf.php
index 311326a..69ffe31 100644
--- a/src/xsprintf/xsprintf.php
+++ b/src/xsprintf/xsprintf.php
@@ -1,117 +1,114 @@
<?php
/**
* Parse a sprintf()-style format string in an extensible way.
*
* This method allows you to build a function with sprintf() semantics but
* custom conversions for different datatypes. Three examples are
* @{function:jsprintf} (which builds Javascript strings),
* @{function:qsprintf} (which builds MySQL strings), and
* @{function:csprintf} (which builds command line strings).
*
* To build a new xsprintf-family function, provide a callback which conforms
* to the specification described in @{function:xsprintf_callback_example}. The
* callback will be invoked each time a conversion (like "%Z") is encountered
* in the string. For instance, if you call xsprintf() like this...
*
* $result = xsprintf(
* 'xsprintf_callback_example',
* $userdata = null,
* array(
* "The %M is made of %C.",
* 'moon',
* 'cheese',
* ));
*
* ...the callback will be invoked twice, at string positions 5 ("M") and 19
* ("C"), with values "moon" and "cheese" respectively.
*
* @param string The name of a callback to pass conversions to.
* @param wild Optional userdata to pass to the callback. For
* @{function:qsprintf}, this is the database connection.
* @param list List of arguments, with the sprintf() pattern in position 0.
* @return string Formatted string.
- *
*/
-function xsprintf($callback, $userdata, $argv) {
+function xsprintf($callback, $userdata, array $argv) {
$argc = count($argv);
$arg = 0;
$pos = 0;
$pattern = $argv[0];
$len = strlen($pattern);
$conv = false; // Are we inside a conversion?
for ($pos = 0; $pos < $len; $pos++) {
$c = $pattern[$pos];
if ($conv) {
- // We could make a greater effort to support formatting modifiers,
- // but they really have no place in semantic string formatting.
+ // We could make a greater effort to support formatting modifiers,
+ // but they really have no place in semantic string formatting.
if (strpos("'-0123456789.\$+", $c) !== false) {
- throw new Exception(
+ throw new InvalidArgumentException(
"xsprintf() does not support the `%{$c}' modifier.");
}
- if ($c != '%') {
+ if ($c !== '%') {
$conv = false;
$arg++;
if ($arg >= $argc) {
- throw new Exception('Too few arguments to xsprintf().');
+ throw new BadFunctionCallException(
+ 'Too few arguments to xsprintf().');
}
$callback($userdata, $pattern, $pos, $argv[$arg], $len);
}
}
- if ($c == '%') {
- // If we have "%%", this encodes a literal percentage symbol, so we are
- // no longer inside a conversion.
+ if ($c === '%') {
+ // If we have "%%", this encodes a literal percentage symbol, so we are
+ // no longer inside a conversion.
$conv = !$conv;
}
}
- if ($arg != ($argc - 1)) {
- throw new Exception('Too many arguments to xsprintf().');
+ if ($arg !== ($argc - 1)) {
+ throw new BadFunctionCallException('Too many arguments to xsprintf().');
}
$argv[0] = $pattern;
-
return call_user_func_array('sprintf', $argv);
}
-
/**
- * Example @{function:xsprintf} callback. When you call xsprintf(), you
- * must pass a callback like this one. xsprintf() will invoke the callback when
- * it encounters a conversion (like "%Z") in the pattern string.
+ * Example @{function:xsprintf} callback. When you call `xsprintf`, you must
+ * pass a callback like this one. `xsprintf` will invoke the callback when it
+ * encounters a conversion (like "%Z") in the pattern string.
*
- * Generally, this callback should examine ##$pattern[$pos]## (which will
- * contain the conversion character, like 'Z'), escape ##$value## appropriately,
- * and then replace ##$pattern[$pos]## with an 's' so sprintf() prints the
- * escaped value as a string. However, more sophisticated behaviors are possible
- * -- particularly, consuming multiple characters to allow for conversions like
- * "%Ld". In this case, the callback needs to substr_replace() the entire
- * conversion with 's' and then update ##$length##.
+ * Generally, this callback should examine `$pattern[$pos]` (which will contain
+ * the conversion character, like 'Z'), escape `$value` appropriately, and then
+ * replace `$pattern[$pos]` with an 's' so `sprintf` prints the escaped value
+ * as a string. However, more sophisticated behaviors are possible --
+ * particularly, consuming multiple characters to allow for conversions like
+ * "%Ld". In this case, the callback needs to `substr_replace` the entire
+ * conversion with 's' and then update `$length`.
*
* For example implementations, see @{function:xsprintf_command},
- * @{function:xsprintf_javascript},
- * and @{function:xsprintf_query}.
+ * @{function:xsprintf_javascript} and @{function:xsprintf_query}.
*
* @param wild Arbitrary, optional userdata. This is whatever userdata
* was passed to @{function:xsprintf}.
* @param string The pattern string being parsed.
* @param int The current character position in the string.
* @param wild The value to convert.
* @param int The string length.
*/
function xsprintf_callback_example(
$userdata,
&$pattern,
&$pos,
&$value,
&$length) {
- throw new Exception(
+ throw new RuntimeException(
'This function exists only to document the call signature for xsprintf() '.
'callbacks.');
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 8, 12:25 PM (17 h, 21 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
2c/7c/44452a8c86e6db984775c7e7443d

Event Timeline