diff --git a/lib/Gallio_3.1.397.0/ASL - Apache Software Foundation License.txt b/lib/Gallio_3.1.397.0/ASL - Apache Software Foundation License.txt new file mode 100644 index 00000000..e259b584 --- /dev/null +++ b/lib/Gallio_3.1.397.0/ASL - Apache Software Foundation License.txt @@ -0,0 +1,57 @@ +Apache License, Version 2.0 + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating that You changed the files; and + + 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/lib/Gallio_3.1.397.0/Cecil.FlowAnalysis.license.html b/lib/Gallio_3.1.397.0/Cecil.FlowAnalysis.license.html new file mode 100644 index 00000000..d7d78ce5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/Cecil.FlowAnalysis.license.html @@ -0,0 +1,37 @@ + + +Cecil.FlowAnalysis.license + + + +

+ (C) 2005-2006 db4objects, Inc. http://www.db4o.com +

+

+ Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in the + Software without restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, subject to the + following conditions: +

+

+ The above copyright notice and this permission notice shall be included in all copies + or substantial portions of the Software. +

+

+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +

+ + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/Credits.html b/lib/Gallio_3.1.397.0/Credits.html new file mode 100644 index 00000000..280bcbab --- /dev/null +++ b/lib/Gallio_3.1.397.0/Credits.html @@ -0,0 +1,83 @@ + +Credits + +

+Many people have donated their creativity, insight, time and effort +to the Gallio and MbUnit projects. +

+We would like to take a moment to recognize and thank these individuals. +

+

Contributors

+

+These people have contributed directly to this project as developers, +writers, editors, leaders, and promoters. +

+We thank them all for their careful attention to detail and work +in pursuit of excellence. +

+

+

+

Acknowledgements

+

+These people have contributed indirectly to this project as peers, +users, reviewers, bug reporters, friends and family. +

+We thank them all for their ideas, support and constructive criticism. +

+

+

+

Final Thanks

+

+In addition to these fine people, there are always countless others whose +efforts directly or indirectly supported this project. They produced +the tools we use, invented the ideas we borrowed, and offered a kind word +in a time of need. +

+We thank them all. +

+If you are one of these people and your name does not appear on this list, +please let us know and we shall update it. +

+ + diff --git a/lib/Gallio_3.1.397.0/Gallio License.txt b/lib/Gallio_3.1.397.0/Gallio License.txt new file mode 100644 index 00000000..3d41c893 --- /dev/null +++ b/lib/Gallio_3.1.397.0/Gallio License.txt @@ -0,0 +1,14 @@ +Copyright 2005-2009 Gallio Project - http://www.gallio.org/ +Portions Copyright 2000-2004 Jonathan de Halleux + +Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/lib/Gallio_3.1.397.0/Gallio Website.url b/lib/Gallio_3.1.397.0/Gallio Website.url new file mode 100644 index 00000000..f488e52a --- /dev/null +++ b/lib/Gallio_3.1.397.0/Gallio Website.url @@ -0,0 +1,8 @@ +[InternetShortcut] +URL=http://www.gallio.org/ +IDList= +IconFile=http://www.mbunit.com/favicon.ico +IconIndex=1 +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/lib/Gallio_3.1.397.0/MbUnit Website.url b/lib/Gallio_3.1.397.0/MbUnit Website.url new file mode 100644 index 00000000..6f2b4e28 --- /dev/null +++ b/lib/Gallio_3.1.397.0/MbUnit Website.url @@ -0,0 +1,8 @@ +[InternetShortcut] +URL=http://www.mbunit.com/ +IDList= +IconFile=http://www.mbunit.com/favicon.ico +IconIndex=1 +HotKey=0 +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/lib/Gallio_3.1.397.0/Mono.Cecil.license.html b/lib/Gallio_3.1.397.0/Mono.Cecil.license.html new file mode 100644 index 00000000..8025bbaf --- /dev/null +++ b/lib/Gallio_3.1.397.0/Mono.Cecil.license.html @@ -0,0 +1,36 @@ + + +Mono.Cecil.license + + + +

+ (C) 2004-2006 Jb Evain +

+

+ Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in the + Software without restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, subject to the + following conditions: +

+

+ The above copyright notice and this permission notice shall be included in all copies + or substantial portions of the Software. +

+

+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE.

+ + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/Mono.GetOptions.license.html b/lib/Gallio_3.1.397.0/Mono.GetOptions.license.html new file mode 100644 index 00000000..22c56b31 --- /dev/null +++ b/lib/Gallio_3.1.397.0/Mono.GetOptions.license.html @@ -0,0 +1,38 @@ + + +Mono.GetOptions.license + + + +

+ Mono.GetOptions - + (C) 2002, 2003, 2004, 2005 Rafael Teixeira +

+

+ Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in the + Software without restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, subject to the + following conditions: +

+

+ The above copyright notice and this permission notice shall be included in all copies + or substantial portions of the Software. +

+

+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +

+ + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Aga.Controls.dll b/lib/Gallio_3.1.397.0/bin/Aga.Controls.dll new file mode 100644 index 00000000..3497d277 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Aga.Controls.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.Plugin.dll b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.Plugin.dll new file mode 100644 index 00000000..6b852511 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.Plugin.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.UI.dll b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.UI.dll new file mode 100644 index 00000000..b012d72f Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.UI.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.UI.plugin b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.UI.plugin new file mode 100644 index 00000000..a62e84b9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.UI.plugin @@ -0,0 +1,48 @@ + + + + AutoCAD Integration Plugin UI + 3.1.0.0 + AutoCAD plugin UI components. + plugin://Gallio.AutoCAD/Resources/Gallio.AutoCAD.ico + + + + + + + + + + + + + + + + + + + + + AutoCAD + plugin://Gallio.AutoCAD/Resources/Gallio.AutoCAD.ico + + + + + + AutoCAD/Startup + plugin://Gallio.AutoCAD/Resources/Gallio.AutoCAD.ico + User + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.dll b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.dll new file mode 100644 index 00000000..3907f703 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.plugin b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.plugin new file mode 100644 index 00000000..fc0cf849 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/AutoCAD/Gallio.AutoCAD.plugin @@ -0,0 +1,76 @@ + + + + AutoCAD Integration Plugin + 3.1.0.0 + Provides support for testing ObjectARX extensions within AutoCAD. + plugin://Gallio.AutoCAD/Resources/Gallio.AutoCAD.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${AutoCAD.AcadTestIsolationProvider} + + + AutoCAD + + Runs tests within an AutoCAD process. + + Supported test runner properties: + - AcadAttachToExisting: If "true" attaches to an existing AutoCAD process, otherwise starts a new one. + - AcadExePath: Specifies the full path of the "acad.exe" program. + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/Resources/Gallio.AutoCAD.ico b/lib/Gallio_3.1.397.0/bin/AutoCAD/Resources/Gallio.AutoCAD.ico new file mode 100644 index 00000000..9bcd7fbe Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/AutoCAD/Resources/Gallio.AutoCAD.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/AutoCAD/objectarx_license.doc b/lib/Gallio_3.1.397.0/bin/AutoCAD/objectarx_license.doc new file mode 100644 index 00000000..51aec728 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/AutoCAD/objectarx_license.doc differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/Gallio.CSUnitAdapter.dll b/lib/Gallio_3.1.397.0/bin/CSUnit/Gallio.CSUnitAdapter.dll new file mode 100644 index 00000000..a15eb1a9 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/CSUnit/Gallio.CSUnitAdapter.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/Gallio.CSUnitAdapter.plugin b/lib/Gallio_3.1.397.0/bin/CSUnit/Gallio.CSUnitAdapter.plugin new file mode 100644 index 00000000..4d91c5f0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/CSUnit/Gallio.CSUnitAdapter.plugin @@ -0,0 +1,85 @@ + + + + csUnit Adapter Plugin + 3.1.0.0 + Provides support for running csUnit tests. + plugin://Gallio.CSUnitAdapter/Resources/csUnit.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + csUnit + csUnit + 2.6.3374.34355 + Assembly + plugin://Gallio.CSUnitAdapter/Resources/csUnit.ico + + + + + + csUnit Assembly + csUnit Test Assembly + plugin://Gallio.CSUnitAdapter/Resources/csUnit.ico + + + + diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/Readme.txt b/lib/Gallio_3.1.397.0/bin/CSUnit/Readme.txt new file mode 100644 index 00000000..5b696f68 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/CSUnit/Readme.txt @@ -0,0 +1,11 @@ +CSUnit Adapter Plugin +===================== + +This plugin uses the csUnit test runner to adapt csUnit tests so that +they can run within Gallio and be manipulated by Gallio-based tools. + +The plugin assembly is deliberately NOT signed using a strong name. +You can replace the underlying test framework with newer versions as +long as they are binary compatible with the originally distributed version. + +Home page: http://www.csunit.org/ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/Resources/csUnit.ico b/lib/Gallio_3.1.397.0/bin/CSUnit/Resources/csUnit.ico new file mode 100644 index 00000000..6ba0f33b Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/CSUnit/Resources/csUnit.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Common.dll b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Common.dll new file mode 100644 index 00000000..3b30bd16 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Common.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Core.dll b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Core.dll new file mode 100644 index 00000000..07301066 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Core.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Interfaces.dll b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Interfaces.dll new file mode 100644 index 00000000..e427324c Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.Interfaces.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.dll b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.dll new file mode 100644 index 00000000..6e98aecc Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.dll.tdnet b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.dll.tdnet new file mode 100644 index 00000000..f7ec05a5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/CSUnit/csUnit.dll.tdnet @@ -0,0 +1,6 @@ + + csUnit v{0}.{1}.{2} + ..\TDNet\Gallio.TDNetRunner.dll + Gallio.TDNetRunner.GallioResidentTestRunner + Resident + diff --git a/lib/Gallio_3.1.397.0/bin/CSUnit/license.txt b/lib/Gallio_3.1.397.0/bin/CSUnit/license.txt new file mode 100644 index 00000000..ac5fbb78 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/CSUnit/license.txt @@ -0,0 +1,20 @@ +Copyright © 2002-2008 by Manfred Lange, Markus Renschler, Jake Anderson, + and Piers Lawson. All rights reserved. + +This software is provided 'as-is', without any express or implied warranty. In +no event will the authors be held liable for any damages arising from the use +of this software. + +Permission is granted to anyone to use this software for any purpose, including +commercial applications, and to alter it and redistribute it freely, subject to +the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim + that you wrote the original software. If you use this software in a product, + an acknowledgment in the product documentation would be appreciated but is + not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.dll b/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.dll new file mode 100644 index 00000000..979c8af5 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.dll.config b/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.dll.config new file mode 100644 index 00000000..03afde39 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.dll.config @@ -0,0 +1,16 @@ + + + +
+ + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.plugin b/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.plugin new file mode 100644 index 00000000..fec27fc1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Gallio.DLRIntegration.plugin @@ -0,0 +1,645 @@ + + + + Dynamic Language Runtime Integration Plugin + 3.1.0.0 + Integrates the Dynamic Language Runtime with Gallio. + + + + + + + + libs + ..\libs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RubySource + A Ruby source file. + .*\.rb + + + + + + PythonSource + A Python source file. + .*\.py + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio.rb b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio.rb new file mode 100644 index 00000000..6ac8ac00 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio.rb @@ -0,0 +1,7 @@ +# +# Gallio integration classes for IronRuby. +# + +load_assembly 'Gallio' + +require 'gallio/wrappers' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers.rb b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers.rb new file mode 100644 index 00000000..7260ca85 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers.rb @@ -0,0 +1,8 @@ +# +# Provides wrappers for Gallio types and services. +# + +require 'gallio/wrappers/logger.rb' +require 'gallio/wrappers/message_sink.rb' +require 'gallio/wrappers/progress_monitor.rb' +require 'gallio/wrappers/runtime.rb' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/logger.rb b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/logger.rb new file mode 100644 index 00000000..e590eb9b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/logger.rb @@ -0,0 +1,41 @@ +# +# A wrapper for ILogger. +# + +module Gallio + module Wrappers + class Logger + attr_reader :inner + + def initialize(inner) + @inner = inner + end + + def error(message) + log(::Gallio::Runtime::Logging::LogSeverity.Error, message) + end + + def warning(message) + log(::Gallio::Runtime::Logging::LogSeverity.Warning, message) + end + + def important(message) + log(::Gallio::Runtime::Logging::LogSeverity.Important, message) + end + + def info(message) + log(::Gallio::Runtime::Logging::LogSeverity.Info, message) + end + + def debug(message) + log(::Gallio::Runtime::Logging::LogSeverity.Debug, message) + end + + private + + def log(severity, message) + @inner.Log(severity, message) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/message_sink.rb b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/message_sink.rb new file mode 100644 index 00000000..351d630c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/message_sink.rb @@ -0,0 +1,19 @@ +# +# A wrapper for IMessageSink +# + +module Gallio + module Wrappers + class MessageSink + attr_reader :inner + + def initialize(inner) + @inner = inner + end + + def publish(message) + @inner.Publish(message) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/progress_monitor.rb b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/progress_monitor.rb new file mode 100644 index 00000000..9c49161c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/progress_monitor.rb @@ -0,0 +1,39 @@ +# +# A wrapper for IProgressMonitor +# + +module Gallio + module Wrappers + class ProgressMonitor + attr_reader :inner + + def initialize(inner) + @inner = inner + end + + def begin_task(task_name, total_work_units) + @inner.BeginTask(task_name, total_work_units) + end + + def done() + @inner.Done() + end + + def is_canceled? + @inner.IsCanceled + end + + def set_status(message) + @inner.SetStatus(message) + end + + def worked(work_units) + @inner.Worked(work_units) + end + + def create_sub_progress_monitor(parent_work_units) + new(@inner.CreateSubProgressMonitor(parent_work_units)) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/runtime.rb b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/runtime.rb new file mode 100644 index 00000000..1816a9a1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/Scripts/IronRuby/gallio/wrappers/runtime.rb @@ -0,0 +1,13 @@ +# +# A wrapper for the runtime. +# + +module Gallio + module Wrappers + class Runtime + def self.Resolve(service_type_module) + ::Gallio::Runtime::RuntimeAccessor.ServiceLocator.Resolve(service_type_module.to_clr_type) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.Libraries.Yaml.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.Libraries.Yaml.dll new file mode 100644 index 00000000..99e81679 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.Libraries.Yaml.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.Libraries.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.Libraries.dll new file mode 100644 index 00000000..be60c939 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.Libraries.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.dll new file mode 100644 index 00000000..60dd87ce Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/IronRuby.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/IronRuby.rb new file mode 100644 index 00000000..5c8c8fc0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/IronRuby.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +warn("IronRuby library is built-in and doesn't need to be required anymore") diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/PresentationCore.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/PresentationCore.rb new file mode 100644 index 00000000..05c3b89b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/PresentationCore.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/PresentationFramework.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/PresentationFramework.rb new file mode 100644 index 00000000..41e65a02 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/PresentationFramework.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Data.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Data.rb new file mode 100644 index 00000000..9c160c9f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Data.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Drawing.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Drawing.rb new file mode 100644 index 00000000..9dbfe1ca --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Drawing.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Windows.Forms.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Windows.Forms.rb new file mode 100644 index 00000000..a02266e8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/System.Windows.Forms.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/WindowsBase.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/WindowsBase.rb new file mode 100644 index 00000000..dc3ef9be --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/WindowsBase.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require "WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/bigdecimal.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/bigdecimal.rb new file mode 100644 index 00000000..b2822f0f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/bigdecimal.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.BigDecimal' \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest.rb new file mode 100644 index 00000000..ac5e43cf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Digest' \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest/md5.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest/md5.rb new file mode 100644 index 00000000..5d30ed0f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest/md5.rb @@ -0,0 +1,17 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'digest' +# placeholder no-op file diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest/sha1.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest/sha1.rb new file mode 100644 index 00000000..a7364da5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/digest/sha1.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'digest' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/enumerator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/enumerator.rb new file mode 100644 index 00000000..57595610 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/enumerator.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Enumerator' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/etc.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/etc.rb new file mode 100644 index 00000000..2acb1eca --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/etc.rb @@ -0,0 +1,17 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + + +# No-op file since we won't support this under Windows diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/fcntl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/fcntl.rb new file mode 100644 index 00000000..eabc4379 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/fcntl.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.FileControl' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/hacks.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/hacks.rb new file mode 100644 index 00000000..8ca993c9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/hacks.rb @@ -0,0 +1,55 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +# In non-iirb sessions, TOPLEVEL_BINDING isn't defined +unless defined?(TOPLEVEL_BINDING) + TOPLEVEL_BINDING = binding +end + +# IronRuby bug: IO#read seems to chop off the first char + +class TCPSocket + def read size + recv size + end +end + +# Subclass Tracking + +module SubclassTracking + class Holder < Array + def each_object(klass, &b) + self.each { |c| b[c] } + end + end + def self.extended(klass) + (class << klass; self; end).send :attr_accessor, :subclasses + (class << klass; self; end).send :define_method, :inherited do |klazz| + klass.subclasses << klazz + super + end + klass.subclasses = Holder.new + end +end + +class IO + def flush; end # nop +end + +class String + def hex + self.to_i(16) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/iconv.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/iconv.rb new file mode 100644 index 00000000..ad2201f7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/iconv.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Iconv' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/nkf.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/nkf.rb new file mode 100644 index 00000000..dc85bf94 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/nkf.rb @@ -0,0 +1,33 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +# HACKHACKHACK: Stub implementation of NKF + +module NKF + AUTO = 0 + JIS = 1 + EUC = 2 + SJIS = 3 + NOCONV = 4 + ASCII = 5 + BINARY = 4 + NKF_RELEASE_DATE = "2007-01-28" + NKF_VERSION = "2.0.8" + UNKNOWN = 0 + UTF16 = 8 + UTF32 = 12 + UTF8 = 6 + VERSION = "2.0.8 (2007-01-28)" +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/openssl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/openssl.rb new file mode 100644 index 00000000..9608003a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/openssl.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.OpenSsl' \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/parse_tree.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/parse_tree.rb new file mode 100644 index 00000000..3e4312ad --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/parse_tree.rb @@ -0,0 +1,253 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +abort "*** Sorry, ParseTree doesn't work with ruby #{RUBY_VERSION}" if + RUBY_VERSION >= "1.9" + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.ParseTree' + +class Module + def modules + ancestors[1..-1] + end +end + +class Class + def modules + a = self.ancestors + a[1..a.index(superclass)-1] + end +end + +## +# ParseTree is a RubyInline-style extension that accesses and +# traverses the internal parse tree created by ruby. +# +# class Example +# def blah +# return 1 + 1 +# end +# end +# +# ParseTree.new.parse_tree(Example) +# => [[:class, :Example, :Object, +# [:defn, +# "blah", +# [:scope, +# [:block, +# [:args], +# [:return, [:call, [:lit, 1], "+", [:array, [:lit, 1]]]]]]]]] + +class ParseTree + + VERSION = '2.1.1' + + ## + # Front end translation method. + + def self.translate(klass_or_str, method=nil) + pt = self.new(false) + case klass_or_str + when String then + sexp = pt.parse_tree_for_string(klass_or_str).first + if method then + # class, scope, block, *methods + sexp.last.last[1..-1].find do |defn| + defn[1] == method + end + else + sexp + end + else + unless method.nil? then + if method.to_s =~ /^self\./ then + method = method.to_s[5..-1].intern + pt.parse_tree_for_method(klass_or_str, method, true) + else + pt.parse_tree_for_method(klass_or_str, method) + end + else + pt.parse_tree(klass_or_str).first + end + end + end + + ## + # Initializes a ParseTree instance. Includes newline nodes if + # +include_newlines+ which defaults to +$DEBUG+. + + def initialize(include_newlines=$DEBUG) + @include_newlines = include_newlines + end + + ## + # Main driver for ParseTree. Returns an array of arrays containing + # the parse tree for +klasses+. + # + # Structure: + # + # [[:class, classname, superclassname, [:defn :method1, ...], ...], ...] + # + # NOTE: v1.0 - v1.1 had the signature (klass, meth=nil). This wasn't + # used much at all and since parse_tree_for_method already existed, + # it was deemed more useful to expand this method to do multiple + # classes. + + def parse_tree(*klasses) + result = [] + klasses.each do |klass| + klassname = klass.name rescue '' # HACK klass.name should never be nil + # Tempfile's DelegateClass(File) seems to + # cause this + klassname = "UnnamedClass_#{klass.object_id}" if klassname.empty? + klassname = klassname.to_sym + + code = if Class === klass then + sc = klass.superclass + sc_name = ((sc.nil? or sc.name.empty?) ? "nil" : sc.name).intern + [:class, klassname, [:const, sc_name]] + else + [:module, klassname] + end + + method_names = [] + method_names += klass.instance_methods false + method_names += klass.private_instance_methods false + # protected methods are included in instance_methods, go figure! + + method_names.sort.each do |m| + r = parse_tree_for_method(klass, m.to_sym) + code << r + end + + klass.modules.each do |mod| # TODO: add a test for this + mod.instance_methods.each do |m| + r = parse_tree_for_method(mod, m.to_sym) + code << r + end + end + + klass.singleton_methods(false).sort.each do |m| + code << parse_tree_for_method(klass, m.to_sym, true) + end + + result << code + end + return result + end + + ## + # Returns the parse tree for just one +method+ of a class +klass+. + # + # Format: + # + # [:defn, :name, :body] + + def parse_tree_for_method(klass, method, is_cls_meth=false) + $stderr.puts "** parse_tree_for_method(#{klass}, #{method}):" if $DEBUG + r = parse_tree_for_meth(klass, method.to_sym, is_cls_meth) + r + end + + ## + # Returns the parse tree for a string +source+. + # + # Format: + # + # [[sexps] ... ] + + def parse_tree_for_string(source, filename = '(string)', line = 1) + old_verbose, $VERBOSE = $VERBOSE, true + return parse_tree_for_str0(source, filename, line) + ensure + $VERBOSE = old_verbose + end + + def parse_tree_for_str0(*__1args2__) # :nodoc: + parse_tree_for_str(*__1args2__) # just helps clean up the binding + end + + if RUBY_VERSION < "1.8.4" then + inline do |builder| + builder.add_type_converter("bool", '', '') + builder.c_singleton " + bool has_alloca() { + (void)self; + #ifdef C_ALLOCA + return Qtrue; + #else + return Qfalse; + #endif + }" + end + else + def self.has_alloca + true + end + end + + + NODE_NAMES = [ + # 00 + :method, :fbody, :cfunc, :scope, :block, + :if, :case, :when, :opt_n, :while, + # 10 + :until, :iter, :for, :break, :next, + :redo, :retry, :begin, :rescue, :resbody, + # 20 + :ensure, :and, :or, :not, :masgn, + :lasgn, :dasgn, :dasgn_curr, :gasgn, :iasgn, + # 30 + :cdecl, :cvasgn, :cvdecl, :op_asgn1, :op_asgn2, + :op_asgn_and, :op_asgn_or, :call, :fcall, :vcall, + # 40 + :super, :zsuper, :array, :zarray, :hash, + :return, :yield, :lvar, :dvar, :gvar, + # 50 + :ivar, :const, :cvar, :nth_ref, :back_ref, + :match, :match2, :match3, :lit, :str, + # 60 + :dstr, :xstr, :dxstr, :evstr, :dregx, + :dregx_once, :args, :argscat, :argspush, :splat, + # 70 + :to_ary, :svalue, :block_arg, :block_pass, :defn, + :defs, :alias, :valias, :undef, :class, + # 80 + :module, :sclass, :colon2, :colon3, :cref, + :dot2, :dot3, :flip2, :flip3, :attrset, + # 90 + :self, :nil, :true, :false, :defined, + # 95 + :newline, :postexe, :alloca, :dmethod, :bmethod, + # 100 + :memo, :ifunc, :dsym, :attrasgn, + :last + ] + + if RUBY_VERSION > "1.9" then + NODE_NAMES.insert NODE_NAMES.index(:hash), :values + NODE_NAMES.insert NODE_NAMES.index(:defined), :errinfo + NODE_NAMES.insert NODE_NAMES.index(:last), :prelude, :lambda + NODE_NAMES.delete :dmethod + NODE_NAMES[128] = NODE_NAMES.delete :newline + end + + ############################################################ + # END of rdoc methods + ############################################################ + + include ::IronRuby::ParseTree + +end # ParseTree class diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/prime.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/prime.rb new file mode 100644 index 00000000..d96cb451 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/prime.rb @@ -0,0 +1,21 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +#placeholder for either throwing an error, or implementing a readline library +#the basics here are just to past specs +class Prime + def self.instance + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/rbconfig.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/rbconfig.rb new file mode 100644 index 00000000..eec0aa3b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/rbconfig.rb @@ -0,0 +1,177 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + + +module Config + RUBY_VERSION == "1.8.6" or + raise "ruby lib version (1.8.6) doesn't match executable version (#{RUBY_VERSION})" + + CONFIG = {} + CONFIG["MAJOR"] = "1" + CONFIG["MINOR"] = "8" + CONFIG["TEENY"] = "6" + CONFIG["PATCHLEVEL"] = "0" + CONFIG["EXEEXT"] = ".exe" + # This value is used by libraries to spawn new processes to run Ruby scripts. Hence it needs to match the ir.exe name + CONFIG["ruby_install_name"] = "ir" + CONFIG["RUBY_INSTALL_NAME"] = "ir" + CONFIG["RUBY_SO_NAME"] = "msvcrt-ruby18" + CONFIG["SHELL"] = "$(COMSPEC)" + CONFIG["BUILD_FILE_SEPARATOR"] = "\\" + CONFIG["PATH_SEPARATOR"] = ";" + CONFIG["CFLAGS"] = "-MD -Zi -O2b2xg- -G6" + CONFIG["CPPFLAGS"] = "" + CONFIG["CXXFLAGS"] = "" + CONFIG["FFLAGS"] = "" + CONFIG["LDFLAGS"] = "" + CONFIG["LIBS"] = "oldnames.lib user32.lib advapi32.lib ws2_32.lib " + + # Set up paths + if ENV["MERLIN_ROOT"] then + # This is a dev environment. See http://wiki.github.com/ironruby/ironruby + TOPDIR = File.expand_path("bin/Debug", ENV["MERLIN_ROOT"]) + CONFIG["bindir"] = TOPDIR + CONFIG["libdir"] = File.expand_path("../External.LCA_RESTRICTED/Languages/Ruby/redist-libs", ENV["MERLIN_ROOT"]) + else + TOPDIR = File.dirname(__FILE__) + '/../../' + CONFIG["bindir"] = TOPDIR + "/bin" + CONFIG["libdir"] = TOPDIR + "/lib" + end + DESTDIR = TOPDIR && TOPDIR[/\A[a-z]:/i] || '' unless defined? DESTDIR + CONFIG["DESTDIR"] = DESTDIR + CONFIG["prefix"] = (TOPDIR || DESTDIR + "") + CONFIG["exec_prefix"] = "$(prefix)" + CONFIG["sbindir"] = "$(exec_prefix)/sbin" + CONFIG["libexecdir"] = "$(exec_prefix)/libexec" + CONFIG["datadir"] = "$(prefix)/share" + CONFIG["sysconfdir"] = "$(prefix)/etc" + CONFIG["sharedstatedir"] = "$(DESTDIR)/etc" + CONFIG["localstatedir"] = "$(DESTDIR)/var" + CONFIG["includedir"] = "$(prefix)/include" + CONFIG["infodir"] = "$(prefix)/info" + CONFIG["mandir"] = "$(prefix)/man" + CONFIG["rubylibdir"] = "$(libdir)/ruby/$(ruby_version)" + CONFIG["sitedir"] = "$(libdir)/ruby/site_ruby" + + CONFIG["oldincludedir"] = "/usr/include" + CONFIG["build"] = "i686-pc-mswin32" + CONFIG["build_alias"] = "i686-mswin32" + CONFIG["build_cpu"] = "i686" + CONFIG["build_vendor"] = "pc" + CONFIG["build_os"] = "mswin32" + CONFIG["host"] = "i686-pc-mswin32" + CONFIG["host_alias"] = "i686-mswin32" + CONFIG["host_cpu"] = "i686" + CONFIG["host_vendor"] = "pc" + CONFIG["host_os"] = "mswin32" + CONFIG["target"] = "i386-pc-mswin32" + CONFIG["target_alias"] = "i386-mswin32" + CONFIG["target_cpu"] = "i386" + CONFIG["target_vendor"] = "pc" + CONFIG["target_os"] = "mswin32" + CONFIG["CC"] = "cl -nologo" + CONFIG["CPP"] = "cl -nologo -E" + CONFIG["YACC"] = "byacc" + CONFIG["RANLIB"] = "" + CONFIG["AR"] = "lib -nologo" + CONFIG["ARFLAGS"] = "-machine:x86 -out:" + CONFIG["LN_S"] = "" + CONFIG["SET_MAKE"] = "" + CONFIG["CP"] = "copy > nul" + CONFIG["ALLOCA"] = "" + CONFIG["DEFAULT_KCODE"] = "" + CONFIG["OBJEXT"] = "obj" + CONFIG["XCFLAGS"] = "-DRUBY_EXPORT -I. -IC:/develop/win/ruby/ruby-1.8.6 -IC:/develop/win/ruby/ruby-1.8.6/missing" + CONFIG["XLDFLAGS"] = "-stack:0x2000000" + CONFIG["DLDFLAGS"] = "-link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH) -def:$(DEFFILE) -implib:$(*F:.so=)-$(arch).lib -pdb:$(*F:.so=)-$(arch).pdb" + CONFIG["ARCH_FLAG"] = "" + CONFIG["STATIC"] = "" + CONFIG["CCDLFLAGS"] = "" + CONFIG["LDSHARED"] = "cl -nologo -LD" + CONFIG["DLEXT"] = "so" + CONFIG["DLEXT2"] = "dll" + CONFIG["LIBEXT"] = "lib" + CONFIG["STRIP"] = "" + CONFIG["EXTSTATIC"] = "" + CONFIG["setup"] = "Setup" + CONFIG["MINIRUBY"] = ".\\miniruby.exe " + CONFIG["PREP"] = "miniruby.exe" + CONFIG["RUNRUBY"] = ".\\ruby.exe \"C:/develop/win/ruby/ruby-1.8.6/runruby.rb\" --extout=\".ext\" --" + CONFIG["EXTOUT"] = ".ext" + CONFIG["ARCHFILE"] = "" + CONFIG["RDOCTARGET"] = "install-nodoc" + CONFIG["LIBRUBY_LDSHARED"] = "cl -nologo -LD" + CONFIG["LIBRUBY_DLDFLAGS"] = " -def:msvcrt-ruby18.def" + CONFIG["rubyw_install_name"] = "rubyw" + CONFIG["RUBYW_INSTALL_NAME"] = "rubyw" + CONFIG["LIBRUBY_A"] = "$(RUBY_SO_NAME)-static.lib" + CONFIG["LIBRUBY_SO"] = "$(RUBY_SO_NAME).dll" + CONFIG["LIBRUBY_ALIASES"] = "" + CONFIG["LIBRUBY"] = "$(RUBY_SO_NAME).lib" + CONFIG["LIBRUBYARG"] = "$(LIBRUBYARG_SHARED)" + CONFIG["LIBRUBYARG_STATIC"] = "$(LIBRUBY_A)" + CONFIG["LIBRUBYARG_SHARED"] = "$(LIBRUBY)" + CONFIG["SOLIBS"] = "" + CONFIG["DLDLIBS"] = "" + CONFIG["ENABLE_SHARED"] = "yes" + CONFIG["OUTFLAG"] = "-Fe" + CONFIG["CPPOUTFILE"] = "-P" + CONFIG["LIBPATHFLAG"] = " -libpath:\"%s\"" + CONFIG["RPATHFLAG"] = "" + CONFIG["LIBARG"] = "%s.lib" + CONFIG["LINK_SO"] = "$(LDSHARED) -Fe$(@) $(OBJS) $(LIBS) $(LOCAL_LIBS) $(DLDFLAGS)" + CONFIG["COMPILE_C"] = "$(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)" + CONFIG["COMPILE_CXX"] = "$(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\\=/)" + CONFIG["COMPILE_RULES"] = "{$(srcdir)}.%s{}.%s: {$(topdir)}.%s{}.%s: {$(hdrdir)}.%s{}.%s: .%s.%s:" + CONFIG["RULE_SUBST"] = "{.;$(srcdir);$(topdir);$(hdrdir)}%s" + CONFIG["TRY_LINK"] = "$(CC) -Feconftest $(INCFLAGS) -I$(hdrdir) $(CPPFLAGS) $(CFLAGS) $(src) $(LOCAL_LIBS) $(LIBS) -link $(LDFLAGS) $(LIBPATH) $(XLDFLAGS)" + CONFIG["COMMON_LIBS"] = "m" + CONFIG["COMMON_MACROS"] = "WIN32_LEAN_AND_MEAN" + CONFIG["COMMON_HEADERS"] = "winsock2.h windows.h" + CONFIG["DISTCLEANFILES"] = "vc*.pdb" + CONFIG["EXPORT_PREFIX"] = " " + CONFIG["arch"] = "i386-mswin32" + CONFIG["sitearch"] = "i386-msvcrt" + CONFIG["configure_args"] = "--with-make-prog=nmake --enable-shared --with-winsock2" + CONFIG["ruby_version"] = "$(MAJOR).$(MINOR)" + CONFIG["archdir"] = "$(rubylibdir)/$(arch)" + CONFIG["sitelibdir"] = "$(sitedir)/$(ruby_version)" + CONFIG["sitearchdir"] = "$(sitelibdir)/$(sitearch)" + CONFIG["topdir"] = File.dirname(__FILE__) + MAKEFILE_CONFIG = {} + CONFIG.each{|k,v| MAKEFILE_CONFIG[k] = v.dup} + def Config::expand(val, config = CONFIG) + val.gsub!(/\$\$|\$\(([^()]+)\)|\$\{([^{}]+)\}/) do |var| + if !(v = $1 || $2) + '$' + elsif key = config[v = v[/\A[^:]+(?=(?::(.*?)=(.*))?\z)/]] + pat, sub = $1, $2 + config[v] = false + Config::expand(key, config) + config[v] = key + key = key.gsub(/#{Regexp.quote(pat)}(?=\s|\z)/n) {sub} if pat + key + else + var + end + end + val + end + CONFIG.each_value do |val| + Config::expand(val) + end +end +RbConfig = Config # compatibility for ruby-1.9 +CROSS_COMPILING = nil unless defined? CROSS_COMPILING diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/socket.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/socket.rb new file mode 100644 index 00000000..225a189a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/socket.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Sockets' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/stringio.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/stringio.rb new file mode 100644 index 00000000..3ec05c0d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/stringio.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.StringIO' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/strscan.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/strscan.rb new file mode 100644 index 00000000..fbed87e0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/strscan.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.StringScanner' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/syslog.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/syslog.rb new file mode 100644 index 00000000..ecf56d03 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/syslog.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +#placeholder for either throwing an error, or implementing a readline library diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/system.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/system.rb new file mode 100644 index 00000000..a34eca5e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/system.rb @@ -0,0 +1 @@ +require 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit.rb new file mode 100644 index 00000000..e1b43ea3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit.rb @@ -0,0 +1,281 @@ +require 'hacks' +require 'test/unit/testcase' +require 'test/unit/autorunner' + +module Test # :nodoc: + # + # = Test::Unit - Ruby Unit Testing Framework + # + # == Introduction + # + # Unit testing is making waves all over the place, largely due to the + # fact that it is a core practice of XP. While XP is great, unit testing + # has been around for a long time and has always been a good idea. One + # of the keys to good unit testing, though, is not just writing tests, + # but having tests. What's the difference? Well, if you just _write_ a + # test and throw it away, you have no guarantee that something won't + # change later which breaks your code. If, on the other hand, you _have_ + # tests (obviously you have to write them first), and run them as often + # as possible, you slowly build up a wall of things that cannot break + # without you immediately knowing about it. This is when unit testing + # hits its peak usefulness. + # + # Enter Test::Unit, a framework for unit testing in Ruby, helping you to + # design, debug and evaluate your code by making it easy to write and + # have tests for it. + # + # + # == Notes + # + # Test::Unit has grown out of and superceded Lapidary. + # + # + # == Feedback + # + # I like (and do my best to practice) XP, so I value early releases, + # user feedback, and clean, simple, expressive code. There is always + # room for improvement in everything I do, and Test::Unit is no + # exception. Please, let me know what you think of Test::Unit as it + # stands, and what you'd like to see expanded/changed/improved/etc. If + # you find a bug, let me know ASAP; one good way to let me know what the + # bug is is to submit a new test that catches it :-) Also, I'd love to + # hear about any successes you have with Test::Unit, and any + # documentation you might add will be greatly appreciated. My contact + # info is below. + # + # + # == Contact Information + # + # A lot of discussion happens about Ruby in general on the ruby-talk + # mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask + # any questions you might have there. I monitor the list, as do many + # other helpful Rubyists, and you're sure to get a quick answer. Of + # course, you're also welcome to email me (Nathaniel Talbott) directly + # at mailto:testunit@talbott.ws, and I'll do my best to help you out. + # + # + # == Credits + # + # I'd like to thank... + # + # Matz, for a great language! + # + # Masaki Suketa, for his work on RubyUnit, which filled a vital need in + # the Ruby world for a very long time. I'm also grateful for his help in + # polishing Test::Unit and getting the RubyUnit compatibility layer + # right. His graciousness in allowing Test::Unit to supercede RubyUnit + # continues to be a challenge to me to be more willing to defer my own + # rights. + # + # Ken McKinlay, for his interest and work on unit testing, and for his + # willingness to dialog about it. He was also a great help in pointing + # out some of the holes in the RubyUnit compatibility layer. + # + # Dave Thomas, for the original idea that led to the extremely simple + # "require 'test/unit'", plus his code to improve it even more by + # allowing the selection of tests from the command-line. Also, without + # RDoc, the documentation for Test::Unit would stink a lot more than it + # does now. + # + # Everyone who's helped out with bug reports, feature ideas, + # encouragement to continue, etc. It's a real privilege to be a part of + # the Ruby community. + # + # The guys at RoleModel Software, for putting up with me repeating, "But + # this would be so much easier in Ruby!" whenever we're coding in Java. + # + # My Creator, for giving me life, and giving it more abundantly. + # + # + # == License + # + # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free + # software, and is distributed under the Ruby license. See the COPYING + # file in the standard Ruby distribution for details. + # + # + # == Warranty + # + # This software is provided "as is" and without any express or + # implied warranties, including, without limitation, the implied + # warranties of merchantibility and fitness for a particular + # purpose. + # + # + # == Author + # + # Nathaniel Talbott. + # Copyright (c) 2000-2003, Nathaniel Talbott + # + # ---- + # + # = Usage + # + # The general idea behind unit testing is that you write a _test_ + # _method_ that makes certain _assertions_ about your code, working + # against a _test_ _fixture_. A bunch of these _test_ _methods_ are + # bundled up into a _test_ _suite_ and can be run any time the + # developer wants. The results of a run are gathered in a _test_ + # _result_ and displayed to the user through some UI. So, lets break + # this down and see how Test::Unit provides each of these necessary + # pieces. + # + # + # == Assertions + # + # These are the heart of the framework. Think of an assertion as a + # statement of expected outcome, i.e. "I assert that x should be equal + # to y". If, when the assertion is executed, it turns out to be + # correct, nothing happens, and life is good. If, on the other hand, + # your assertion turns out to be false, an error is propagated with + # pertinent information so that you can go back and make your + # assertion succeed, and, once again, life is good. For an explanation + # of the current assertions, see Test::Unit::Assertions. + # + # + # == Test Method & Test Fixture + # + # Obviously, these assertions have to be called within a context that + # knows about them and can do something meaningful with their + # pass/fail value. Also, it's handy to collect a bunch of related + # tests, each test represented by a method, into a common test class + # that knows how to run them. The tests will be in a separate class + # from the code they're testing for a couple of reasons. First of all, + # it allows your code to stay uncluttered with test code, making it + # easier to maintain. Second, it allows the tests to be stripped out + # for deployment, since they're really there for you, the developer, + # and your users don't need them. Third, and most importantly, it + # allows you to set up a common test fixture for your tests to run + # against. + # + # What's a test fixture? Well, tests do not live in a vacuum; rather, + # they're run against the code they are testing. Often, a collection + # of tests will run against a common set of data, also called a + # fixture. If they're all bundled into the same test class, they can + # all share the setting up and tearing down of that data, eliminating + # unnecessary duplication and making it much easier to add related + # tests. + # + # Test::Unit::TestCase wraps up a collection of test methods together + # and allows you to easily set up and tear down the same test fixture + # for each test. This is done by overriding #setup and/or #teardown, + # which will be called before and after each test method that is + # run. The TestCase also knows how to collect the results of your + # assertions into a Test::Unit::TestResult, which can then be reported + # back to you... but I'm getting ahead of myself. To write a test, + # follow these steps: + # + # * Make sure Test::Unit is in your library path. + # * require 'test/unit' in your test script. + # * Create a class that subclasses Test::Unit::TestCase. + # * Add a method that begins with "test" to your class. + # * Make assertions in your test method. + # * Optionally define #setup and/or #teardown to set up and/or tear + # down your common test fixture. + # * You can now run your test as you would any other Ruby + # script... try it and see! + # + # A really simple test might look like this (#setup and #teardown are + # commented out to indicate that they are completely optional): + # + # require 'test/unit' + # + # class TC_MyTest < Test::Unit::TestCase + # # def setup + # # end + # + # # def teardown + # # end + # + # def test_fail + # assert(false, 'Assertion was false.') + # end + # end + # + # + # == Test Runners + # + # So, now you have this great test class, but you still need a way to + # run it and view any failures that occur during the run. This is + # where Test::Unit::UI::Console::TestRunner (and others, such as + # Test::Unit::UI::GTK::TestRunner) comes into play. The console test + # runner is automatically invoked for you if you require 'test/unit' + # and simply run the file. To use another runner, or to manually + # invoke a runner, simply call its run class method and pass in an + # object that responds to the suite message with a + # Test::Unit::TestSuite. This can be as simple as passing in your + # TestCase class (which has a class suite method). It might look + # something like this: + # + # require 'test/unit/ui/console/testrunner' + # Test::Unit::UI::Console::TestRunner.run(TC_MyTest) + # + # + # == Test Suite + # + # As more and more unit tests accumulate for a given project, it + # becomes a real drag running them one at a time, and it also + # introduces the potential to overlook a failing test because you + # forget to run it. Suddenly it becomes very handy that the + # TestRunners can take any object that returns a Test::Unit::TestSuite + # in response to a suite method. The TestSuite can, in turn, contain + # other TestSuites or individual tests (typically created by a + # TestCase). In other words, you can easily wrap up a group of + # TestCases and TestSuites like this: + # + # require 'test/unit/testsuite' + # require 'tc_myfirsttests' + # require 'tc_moretestsbyme' + # require 'ts_anothersetoftests' + # + # class TS_MyTests + # def self.suite + # suite = Test::Unit::TestSuite.new + # suite << TC_MyFirstTests.suite + # suite << TC_MoreTestsByMe.suite + # suite << TS_AnotherSetOfTests.suite + # return suite + # end + # end + # Test::Unit::UI::Console::TestRunner.run(TS_MyTests) + # + # Now, this is a bit cumbersome, so Test::Unit does a little bit more + # for you, by wrapping these up automatically when you require + # 'test/unit'. What does this mean? It means you could write the above + # test case like this instead: + # + # require 'test/unit' + # require 'tc_myfirsttests' + # require 'tc_moretestsbyme' + # require 'ts_anothersetoftests' + # + # Test::Unit is smart enough to find all the test cases existing in + # the ObjectSpace and wrap them up into a suite for you. It then runs + # the dynamic suite using the console TestRunner. + # + # + # == Questions? + # + # I'd really like to get feedback from all levels of Ruby + # practitioners about typos, grammatical errors, unclear statements, + # missing points, etc., in this document (or any other). + # + + module Unit + # If set to false Test::Unit will not automatically run at exit. + def self.run=(flag) + @run = flag + end + + # Automatically run tests at exit? + def self.run? + @run ||= false + end + end +end + +at_exit do + unless $! || Test::Unit.run? + exit Test::Unit::AutoRunner.run + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit/autorunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit/autorunner.rb new file mode 100644 index 00000000..18023d55 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit/autorunner.rb @@ -0,0 +1,217 @@ +require 'test/unit' +require 'test/unit/ui/testrunnerutilities' +require 'optparse' + +module Test + module Unit + class AutoRunner + def self.run(force_standalone=false, default_dir=nil, argv=ARGV, &block) + r = new(force_standalone || standalone?, &block) + r.base = default_dir + r.process_args(argv) + r.run + end + + def self.standalone? + return false unless("-e" == $0) + return TestCase.subclasses.length == 0 + end + + RUNNERS = { + :console => proc do |r| + require 'test/unit/ui/console/testrunner' + Test::Unit::UI::Console::TestRunner + end, + :gtk => proc do |r| + require 'test/unit/ui/gtk/testrunner' + Test::Unit::UI::GTK::TestRunner + end, + :gtk2 => proc do |r| + require 'test/unit/ui/gtk2/testrunner' + Test::Unit::UI::GTK2::TestRunner + end, + :fox => proc do |r| + require 'test/unit/ui/fox/testrunner' + Test::Unit::UI::Fox::TestRunner + end, + :tk => proc do |r| + require 'test/unit/ui/tk/testrunner' + Test::Unit::UI::Tk::TestRunner + end, + } + + OUTPUT_LEVELS = [ + [:silent, UI::SILENT], + [:progress, UI::PROGRESS_ONLY], + [:normal, UI::NORMAL], + [:verbose, UI::VERBOSE], + ] + + COLLECTORS = { + :objectspace => proc do |r| + require 'test/unit/collector/objectspace' + c = Collector::ObjectSpace.new(TestCase.subclasses) + c.filter = r.filters + c.collect($0.sub(/\.rb\Z/, '')) + end, + :dir => proc do |r| + require 'test/unit/collector/dir' + c = Collector::Dir.new + c.filter = r.filters + c.pattern.concat(r.pattern) if(r.pattern) + c.exclude.concat(r.exclude) if(r.exclude) + c.base = r.base + $:.push(r.base) if r.base + c.collect(*(r.to_run.empty? ? ['.'] : r.to_run)) + end, + } + + attr_reader :suite + attr_accessor :output_level, :filters, :to_run, :pattern, :exclude, :base, :workdir + attr_writer :runner, :collector + + def initialize(standalone) + Unit.run = true + @standalone = standalone + @runner = RUNNERS[:console] + @collector = COLLECTORS[(standalone ? :dir : :objectspace)] + @filters = [] + @to_run = [] + @output_level = UI::NORMAL + @workdir = nil + yield(self) if(block_given?) + end + + def process_args(args = ARGV) + begin + options.order!(args) {|arg| @to_run << arg} + rescue OptionParser::ParseError => e + puts e + puts options + $! = nil + abort + else + @filters << proc{false} unless(@filters.empty?) + end + not @to_run.empty? + end + + def options + @options ||= OptionParser.new do |o| + o.banner = "Test::Unit automatic runner." + o.banner << "\nUsage: #{$0} [options] [-- untouched arguments]" + + o.on + o.on('-r', '--runner=RUNNER', RUNNERS, + "Use the given RUNNER.", + "(" + keyword_display(RUNNERS) + ")") do |r| + @runner = r + end + + if(@standalone) + o.on('-b', '--basedir=DIR', "Base directory of test suites.") do |b| + @base = b + end + + o.on('-w', '--workdir=DIR', "Working directory to run tests.") do |w| + @workdir = w + end + + o.on('-a', '--add=TORUN', Array, + "Add TORUN to the list of things to run;", + "can be a file or a directory.") do |a| + @to_run.concat(a) + end + + @pattern = [] + o.on('-p', '--pattern=PATTERN', Regexp, + "Match files to collect against PATTERN.") do |e| + @pattern << e + end + + @exclude = [] + o.on('-x', '--exclude=PATTERN', Regexp, + "Ignore files to collect against PATTERN.") do |e| + @exclude << e + end + end + + o.on('-n', '--name=NAME', String, + "Runs tests matching NAME.", + "(patterns may be used).") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + case n + when Regexp + @filters << proc{|t| n =~ t.method_name ? true : nil} + else + @filters << proc{|t| n == t.method_name ? true : nil} + end + end + + o.on('-t', '--testcase=TESTCASE', String, + "Runs tests in TestCases matching TESTCASE.", + "(patterns may be used).") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + case n + when Regexp + @filters << proc{|t| n =~ t.class.name ? true : nil} + else + @filters << proc{|t| n == t.class.name ? true : nil} + end + end + + o.on('-I', "--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]", + "Appends directory list to $LOAD_PATH.") do |dirs| + $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR)) + end + + o.on('-v', '--verbose=[LEVEL]', OUTPUT_LEVELS, + "Set the output level (default is verbose).", + "(" + keyword_display(OUTPUT_LEVELS) + ")") do |l| + @output_level = l || UI::VERBOSE + end + + o.on('--', + "Stop processing options so that the", + "remaining options will be passed to the", + "test."){o.terminate} + + o.on('-h', '--help', 'Display this help.'){puts o; exit} + + o.on_tail + o.on_tail('Deprecated options:') + + o.on_tail('--console', 'Console runner (use --runner).') do + warn("Deprecated option (--console).") + @runner = RUNNERS[:console] + end + + o.on_tail('--gtk', 'GTK runner (use --runner).') do + warn("Deprecated option (--gtk).") + @runner = RUNNERS[:gtk] + end + + o.on_tail('--fox', 'Fox runner (use --runner).') do + warn("Deprecated option (--fox).") + @runner = RUNNERS[:fox] + end + + o.on_tail + end + end + + def keyword_display(array) + list = array.collect {|e, *| e.to_s} + Array === array or list.sort! + list.collect {|e| e.sub(/^(.)([A-Za-z]+)(?=\w*$)/, '\\1[\\2]')}.join(", ") + end + + def run + @suite = @collector[self] + result = @runner[self] or return false + Dir.chdir(@workdir) if @workdir + result.run(@suite, @output_level).passed? + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit/testcase.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit/testcase.rb new file mode 100644 index 00000000..c388958b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/test/unit/testcase.rb @@ -0,0 +1,162 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertions' +require 'test/unit/failure' +require 'test/unit/error' +require 'test/unit/testsuite' +require 'test/unit/assertionfailederror' +require 'test/unit/util/backtracefilter' +require File.dirname(__FILE__) + '/../../hacks' + +module Test + module Unit + + # Ties everything together. If you subclass and add your own + # test methods, it takes care of making them into tests and + # wrapping those tests into a suite. It also does the + # nitty-gritty of actually running an individual test and + # collecting its results into a Test::Unit::TestResult object. + class TestCase + include Assertions + include Util::BacktraceFilter + + attr_reader :method_name + + STARTED = name + "::STARTED" + FINISHED = name + "::FINISHED" + + ## + # These exceptions are not caught by #run. + + PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt, + SystemExit] + + # Creates a new instance of the fixture for running the + # test represented by test_method_name. + def initialize(test_method_name) + unless(respond_to?(test_method_name) and + (method(test_method_name).arity == 0 || + method(test_method_name).arity == -1)) + throw :invalid_test + end + @method_name = test_method_name + @test_passed = true + end + + # Rolls up all of the test* methods in the fixture into + # one suite, creating a new instance of the fixture for + # each method. + def self.suite + method_names = public_instance_methods(true) + tests = method_names.delete_if {|method_name| method_name !~ /^test./} + suite = TestSuite.new(name) + tests.sort.each do + |test| + catch(:invalid_test) do + suite << new(test) + end + end + if (suite.empty?) + catch(:invalid_test) do + suite << new("default_test") + end + end + return suite + end + + # Runs the individual test method represented by this + # instance of the fixture, collecting statistics, failures + # and errors in result. + def run(result) + yield(STARTED, name) + @_result = result + begin + setup + __send__(@method_name) + rescue AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue Exception + raise if PASSTHROUGH_EXCEPTIONS.include? $!.class + add_error($!) + ensure + begin + teardown + rescue AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue Exception + raise if PASSTHROUGH_EXCEPTIONS.include? $!.class + add_error($!) + end + end + result.add_run + yield(FINISHED, name) + end + + # Called before every test method runs. Can be used + # to set up fixture information. + def setup + end + + # Called after every test method runs. Can be used to tear + # down fixture information. + def teardown + end + + def default_test + flunk("No tests were specified") + end + + # Returns whether this individual test passed or + # not. Primarily for use in teardown so that artifacts + # can be left behind if the test fails. + def passed? + return @test_passed + end + private :passed? + + def size + 1 + end + + def add_assertion + @_result.add_assertion + end + private :add_assertion + + def add_failure(message, all_locations=caller()) + @test_passed = false + @_result.add_failure(Failure.new(name, filter_backtrace(all_locations), message)) + end + private :add_failure + + def add_error(exception) + @test_passed = false + @_result.add_error(Error.new(name, exception)) + end + private :add_error + + # Returns a human-readable name for the specific test that + # this instance of TestCase represents. + def name + "#{@method_name}(#{self.class.name})" + end + + # Overridden to return #name. + def to_s + name + end + + # It's handy to be able to compare TestCase instances. + def ==(other) + return false unless(other.kind_of?(self.class)) + return false unless(@method_name == other.method_name) + self.class == other.class + end + end + TestCase.extend ::SubclassTracking + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/thread.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/thread.rb new file mode 100644 index 00000000..2d2cf25b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/thread.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Threading' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/tmpdir.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/tmpdir.rb new file mode 100644 index 00000000..43ce53ec --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/tmpdir.rb @@ -0,0 +1,38 @@ +# +# tmpdir - retrieve temporary directory path +# +# $Id: tmpdir.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# + +require 'mscorlib' + +class Dir + + begin + @@systmpdir = System::IO::Path.get_temp_path + rescue + @@systmpdir = nil + end + + private + + ## + # Returns the operating system's temporary file path. + + def Dir::tmpdir + tmp = '.' + if $SAFE > 0 and @@systmpdir + tmp = @@systmpdir + else + for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], + ENV['USERPROFILE'], @@systmpdir, '/tmp'] + if dir and File.directory?(dir) and File.writable?(dir) + tmp = dir + break + end + end + end + File.expand_path(tmp) + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/yaml.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/yaml.rb new file mode 100644 index 00000000..facddd6e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/yaml.rb @@ -0,0 +1,18 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +require 'stringio' +require 'date' +load_assembly 'IronRuby.Libraries.Yaml', 'IronRuby.StandardLibrary.Yaml' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/zlib.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/zlib.rb new file mode 100644 index 00000000..e4c84bc2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/IronRuby/zlib.rb @@ -0,0 +1,16 @@ +# **************************************************************************** +# +# Copyright (c) Microsoft Corporation. +# +# This source code is subject to terms and conditions of the Microsoft Public License. A +# copy of the license can be found in the License.html file at the root of this distribution. If +# you cannot locate the Microsoft Public License, please send an email to +# ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound +# by the terms of the Microsoft Public License. +# +# You must not remove this notice, or any other, from this software. +# +# +# **************************************************************************** + +load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Zlib' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/English.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/English.rb new file mode 100644 index 00000000..1a0e11de --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/English.rb @@ -0,0 +1,155 @@ +# Include the English library file in a Ruby script, and you can +# reference the global variables such as \VAR{\$\_} using less +# cryptic names, listed in the following table.% \vref{tab:english}. +# +# Without 'English': +# +# $\ = ' -- ' +# "waterbuffalo" =~ /buff/ +# print $", $', $$, "\n" +# +# With English: +# +# require "English" +# +# $OUTPUT_FIELD_SEPARATOR = ' -- ' +# "waterbuffalo" =~ /buff/ +# print $LOADED_FEATURES, $POSTMATCH, $PID, "\n" + + +# The exception object passed to +raise+. +alias $ERROR_INFO $! + +# The stack backtrace generated by the last +# exception. See Kernel.caller for details. Thread local. +alias $ERROR_POSITION $@ + +# The default separator pattern used by String.split. May be +# set from the command line using the -F flag. +alias $FS $; + +# The default separator pattern used by String.split. May be +# set from the command line using the -F flag. +alias $FIELD_SEPARATOR $; + +# The separator string output between the parameters to methods such +# as Kernel.print and Array.join. Defaults to +nil+, +# which adds no text. +alias $OFS $, + +# The separator string output between the parameters to methods such +# as Kernel.print and Array.join. Defaults to +nil+, +# which adds no text. +alias $OUTPUT_FIELD_SEPARATOR $, + +# The input record separator (newline by default). This is the value +# that routines such as Kernel.gets use to determine record +# boundaries. If set to +nil+, +gets+ will read the entire file. +alias $RS $/ + +# The input record separator (newline by default). This is the value +# that routines such as Kernel.gets use to determine record +# boundaries. If set to +nil+, +gets+ will read the entire file. +alias $INPUT_RECORD_SEPARATOR $/ + +# The string appended to the output of every call to methods such as +# Kernel.print and IO.write. The default value is +# +nil+. +alias $ORS $\ + +# The string appended to the output of every call to methods such as +# Kernel.print and IO.write. The default value is +# +nil+. +alias $OUTPUT_RECORD_SEPARATOR $\ + +# The number of the last line read from the current input file. +alias $INPUT_LINE_NUMBER $. + +# The number of the last line read from the current input file. +alias $NR $. + +# The last line read by Kernel.gets or +# Kernel.readline. Many string-related functions in the +# +Kernel+ module operate on $_ by default. The variable is +# local to the current scope. Thread local. +alias $LAST_READ_LINE $_ + +# The destination of output for Kernel.print +# and Kernel.printf. The default value is +# $stdout. +alias $DEFAULT_OUTPUT $> + +# An object that provides access to the concatenation +# of the contents of all the files +# given as command-line arguments, or $stdin +# (in the case where there are no +# arguments). $< supports methods similar to a +# +File+ object: +# +inmode+, +close+, +# closed?, +each+, +# each_byte, each_line, +# +eof+, eof?, +file+, +# +filename+, +fileno+, +# +getc+, +gets+, +lineno+, +# lineno=, +path+, +# +pos+, pos=, +# +read+, +readchar+, +# +readline+, +readlines+, +# +rewind+, +seek+, +skip+, +# +tell+, to_a, to_i, +# to_io, to_s, along with the +# methods in +Enumerable+. The method +file+ +# returns a +File+ object for the file currently +# being read. This may change as $< reads +# through the files on the command line. Read only. +alias $DEFAULT_INPUT $< + +# The process number of the program being executed. Read only. +alias $PID $$ + +# The process number of the program being executed. Read only. +alias $PROCESS_ID $$ + +# The exit status of the last child process to terminate. Read +# only. Thread local. +alias $CHILD_STATUS $? + +# A +MatchData+ object that encapsulates the results of a successful +# pattern match. The variables $&, $`, $', +# and $1 to $9 are all derived from +# $~. Assigning to $~ changes the values of these +# derived variables. This variable is local to the current +# scope. Thread local. +alias $LAST_MATCH_INFO $~ + +# If set to any value apart from +nil+ or +false+, all pattern matches +# will be case insensitive, string comparisons will ignore case, and +# string hash values will be case insensitive. Deprecated +alias $IGNORECASE $= + +# An array of strings containing the command-line +# options from the invocation of the program. Options +# used by the Ruby interpreter will have been +# removed. Read only. Also known simply as +ARGV+. +alias $ARGV $* + +# The string matched by the last successful pattern +# match. This variable is local to the current +# scope. Read only. Thread local. +alias $MATCH $& + +# The string preceding the match in the last +# successful pattern match. This variable is local to +# the current scope. Read only. Thread local. +alias $PREMATCH $` + +# The string following the match in the last +# successful pattern match. This variable is local to +# the current scope. Read only. Thread local. +alias $POSTMATCH $' + +# The contents of the highest-numbered group matched in the last +# successful pattern match. Thus, in "cat" =~ /(c|a)(t|z)/, +# $+ will be set to "t". This variable is local to the +# current scope. Read only. Thread local. +alias $LAST_PAREN_MATCH $+ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/Env.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/Env.rb new file mode 100644 index 00000000..452a2865 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/Env.rb @@ -0,0 +1,18 @@ +# Env.rb -- imports environment variables as global variables, Perlish ;( +# Usage: +# +# require 'Env' +# p $USER +# $USER = "matz" +# p ENV["USER"] + +require 'importenv' + +if __FILE__ == $0 + p $TERM + $TERM = nil + p $TERM + p ENV["TERM"] + $TERM = "foo" + p ENV["TERM"] +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/abbrev.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/abbrev.rb new file mode 100644 index 00000000..338b89f1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/abbrev.rb @@ -0,0 +1,103 @@ +#!/usr/bin/env ruby +=begin +# +# Copyright (c) 2001,2003 Akinori MUSHA +# +# All rights reserved. You can redistribute and/or modify it under +# the same terms as Ruby. +# +# $Idaemons: /home/cvs/rb/abbrev.rb,v 1.2 2001/05/30 09:37:45 knu Exp $ +# $RoughId: abbrev.rb,v 1.4 2003/10/14 19:45:42 knu Exp $ +# $Id: abbrev.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +# Calculate the set of unique abbreviations for a given set of strings. +# +# require 'abbrev' +# require 'pp' +# +# pp Abbrev::abbrev(['ruby', 'rules']).sort +# +# Generates: +# +# [["rub", "ruby"], +# ["ruby", "ruby"], +# ["rul", "rules"], +# ["rule", "rules"], +# ["rules", "rules"]] +# +# Also adds an +abbrev+ method to class +Array+. + +module Abbrev + + # Given a set of strings, calculate the set of unambiguous + # abbreviations for those strings, and return a hash where the keys + # are all the possible abbreviations and the values are the full + # strings. Thus, given input of "car" and "cone", the keys pointing + # to "car" would be "ca" and "car", while those pointing to "cone" + # would be "co", "con", and "cone". + # + # The optional +pattern+ parameter is a pattern or a string. Only + # those input strings matching the pattern, or begging the string, + # are considered for inclusion in the output hash + + def abbrev(words, pattern = nil) + table = {} + seen = Hash.new(0) + + if pattern.is_a?(String) + pattern = /^#{Regexp.quote(pattern)}/ # regard as a prefix + end + + words.each do |word| + next if (abbrev = word).empty? + while (len = abbrev.rindex(/[\w\W]\z/)) > 0 + abbrev = word[0,len] + + next if pattern && pattern !~ abbrev + + case seen[abbrev] += 1 + when 1 + table[abbrev] = word + when 2 + table.delete(abbrev) + else + break + end + end + end + + words.each do |word| + next if pattern && pattern !~ word + + table[word] = word + end + + table + end + + module_function :abbrev +end + +class Array + # Calculates the set of unambiguous abbreviations for the strings in + # +self+. If passed a pattern or a string, only the strings matching + # the pattern or starting with the string are considered. + # + # %w{ car cone }.abbrev #=> { "ca" => "car", "car" => "car", + # "co" => "cone", "con" => cone", + # "cone" => "cone" } + def abbrev(pattern = nil) + Abbrev::abbrev(self, pattern) + end +end + +if $0 == __FILE__ + while line = gets + hash = line.split.abbrev + + hash.sort.each do |k, v| + puts "#{k} => #{v}" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/base64.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/base64.rb new file mode 100644 index 00000000..8628d611 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/base64.rb @@ -0,0 +1,133 @@ +# +# = base64.rb: methods for base64-encoding and -decoding stings +# +# Author:: Yukihiro Matsumoto +# Documentation:: Dave Thomas and Gavin Sinclair +# +# Until Ruby 1.8.1, these methods were defined at the top-level. Now +# they are in the Base64 module but included in the top-level, where +# their usage is deprecated. +# +# See Base64 for documentation. +# + +require "kconv" + + +# The Base64 module provides for the encoding (#encode64) and decoding +# (#decode64) of binary data using a Base64 representation. +# +# The following particular features are also provided: +# - encode into lines of a given length (#b64encode) +# - decode the special format specified in RFC2047 for the +# representation of email headers (decode_b) +# +# == Example +# +# A simple encoding and decoding. +# +# require "base64" +# +# enc = Base64.encode64('Send reinforcements') +# # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n" +# plain = Base64.decode64(enc) +# # -> "Send reinforcements" +# +# The purpose of using base64 to encode data is that it translates any +# binary data into purely printable characters. It is specified in +# RFC 2045 (http://www.faqs.org/rfcs/rfc2045.html). + +module Base64 + module_function + + # Returns the Base64-decoded version of +str+. + # + # require 'base64' + # str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' + + # 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' + + # 'ZSB0aHJlZQpBbmQgc28gb24uLi4K' + # puts Base64.decode64(str) + # + # Generates: + # + # This is line one + # This is line two + # This is line three + # And so on... + + def decode64(str) + str.unpack("m")[0] + end + + + # Decodes text formatted using a subset of RFC2047 (the one used for + # mime-encoding mail headers). + # + # Only supports an encoding type of 'b' (base 64), and only supports + # the character sets ISO-2022-JP and SHIFT_JIS (so the only two + # encoded word sequences recognized are =?ISO-2022-JP?B?...= and + # =?SHIFT_JIS?B?...=). Recognition of these sequences is case + # insensitive. + + def decode_b(str) + str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) { + decode64($1) + } + str = Kconv::toeuc(str) + str.gsub!(/=\?SHIFT_JIS\?B\?([!->@-~]+)\?=/i) { + decode64($1) + } + str = Kconv::toeuc(str) + str.gsub!(/\n/, ' ') + str.gsub!(/\0/, '') + str + end + + # Returns the Base64-encoded version of +str+. + # + # require 'base64' + # Base64.b64encode("Now is the time for all good coders\nto learn Ruby") + # + # Generates: + # + # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g + # UnVieQ== + + def encode64(bin) + [bin].pack("m") + end + + # _Prints_ the Base64 encoded version of +bin+ (a +String+) in lines of + # +len+ (default 60) characters. + # + # require 'base64' + # data = "Now is the time for all good coders\nto learn Ruby" + # Base64.b64encode(data) + # + # Generates: + # + # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g + # UnVieQ== + + def b64encode(bin, len = 60) + encode64(bin).scan(/.{1,#{len}}/) do + print $&, "\n" + end + end + + + module Deprecated # :nodoc: + include Base64 + + for m in Base64.private_instance_methods(false) + module_eval %{ + def #{m}(*args) + warn("\#{caller(1)[0]}: #{m} is deprecated; use Base64.#{m} instead") + super + end + } + end + end +end + +include Base64::Deprecated diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/benchmark.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/benchmark.rb new file mode 100644 index 00000000..3646ceea --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/benchmark.rb @@ -0,0 +1,572 @@ +=begin +# +# benchmark.rb - a performance benchmarking library +# +# $Id: benchmark.rb 17135 2008-06-13 03:10:19Z shyouhei $ +# +# Created by Gotoken (gotoken@notwork.org). +# +# Documentation by Gotoken (original RD), Lyle Johnson (RDoc conversion), and +# Gavin Sinclair (editing). +# +=end + +# == Overview +# +# The Benchmark module provides methods for benchmarking Ruby code, giving +# detailed reports on the time taken for each task. +# + +# The Benchmark module provides methods to measure and report the time +# used to execute Ruby code. +# +# * Measure the time to construct the string given by the expression +# "a"*1_000_000: +# +# require 'benchmark' +# +# puts Benchmark.measure { "a"*1_000_000 } +# +# On my machine (FreeBSD 3.2 on P5, 100MHz) this generates: +# +# 1.166667 0.050000 1.216667 ( 0.571355) +# +# This report shows the user CPU time, system CPU time, the sum of +# the user and system CPU times, and the elapsed real time. The unit +# of time is seconds. +# +# * Do some experiments sequentially using the #bm method: +# +# require 'benchmark' +# +# n = 50000 +# Benchmark.bm do |x| +# x.report { for i in 1..n; a = "1"; end } +# x.report { n.times do ; a = "1"; end } +# x.report { 1.upto(n) do ; a = "1"; end } +# end +# +# The result: +# +# user system total real +# 1.033333 0.016667 1.016667 ( 0.492106) +# 1.483333 0.000000 1.483333 ( 0.694605) +# 1.516667 0.000000 1.516667 ( 0.711077) +# +# * Continuing the previous example, put a label in each report: +# +# require 'benchmark' +# +# n = 50000 +# Benchmark.bm(7) do |x| +# x.report("for:") { for i in 1..n; a = "1"; end } +# x.report("times:") { n.times do ; a = "1"; end } +# x.report("upto:") { 1.upto(n) do ; a = "1"; end } +# end +# +# The result: +# +# user system total real +# for: 1.050000 0.000000 1.050000 ( 0.503462) +# times: 1.533333 0.016667 1.550000 ( 0.735473) +# upto: 1.500000 0.016667 1.516667 ( 0.711239) +# +# +# * The times for some benchmarks depend on the order in which items +# are run. These differences are due to the cost of memory +# allocation and garbage collection. To avoid these discrepancies, +# the #bmbm method is provided. For example, to compare ways to +# sort an array of floats: +# +# require 'benchmark' +# +# array = (1..1000000).map { rand } +# +# Benchmark.bmbm do |x| +# x.report("sort!") { array.dup.sort! } +# x.report("sort") { array.dup.sort } +# end +# +# The result: +# +# Rehearsal ----------------------------------------- +# sort! 11.928000 0.010000 11.938000 ( 12.756000) +# sort 13.048000 0.020000 13.068000 ( 13.857000) +# ------------------------------- total: 25.006000sec +# +# user system total real +# sort! 12.959000 0.010000 12.969000 ( 13.793000) +# sort 12.007000 0.000000 12.007000 ( 12.791000) +# +# +# * Report statistics of sequential experiments with unique labels, +# using the #benchmark method: +# +# require 'benchmark' +# +# n = 50000 +# Benchmark.benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x| +# tf = x.report("for:") { for i in 1..n; a = "1"; end } +# tt = x.report("times:") { n.times do ; a = "1"; end } +# tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } +# [tf+tt+tu, (tf+tt+tu)/3] +# end +# +# The result: +# +# user system total real +# for: 1.016667 0.016667 1.033333 ( 0.485749) +# times: 1.450000 0.016667 1.466667 ( 0.681367) +# upto: 1.533333 0.000000 1.533333 ( 0.722166) +# >total: 4.000000 0.033333 4.033333 ( 1.889282) +# >avg: 1.333333 0.011111 1.344444 ( 0.629761) + +module Benchmark + + BENCHMARK_VERSION = "2002-04-25" #:nodoc" + + def Benchmark::times() # :nodoc: + Process::times() + end + + + # Invokes the block with a Benchmark::Report object, which + # may be used to collect and report on the results of individual + # benchmark tests. Reserves label_width leading spaces for + # labels on each line. Prints _caption_ at the top of the + # report, and uses _fmt_ to format each line. + # If the block returns an array of + # Benchmark::Tms objects, these will be used to format + # additional lines of output. If _label_ parameters are + # given, these are used to label these extra lines. + # + # _Note_: Other methods provide a simpler interface to this one, and are + # suitable for nearly all benchmarking requirements. See the examples in + # Benchmark, and the #bm and #bmbm methods. + # + # Example: + # + # require 'benchmark' + # include Benchmark # we need the CAPTION and FMTSTR constants + # + # n = 50000 + # Benchmark.benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x| + # tf = x.report("for:") { for i in 1..n; a = "1"; end } + # tt = x.report("times:") { n.times do ; a = "1"; end } + # tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } + # [tf+tt+tu, (tf+tt+tu)/3] + # end + # + # Generates: + # + # user system total real + # for: 1.016667 0.016667 1.033333 ( 0.485749) + # times: 1.450000 0.016667 1.466667 ( 0.681367) + # upto: 1.533333 0.000000 1.533333 ( 0.722166) + # >total: 4.000000 0.033333 4.033333 ( 1.889282) + # >avg: 1.333333 0.011111 1.344444 ( 0.629761) + # + + def benchmark(caption = "", label_width = nil, fmtstr = nil, *labels) # :yield: report + sync = STDOUT.sync + STDOUT.sync = true + label_width ||= 0 + fmtstr ||= FMTSTR + raise ArgumentError, "no block" unless iterator? + print caption + results = yield(Report.new(label_width, fmtstr)) + Array === results and results.grep(Tms).each {|t| + print((labels.shift || t.label || "").ljust(label_width), + t.format(fmtstr)) + } + STDOUT.sync = sync + end + + + # A simple interface to the #benchmark method, #bm is generates sequential reports + # with labels. The parameters have the same meaning as for #benchmark. + # + # require 'benchmark' + # + # n = 50000 + # Benchmark.bm(7) do |x| + # x.report("for:") { for i in 1..n; a = "1"; end } + # x.report("times:") { n.times do ; a = "1"; end } + # x.report("upto:") { 1.upto(n) do ; a = "1"; end } + # end + # + # Generates: + # + # user system total real + # for: 1.050000 0.000000 1.050000 ( 0.503462) + # times: 1.533333 0.016667 1.550000 ( 0.735473) + # upto: 1.500000 0.016667 1.516667 ( 0.711239) + # + + def bm(label_width = 0, *labels, &blk) # :yield: report + benchmark(" "*label_width + CAPTION, label_width, FMTSTR, *labels, &blk) + end + + + # Sometimes benchmark results are skewed because code executed + # earlier encounters different garbage collection overheads than + # that run later. #bmbm attempts to minimize this effect by running + # the tests twice, the first time as a rehearsal in order to get the + # runtime environment stable, the second time for + # real. GC.start is executed before the start of each of + # the real timings; the cost of this is not included in the + # timings. In reality, though, there's only so much that #bmbm can + # do, and the results are not guaranteed to be isolated from garbage + # collection and other effects. + # + # Because #bmbm takes two passes through the tests, it can + # calculate the required label width. + # + # require 'benchmark' + # + # array = (1..1000000).map { rand } + # + # Benchmark.bmbm do |x| + # x.report("sort!") { array.dup.sort! } + # x.report("sort") { array.dup.sort } + # end + # + # Generates: + # + # Rehearsal ----------------------------------------- + # sort! 11.928000 0.010000 11.938000 ( 12.756000) + # sort 13.048000 0.020000 13.068000 ( 13.857000) + # ------------------------------- total: 25.006000sec + # + # user system total real + # sort! 12.959000 0.010000 12.969000 ( 13.793000) + # sort 12.007000 0.000000 12.007000 ( 12.791000) + # + # #bmbm yields a Benchmark::Job object and returns an array of + # Benchmark::Tms objects. + # + def bmbm(width = 0, &blk) # :yield: job + job = Job.new(width) + yield(job) + width = job.width + sync = STDOUT.sync + STDOUT.sync = true + + # rehearsal + print "Rehearsal " + puts '-'*(width+CAPTION.length - "Rehearsal ".length) + list = [] + job.list.each{|label,item| + print(label.ljust(width)) + res = Benchmark::measure(&item) + print res.format() + list.push res + } + sum = Tms.new; list.each{|i| sum += i} + ets = sum.format("total: %tsec") + printf("%s %s\n\n", + "-"*(width+CAPTION.length-ets.length-1), ets) + + # take + print ' '*width, CAPTION + list = [] + ary = [] + job.list.each{|label,item| + GC::start + print label.ljust(width) + res = Benchmark::measure(&item) + print res.format() + ary.push res + list.push [label, res] + } + + STDOUT.sync = sync + ary + end + + # + # Returns the time used to execute the given block as a + # Benchmark::Tms object. + # + def measure(label = "") # :yield: + t0, r0 = Benchmark.times, Time.now + yield + t1, r1 = Benchmark.times, Time.now + Benchmark::Tms.new(t1.utime - t0.utime, + t1.stime - t0.stime, + t1.cutime - t0.cutime, + t1.cstime - t0.cstime, + r1.to_f - r0.to_f, + label) + end + + # + # Returns the elapsed real time used to execute the given block. + # + def realtime(&blk) # :yield: + r0 = Time.now + yield + r1 = Time.now + r1.to_f - r0.to_f + end + + + + # + # A Job is a sequence of labelled blocks to be processed by the + # Benchmark.bmbm method. It is of little direct interest to the user. + # + class Job # :nodoc: + # + # Returns an initialized Job instance. + # Usually, one doesn't call this method directly, as new + # Job objects are created by the #bmbm method. + # _width_ is a initial value for the label offset used in formatting; + # the #bmbm method passes its _width_ argument to this constructor. + # + def initialize(width) + @width = width + @list = [] + end + + # + # Registers the given label and block pair in the job list. + # + def item(label = "", &blk) # :yield: + raise ArgumentError, "no block" unless block_given? + label.concat ' ' + w = label.length + @width = w if @width < w + @list.push [label, blk] + self + end + + alias report item + + # An array of 2-element arrays, consisting of label and block pairs. + attr_reader :list + + # Length of the widest label in the #list, plus one. + attr_reader :width + end + + module_function :benchmark, :measure, :realtime, :bm, :bmbm + + + + # + # This class is used by the Benchmark.benchmark and Benchmark.bm methods. + # It is of little direct interest to the user. + # + class Report # :nodoc: + # + # Returns an initialized Report instance. + # Usually, one doesn't call this method directly, as new + # Report objects are created by the #benchmark and #bm methods. + # _width_ and _fmtstr_ are the label offset and + # format string used by Tms#format. + # + def initialize(width = 0, fmtstr = nil) + @width, @fmtstr = width, fmtstr + end + + # + # Prints the _label_ and measured time for the block, + # formatted by _fmt_. See Tms#format for the + # formatting rules. + # + def item(label = "", *fmt, &blk) # :yield: + print label.ljust(@width) + res = Benchmark::measure(&blk) + print res.format(@fmtstr, *fmt) + res + end + + alias report item + end + + + + # + # A data object, representing the times associated with a benchmark + # measurement. + # + class Tms + CAPTION = " user system total real\n" + FMTSTR = "%10.6u %10.6y %10.6t %10.6r\n" + + # User CPU time + attr_reader :utime + + # System CPU time + attr_reader :stime + + # User CPU time of children + attr_reader :cutime + + # System CPU time of children + attr_reader :cstime + + # Elapsed real time + attr_reader :real + + # Total time, that is _utime_ + _stime_ + _cutime_ + _cstime_ + attr_reader :total + + # Label + attr_reader :label + + # + # Returns an initialized Tms object which has + # _u_ as the user CPU time, _s_ as the system CPU time, + # _cu_ as the children's user CPU time, _cs_ as the children's + # system CPU time, _real_ as the elapsed real time and _l_ + # as the label. + # + def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0, l = nil) + @utime, @stime, @cutime, @cstime, @real, @label = u, s, cu, cs, real, l + @total = @utime + @stime + @cutime + @cstime + end + + # + # Returns a new Tms object whose times are the sum of the times for this + # Tms object, plus the time required to execute the code block (_blk_). + # + def add(&blk) # :yield: + self + Benchmark::measure(&blk) + end + + # + # An in-place version of #add. + # + def add! + t = Benchmark::measure(&blk) + @utime = utime + t.utime + @stime = stime + t.stime + @cutime = cutime + t.cutime + @cstime = cstime + t.cstime + @real = real + t.real + self + end + + # + # Returns a new Tms object obtained by memberwise summation + # of the individual times for this Tms object with those of the other + # Tms object. + # This method and #/() are useful for taking statistics. + # + def +(other); memberwise(:+, other) end + + # + # Returns a new Tms object obtained by memberwise subtraction + # of the individual times for the other Tms object from those of this + # Tms object. + # + def -(other); memberwise(:-, other) end + + # + # Returns a new Tms object obtained by memberwise multiplication + # of the individual times for this Tms object by _x_. + # + def *(x); memberwise(:*, x) end + + # + # Returns a new Tms object obtained by memberwise division + # of the individual times for this Tms object by _x_. + # This method and #+() are useful for taking statistics. + # + def /(x); memberwise(:/, x) end + + # + # Returns the contents of this Tms object as + # a formatted string, according to a format string + # like that passed to Kernel.format. In addition, #format + # accepts the following extensions: + # + # %u:: Replaced by the user CPU time, as reported by Tms#utime. + # %y:: Replaced by the system CPU time, as reported by #stime (Mnemonic: y of "s*y*stem") + # %U:: Replaced by the children's user CPU time, as reported by Tms#cutime + # %Y:: Replaced by the children's system CPU time, as reported by Tms#cstime + # %t:: Replaced by the total CPU time, as reported by Tms#total + # %r:: Replaced by the elapsed real time, as reported by Tms#real + # %n:: Replaced by the label string, as reported by Tms#label (Mnemonic: n of "*n*ame") + # + # If _fmtstr_ is not given, FMTSTR is used as default value, detailing the + # user, system and real elapsed time. + # + def format(arg0 = nil, *args) + fmtstr = (arg0 || FMTSTR).dup + fmtstr.gsub!(/(%[-+\.\d]*)n/){"#{$1}s" % label} + fmtstr.gsub!(/(%[-+\.\d]*)u/){"#{$1}f" % utime} + fmtstr.gsub!(/(%[-+\.\d]*)y/){"#{$1}f" % stime} + fmtstr.gsub!(/(%[-+\.\d]*)U/){"#{$1}f" % cutime} + fmtstr.gsub!(/(%[-+\.\d]*)Y/){"#{$1}f" % cstime} + fmtstr.gsub!(/(%[-+\.\d]*)t/){"#{$1}f" % total} + fmtstr.gsub!(/(%[-+\.\d]*)r/){"(#{$1}f)" % real} + arg0 ? Kernel::format(fmtstr, *args) : fmtstr + end + + # + # Same as #format. + # + def to_s + format + end + + # + # Returns a new 6-element array, consisting of the + # label, user CPU time, system CPU time, children's + # user CPU time, children's system CPU time and elapsed + # real time. + # + def to_a + [@label, @utime, @stime, @cutime, @cstime, @real] + end + + protected + def memberwise(op, x) + case x + when Benchmark::Tms + Benchmark::Tms.new(utime.__send__(op, x.utime), + stime.__send__(op, x.stime), + cutime.__send__(op, x.cutime), + cstime.__send__(op, x.cstime), + real.__send__(op, x.real) + ) + else + Benchmark::Tms.new(utime.__send__(op, x), + stime.__send__(op, x), + cutime.__send__(op, x), + cstime.__send__(op, x), + real.__send__(op, x) + ) + end + end + end + + # The default caption string (heading above the output times). + CAPTION = Benchmark::Tms::CAPTION + + # The default format string used to display times. See also Benchmark::Tms#format. + FMTSTR = Benchmark::Tms::FMTSTR +end + +if __FILE__ == $0 + include Benchmark + + n = ARGV[0].to_i.nonzero? || 50000 + puts %Q([#{n} times iterations of `a = "1"']) + benchmark(" " + CAPTION, 7, FMTSTR) do |x| + x.report("for:") {for i in 1..n; a = "1"; end} # Benchmark::measure + x.report("times:") {n.times do ; a = "1"; end} + x.report("upto:") {1.upto(n) do ; a = "1"; end} + end + + benchmark do + [ + measure{for i in 1..n; a = "1"; end}, # Benchmark::measure + measure{n.times do ; a = "1"; end}, + measure{1.upto(n) do ; a = "1"; end} + ] + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/jacobian.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/jacobian.rb new file mode 100644 index 00000000..d80eeab9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/jacobian.rb @@ -0,0 +1,85 @@ +# +# require 'bigdecimal/jacobian' +# +# Provides methods to compute the Jacobian matrix of a set of equations at a +# point x. In the methods below: +# +# f is an Object which is used to compute the Jacobian matrix of the equations. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 1.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# x is the point at which to compute the Jacobian. +# +# fx is f.values(x). +# +module Jacobian + #-- + def isEqual(a,b,zero=0.0,e=1.0e-8) + aa = a.abs + bb = b.abs + if aa == zero && bb == zero then + true + else + if ((a-b)/(aa+bb)).abs < e then + true + else + false + end + end + end + #++ + + # Computes the derivative of f[i] at x[i]. + # fx is the value of f at x. + def dfdxi(f,fx,x,i) + nRetry = 0 + n = x.size + xSave = x[i] + ok = 0 + ratio = f.ten*f.ten*f.ten + dx = x[i].abs/ratio + dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps) + dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps) + until ok>0 do + s = f.zero + deriv = [] + if(nRetry>100) then + raize "Singular Jacobian matrix. No change at x[" + i.to_s + "]" + end + dx = dx*f.two + x[i] += dx + fxNew = f.values(x) + for j in 0...n do + if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then + ok += 1 + deriv <<= (fxNew[j]-fx[j])/dx + else + deriv <<= f.zero + end + end + x[i] = xSave + end + deriv + end + + # Computes the Jacobian of f at x. fx is the value of f at x. + def jacobian(f,fx,x) + n = x.size + dfdx = Array::new(n*n) + for i in 0...n do + df = dfdxi(f,fx,x,i) + for j in 0...n do + dfdx[j*n+i] = df[j] + end + end + dfdx + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/ludcmp.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/ludcmp.rb new file mode 100644 index 00000000..8f488872 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/ludcmp.rb @@ -0,0 +1,84 @@ +# +# Solves a*x = b for x, using LU decomposition. +# +module LUSolve + # Performs LU decomposition of the n by n matrix a. + def ludecomp(a,n,zero=0,one=1) + prec = BigDecimal.limit(nil) + ps = [] + scales = [] + for i in 0...n do # pick up largest(abs. val.) element in each row. + ps <<= i + nrmrow = zero + ixn = i*n + for j in 0...n do + biggst = a[ixn+j].abs + nrmrow = biggst if biggst>nrmrow + end + if nrmrow>zero then + scales <<= one.div(nrmrow,prec) + else + raise "Singular matrix" + end + end + n1 = n - 1 + for k in 0...n1 do # Gaussian elimination with partial pivoting. + biggst = zero; + for i in k...n do + size = a[ps[i]*n+k].abs*scales[ps[i]] + if size>biggst then + biggst = size + pividx = i + end + end + raise "Singular matrix" if biggst<=zero + if pividx!=k then + j = ps[k] + ps[k] = ps[pividx] + ps[pividx] = j + end + pivot = a[ps[k]*n+k] + for i in (k+1)...n do + psin = ps[i]*n + a[psin+k] = mult = a[psin+k].div(pivot,prec) + if mult!=zero then + pskn = ps[k]*n + for j in (k+1)...n do + a[psin+j] -= mult.mult(a[pskn+j],prec) + end + end + end + end + raise "Singular matrix" if a[ps[n1]*n+n1] == zero + ps + end + + # Solves a*x = b for x, using LU decomposition. + # + # a is a matrix, b is a constant vector, x is the solution vector. + # + # ps is the pivot, a vector which indicates the permutation of rows performed + # during LU decomposition. + def lusolve(a,b,ps,zero=0.0) + prec = BigDecimal.limit(nil) + n = ps.size + x = [] + for i in 0...n do + dot = zero + psin = ps[i]*n + for j in 0...i do + dot = a[psin+j].mult(x[j],prec) + dot + end + x <<= b[ps[i]] - dot + end + (n-1).downto(0) do |i| + dot = zero + psin = ps[i]*n + for j in (i+1)...n do + dot = a[psin+j].mult(x[j],prec) + dot + end + x[i] = (x[i]-dot).div(a[psin+i],prec) + end + x + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/math.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/math.rb new file mode 100644 index 00000000..f3248a3c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/math.rb @@ -0,0 +1,235 @@ +# +#-- +# Contents: +# sqrt(x, prec) +# sin (x, prec) +# cos (x, prec) +# atan(x, prec) Note: |x|<1, x=0.9999 may not converge. +# exp (x, prec) +# log (x, prec) +# PI (prec) +# E (prec) == exp(1.0,prec) +# +# where: +# x ... BigDecimal number to be computed. +# |x| must be small enough to get convergence. +# prec ... Number of digits to be obtained. +#++ +# +# Provides mathematical functions. +# +# Example: +# +# require "bigdecimal" +# require "bigdecimal/math" +# +# include BigMath +# +# a = BigDecimal((PI(100)/2).to_s) +# puts sin(a,100) # -> 0.10000000000000000000......E1 +# +module BigMath + + # Computes the square root of x to the specified number of digits of + # precision. + # + # BigDecimal.new('2').sqrt(16).to_s + # -> "0.14142135623730950488016887242096975E1" + # + def sqrt(x,prec) + x.sqrt(prec) + end + + # Computes the sine of x to the specified number of digits of precision. + # + # If x is infinite or NaN, returns NaN. + def sin(x, prec) + raise ArgumentError, "Zero or negative precision for sin" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + x1 = x + x2 = x.mult(x,n) + sign = 1 + y = x + d = y + i = one + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + sign = -sign + x1 = x2.mult(x1,n) + i += two + z *= (i-one) * i + d = sign * x1.div(z,m) + y += d + end + y + end + + # Computes the cosine of x to the specified number of digits of precision. + # + # If x is infinite or NaN, returns NaN. + def cos(x, prec) + raise ArgumentError, "Zero or negative precision for cos" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + x1 = one + x2 = x.mult(x,n) + sign = 1 + y = one + d = y + i = BigDecimal("0") + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + sign = -sign + x1 = x2.mult(x1,n) + i += two + z *= (i-one) * i + d = sign * x1.div(z,m) + y += d + end + y + end + + # Computes the arctangent of x to the specified number of digits of precision. + # + # If x is infinite or NaN, returns NaN. + # Raises an argument error if x > 1. + def atan(x, prec) + raise ArgumentError, "Zero or negative precision for atan" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + raise ArgumentError, "x.abs must be less than 1.0" if x.abs>=1 + n = prec + BigDecimal.double_fig + y = x + d = y + t = x + r = BigDecimal("3") + x2 = x.mult(x,n) + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = -t.mult(x2,n) + d = t.div(r,m) + y += d + r += 2 + end + y + end + + # Computes the value of e (the base of natural logarithms) raised to the + # power of x, to the specified number of digits of precision. + # + # If x is infinite or NaN, returns NaN. + # + # BigMath::exp(BigDecimal.new('1'), 10).to_s + # -> "0.271828182845904523536028752390026306410273E1" + def exp(x, prec) + raise ArgumentError, "Zero or negative precision for exp" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + x1 = one + y = one + d = y + z = one + i = 0 + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + x1 = x1.mult(x,n) + i += 1 + z *= i + d = x1.div(z,m) + y += d + end + y + end + + # Computes the natural logarithm of x to the specified number of digits + # of precision. + # + # Returns x if x is infinite or NaN. + # + def log(x, prec) + raise ArgumentError, "Zero or negative argument for log" if x <= 0 || prec <= 0 + return x if x.infinite? || x.nan? + one = BigDecimal("1") + two = BigDecimal("2") + n = prec + BigDecimal.double_fig + x = (x - one).div(x + one,n) + x2 = x.mult(x,n) + y = x + d = y + i = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + x = x2.mult(x,n) + i += two + d = x.div(i,m) + y += d + end + y*two + end + + # Computes the value of pi to the specified number of digits of precision. + def PI(prec) + raise ArgumentError, "Zero or negative argument for PI" if prec <= 0 + n = prec + BigDecimal.double_fig + zero = BigDecimal("0") + one = BigDecimal("1") + two = BigDecimal("2") + + m25 = BigDecimal("-0.04") + m57121 = BigDecimal("-57121") + + pi = zero + + d = one + k = one + w = one + t = BigDecimal("-80") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t*m25 + d = t.div(k,m) + k = k+two + pi = pi + d + end + + d = one + k = one + w = one + t = BigDecimal("956") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t.div(m57121,n) + d = t.div(k,m) + pi = pi + d + k = k+two + end + pi + end + + # Computes e (the base of natural logarithms) to the specified number of + # digits of precision. + def E(prec) + raise ArgumentError, "Zero or negative precision for E" if prec <= 0 + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + y = one + d = y + z = one + i = 0 + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + i += 1 + z *= i + d = one.div(z,m) + y += d + end + y + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/newton.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/newton.rb new file mode 100644 index 00000000..59ac0f7f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/newton.rb @@ -0,0 +1,77 @@ +# +# newton.rb +# +# Solves the nonlinear algebraic equation system f = 0 by Newton's method. +# This program is not dependent on BigDecimal. +# +# To call: +# n = nlsolve(f,x) +# where n is the number of iterations required, +# x is the initial value vector +# f is an Object which is used to compute the values of the equations to be solved. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 1.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# On exit, x is the solution vector. +# +require "bigdecimal/ludcmp" +require "bigdecimal/jacobian" + +module Newton + include LUSolve + include Jacobian + + def norm(fv,zero=0.0) + s = zero + n = fv.size + for i in 0...n do + s += fv[i]*fv[i] + end + s + end + + def nlsolve(f,x) + nRetry = 0 + n = x.size + + f0 = f.values(x) + zero = f.zero + one = f.one + two = f.two + p5 = one/two + d = norm(f0,zero) + minfact = f.ten*f.ten*f.ten + minfact = one/minfact + e = f.eps + while d >= e do + nRetry += 1 + # Not yet converged. => Compute Jacobian matrix + dfdx = jacobian(f,f0,x) + # Solve dfdx*dx = -f0 to estimate dx + dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) + fact = two + xs = x.dup + begin + fact *= p5 + if fact < minfact then + raise "Failed to reduce function values." + end + for i in 0...n do + x[i] = xs[i] - dx[i]*fact + end + f0 = f.values(x) + dn = norm(f0,zero) + end while(dn>=d) + d = dn + end + nRetry + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/util.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/util.rb new file mode 100644 index 00000000..09e926ac --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/bigdecimal/util.rb @@ -0,0 +1,65 @@ +# +# BigDecimal utility library. +# +# To use these functions, require 'bigdecimal/util' +# +# The following methods are provided to convert other types to BigDecimals: +# +# String#to_d -> BigDecimal +# Float#to_d -> BigDecimal +# Rational#to_d -> BigDecimal +# +# The following method is provided to convert BigDecimals to other types: +# +# BigDecimal#to_r -> Rational +# +# ---------------------------------------------------------------------- +# +class Float < Numeric + def to_d + BigDecimal(self.to_s) + end +end + +class String + def to_d + BigDecimal(self) + end +end + +class BigDecimal < Numeric + # Converts a BigDecimal to a String of the form "nnnnnn.mmm". + # This method is deprecated; use BigDecimal#to_s("F") instead. + def to_digits + if self.nan? || self.infinite? || self.zero? + self.to_s + else + i = self.to_i.to_s + s,f,y,z = self.frac.split + i + "." + ("0"*(-z)) + f + end + end + + # Converts a BigDecimal to a Rational. + def to_r + sign,digits,base,power = self.split + numerator = sign*digits.to_i + denomi_power = power - digits.size # base is always 10 + if denomi_power < 0 + Rational(numerator,base ** (-denomi_power)) + else + Rational(numerator * (base ** denomi_power),1) + end + end +end + +class Rational < Numeric + # Converts a Rational to a BigDecimal + def to_d(nFig=0) + num = self.numerator.to_s + if nFig<=0 + nFig = BigDecimal.double_fig*2+1 + end + BigDecimal.new(num).div(self.denominator,nFig) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi-lib.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi-lib.rb new file mode 100644 index 00000000..d6b60d66 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi-lib.rb @@ -0,0 +1,272 @@ +warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: cgi-lib is deprecated after Ruby 1.8.1; use cgi instead" + +=begin + += simple CGI support library + += example + +== get form values + + require "cgi-lib.rb" + query = CGI.new + query['field'] # <== value of 'field' + query.keys # <== array of fields + +and query has Hash class methods + + +== get cookie values + + require "cgi-lib.rb" + query = CGI.new + query.cookie['name'] # <== cookie value of 'name' + query.cookie.keys # <== all cookie names + +and query.cookie has Hash class methods + + +== print HTTP header and HTML string to $> + + require "cgi-lib.rb" + CGI::print{ + CGI::tag("HTML"){ + CGI::tag("HEAD"){ CGI::tag("TITLE"){"TITLE"} } + + CGI::tag("BODY"){ + CGI::tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){ + CGI::tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"}) + } + + CGI::tag("HR") + } + } + } + + +== make raw cookie string + + require "cgi-lib.rb" + cookie1 = CGI::cookie({'name' => 'name', + 'value' => 'value', + 'path' => 'path', # optional + 'domain' => 'domain', # optional + 'expires' => Time.now, # optional + 'secure' => true # optional + }) + + CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" } + + +== print HTTP header and string to $> + + require "cgi-lib.rb" + CGI::print{ "string" } + # == CGI::print("Content-Type: text/html"){ "string" } + CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" } + + +=== NPH (no-parse-header) mode + + require "cgi-lib.rb" + CGI::print("nph"){ "string" } + # == CGI::print("nph", "Content-Type: text/html"){ "string" } + CGI::print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" } + + +== make HTML tag string + + require "cgi-lib.rb" + CGI::tag("element", {"attribute_name"=>"attribute_value"}){"content"} + + +== make HTTP header string + + require "cgi-lib.rb" + CGI::header # == CGI::header("Content-Type: text/html") + CGI::header("Content-Type: text/html", cookie1, cookie2) + + +=== NPH (no-parse-header) mode + + CGI::header("nph") # == CGI::header("nph", "Content-Type: text/html") + CGI::header("nph", "Content-Type: text/html", cookie1, cookie2) + + +== escape url encode + + require "cgi-lib.rb" + url_encoded_string = CGI::escape("string") + + +== unescape url encoded + + require "cgi-lib.rb" + string = CGI::unescape("url encoded string") + + +== escape HTML &"<> + + require "cgi-lib.rb" + CGI::escapeHTML("string") + + +=end + +require "delegate" + +class CGI < SimpleDelegator + + CR = "\015" + LF = "\012" + EOL = CR + LF + + RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ] + RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ] + + # make rfc1123 date string + def CGI::rfc1123_date(time) + t = time.clone.gmtime + return format("%s, %.2d %s %d %.2d:%.2d:%.2d GMT", + RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year, + t.hour, t.min, t.sec) + end + + # escape url encode + def CGI::escape(str) + str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) } + end + + # unescape url encoded + def CGI::unescape(str) + str.gsub(/\+/, ' ').gsub(/%([0-9a-fA-F]{2})/){ [$1.hex].pack("c") } + end + + # escape HTML + def CGI::escapeHTML(str) + str.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/" + + (iterator? ? yield.to_s + "" : "") + end + + # make raw cookie string + def CGI::cookie(options) + "Set-Cookie: " + options['name'] + '=' + escape(options['value']) + + (options['domain'] ? '; domain=' + options['domain'] : '') + + (options['path'] ? '; path=' + options['path'] : '') + + (options['expires'] ? '; expires=' + rfc1123_date(options['expires']) : '') + + (options['secure'] ? '; secure' : '') + end + + # make HTTP header string + def CGI::header(*options) + if defined?(MOD_RUBY) + options.each{|option| + option.sub(/(.*?): (.*)/){ + Apache::request.headers_out[$1] = $2 + } + } + Apache::request.send_http_header + '' + else + if options.delete("nph") or (ENV['SERVER_SOFTWARE'] =~ /IIS/) + [(ENV['SERVER_PROTOCOL'] or "HTTP/1.0") + " 200 OK", + "Date: " + rfc1123_date(Time.now), + "Server: " + (ENV['SERVER_SOFTWARE'] or ""), + "Connection: close"] + + (options.empty? ? ["Content-Type: text/html"] : options) + else + options.empty? ? ["Content-Type: text/html"] : options + end.join(EOL) + EOL + EOL + end + end + + # print HTTP header and string to $> + def CGI::print(*options) + $>.print CGI::header(*options) + yield.to_s + end + + # print message to $> + def CGI::message(message, title = "", header = ["Content-Type: text/html"]) + if message.kind_of?(Hash) + title = message['title'] + header = message['header'] + message = message['body'] + end + CGI::print(*header){ + CGI::tag("HTML"){ + CGI::tag("HEAD"){ CGI.tag("TITLE"){ title } } + + CGI::tag("BODY"){ message } + } + } + true + end + + # print error message to $> and exit + def CGI::error + CGI::message({'title'=>'ERROR', 'body'=> + CGI::tag("PRE"){ + "ERROR: " + CGI::tag("STRONG"){ escapeHTML($!.to_s) } + "\n" + escapeHTML($@.join("\n")) + } + }) + exit + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi.rb new file mode 100644 index 00000000..d6a1d111 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi.rb @@ -0,0 +1,2303 @@ +# +# cgi.rb - cgi support library +# +# Copyright (C) 2000 Network Applied Communication Laboratory, Inc. +# +# Copyright (C) 2000 Information-technology Promotion Agency, Japan +# +# Author: Wakou Aoyama +# +# Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber) +# +# == Overview +# +# The Common Gateway Interface (CGI) is a simple protocol +# for passing an HTTP request from a web server to a +# standalone program, and returning the output to the web +# browser. Basically, a CGI program is called with the +# parameters of the request passed in either in the +# environment (GET) or via $stdin (POST), and everything +# it prints to $stdout is returned to the client. +# +# This file holds the +CGI+ class. This class provides +# functionality for retrieving HTTP request parameters, +# managing cookies, and generating HTML output. See the +# class documentation for more details and examples of use. +# +# The file cgi/session.rb provides session management +# functionality; see that file for more details. +# +# See http://www.w3.org/CGI/ for more information on the CGI +# protocol. + +raise "Please, use ruby 1.5.4 or later." if RUBY_VERSION < "1.5.4" + +require 'English' + +# CGI class. See documentation for the file cgi.rb for an overview +# of the CGI protocol. +# +# == Introduction +# +# CGI is a large class, providing several categories of methods, many of which +# are mixed in from other modules. Some of the documentation is in this class, +# some in the modules CGI::QueryExtension and CGI::HtmlExtension. See +# CGI::Cookie for specific information on handling cookies, and cgi/session.rb +# (CGI::Session) for information on sessions. +# +# For queries, CGI provides methods to get at environmental variables, +# parameters, cookies, and multipart request data. For responses, CGI provides +# methods for writing output and generating HTML. +# +# Read on for more details. Examples are provided at the bottom. +# +# == Queries +# +# The CGI class dynamically mixes in parameter and cookie-parsing +# functionality, environmental variable access, and support for +# parsing multipart requests (including uploaded files) from the +# CGI::QueryExtension module. +# +# === Environmental Variables +# +# The standard CGI environmental variables are available as read-only +# attributes of a CGI object. The following is a list of these variables: +# +# +# AUTH_TYPE HTTP_HOST REMOTE_IDENT +# CONTENT_LENGTH HTTP_NEGOTIATE REMOTE_USER +# CONTENT_TYPE HTTP_PRAGMA REQUEST_METHOD +# GATEWAY_INTERFACE HTTP_REFERER SCRIPT_NAME +# HTTP_ACCEPT HTTP_USER_AGENT SERVER_NAME +# HTTP_ACCEPT_CHARSET PATH_INFO SERVER_PORT +# HTTP_ACCEPT_ENCODING PATH_TRANSLATED SERVER_PROTOCOL +# HTTP_ACCEPT_LANGUAGE QUERY_STRING SERVER_SOFTWARE +# HTTP_CACHE_CONTROL REMOTE_ADDR +# HTTP_FROM REMOTE_HOST +# +# +# For each of these variables, there is a corresponding attribute with the +# same name, except all lower case and without a preceding HTTP_. +# +content_length+ and +server_port+ are integers; the rest are strings. +# +# === Parameters +# +# The method #params() returns a hash of all parameters in the request as +# name/value-list pairs, where the value-list is an Array of one or more +# values. The CGI object itself also behaves as a hash of parameter names +# to values, but only returns a single value (as a String) for each +# parameter name. +# +# For instance, suppose the request contains the parameter +# "favourite_colours" with the multiple values "blue" and "green". The +# following behaviour would occur: +# +# cgi.params["favourite_colours"] # => ["blue", "green"] +# cgi["favourite_colours"] # => "blue" +# +# If a parameter does not exist, the former method will return an empty +# array, the latter an empty string. The simplest way to test for existence +# of a parameter is by the #has_key? method. +# +# === Cookies +# +# HTTP Cookies are automatically parsed from the request. They are available +# from the #cookies() accessor, which returns a hash from cookie name to +# CGI::Cookie object. +# +# === Multipart requests +# +# If a request's method is POST and its content type is multipart/form-data, +# then it may contain uploaded files. These are stored by the QueryExtension +# module in the parameters of the request. The parameter name is the name +# attribute of the file input field, as usual. However, the value is not +# a string, but an IO object, either an IOString for small files, or a +# Tempfile for larger ones. This object also has the additional singleton +# methods: +# +# #local_path():: the path of the uploaded file on the local filesystem +# #original_filename():: the name of the file on the client computer +# #content_type():: the content type of the file +# +# == Responses +# +# The CGI class provides methods for sending header and content output to +# the HTTP client, and mixes in methods for programmatic HTML generation +# from CGI::HtmlExtension and CGI::TagMaker modules. The precise version of HTML +# to use for HTML generation is specified at object creation time. +# +# === Writing output +# +# The simplest way to send output to the HTTP client is using the #out() method. +# This takes the HTTP headers as a hash parameter, and the body content +# via a block. The headers can be generated as a string using the #header() +# method. The output stream can be written directly to using the #print() +# method. +# +# === Generating HTML +# +# Each HTML element has a corresponding method for generating that +# element as a String. The name of this method is the same as that +# of the element, all lowercase. The attributes of the element are +# passed in as a hash, and the body as a no-argument block that evaluates +# to a String. The HTML generation module knows which elements are +# always empty, and silently drops any passed-in body. It also knows +# which elements require matching closing tags and which don't. However, +# it does not know what attributes are legal for which elements. +# +# There are also some additional HTML generation methods mixed in from +# the CGI::HtmlExtension module. These include individual methods for the +# different types of form inputs, and methods for elements that commonly +# take particular attributes where the attributes can be directly specified +# as arguments, rather than via a hash. +# +# == Examples of use +# +# === Get form values +# +# require "cgi" +# cgi = CGI.new +# value = cgi['field_name'] # <== value string for 'field_name' +# # if not 'field_name' included, then return "". +# fields = cgi.keys # <== array of field names +# +# # returns true if form has 'field_name' +# cgi.has_key?('field_name') +# cgi.has_key?('field_name') +# cgi.include?('field_name') +# +# CAUTION! cgi['field_name'] returned an Array with the old +# cgi.rb(included in ruby 1.6) +# +# === Get form values as hash +# +# require "cgi" +# cgi = CGI.new +# params = cgi.params +# +# cgi.params is a hash. +# +# cgi.params['new_field_name'] = ["value"] # add new param +# cgi.params['field_name'] = ["new_value"] # change value +# cgi.params.delete('field_name') # delete param +# cgi.params.clear # delete all params +# +# +# === Save form values to file +# +# require "pstore" +# db = PStore.new("query.db") +# db.transaction do +# db["params"] = cgi.params +# end +# +# +# === Restore form values from file +# +# require "pstore" +# db = PStore.new("query.db") +# db.transaction do +# cgi.params = db["params"] +# end +# +# +# === Get multipart form values +# +# require "cgi" +# cgi = CGI.new +# value = cgi['field_name'] # <== value string for 'field_name' +# value.read # <== body of value +# value.local_path # <== path to local file of value +# value.original_filename # <== original filename of value +# value.content_type # <== content_type of value +# +# and value has StringIO or Tempfile class methods. +# +# === Get cookie values +# +# require "cgi" +# cgi = CGI.new +# values = cgi.cookies['name'] # <== array of 'name' +# # if not 'name' included, then return []. +# names = cgi.cookies.keys # <== array of cookie names +# +# and cgi.cookies is a hash. +# +# === Get cookie objects +# +# require "cgi" +# cgi = CGI.new +# for name, cookie in cgi.cookies +# cookie.expires = Time.now + 30 +# end +# cgi.out("cookie" => cgi.cookies) {"string"} +# +# cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... } +# +# require "cgi" +# cgi = CGI.new +# cgi.cookies['name'].expires = Time.now + 30 +# cgi.out("cookie" => cgi.cookies['name']) {"string"} +# +# === Print http header and html string to $DEFAULT_OUTPUT ($>) +# +# require "cgi" +# cgi = CGI.new("html3") # add HTML generation methods +# cgi.out() do +# cgi.html() do +# cgi.head{ cgi.title{"TITLE"} } + +# cgi.body() do +# cgi.form() do +# cgi.textarea("get_text") + +# cgi.br + +# cgi.submit +# end + +# cgi.pre() do +# CGI::escapeHTML( +# "params: " + cgi.params.inspect + "\n" + +# "cookies: " + cgi.cookies.inspect + "\n" + +# ENV.collect() do |key, value| +# key + " --> " + value + "\n" +# end.join("") +# ) +# end +# end +# end +# end +# +# # add HTML generation methods +# CGI.new("html3") # html3.2 +# CGI.new("html4") # html4.01 (Strict) +# CGI.new("html4Tr") # html4.01 Transitional +# CGI.new("html4Fr") # html4.01 Frameset +# +class CGI + + # :stopdoc: + + # String for carriage return + CR = "\015" + + # String for linefeed + LF = "\012" + + # Standard internet newline sequence + EOL = CR + LF + + REVISION = '$Id: cgi.rb 17815 2008-07-02 10:06:15Z shyouhei $' #:nodoc: + + NEEDS_BINMODE = true if /WIN/ni.match(RUBY_PLATFORM) + + # Path separators in different environments. + PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'} + + # HTTP status codes. + HTTP_STATUS = { + "OK" => "200 OK", + "PARTIAL_CONTENT" => "206 Partial Content", + "MULTIPLE_CHOICES" => "300 Multiple Choices", + "MOVED" => "301 Moved Permanently", + "REDIRECT" => "302 Found", + "NOT_MODIFIED" => "304 Not Modified", + "BAD_REQUEST" => "400 Bad Request", + "AUTH_REQUIRED" => "401 Authorization Required", + "FORBIDDEN" => "403 Forbidden", + "NOT_FOUND" => "404 Not Found", + "METHOD_NOT_ALLOWED" => "405 Method Not Allowed", + "NOT_ACCEPTABLE" => "406 Not Acceptable", + "LENGTH_REQUIRED" => "411 Length Required", + "PRECONDITION_FAILED" => "412 Rrecondition Failed", + "SERVER_ERROR" => "500 Internal Server Error", + "NOT_IMPLEMENTED" => "501 Method Not Implemented", + "BAD_GATEWAY" => "502 Bad Gateway", + "VARIANT_ALSO_VARIES" => "506 Variant Also Negotiates" + } + + # Abbreviated day-of-week names specified by RFC 822 + RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ] + + # Abbreviated month names specified by RFC 822 + RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ] + + # :startdoc: + + def env_table + ENV + end + + def stdinput + $stdin + end + + def stdoutput + $DEFAULT_OUTPUT + end + + private :env_table, :stdinput, :stdoutput + + # URL-encode a string. + # url_encoded_string = CGI::escape("'Stop!' said Fred") + # # => "%27Stop%21%27+said+Fred" + def CGI::escape(string) + string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do + '%' + $1.unpack('H2' * $1.size).join('%').upcase + end.tr(' ', '+') + end + + + # URL-decode a string. + # string = CGI::unescape("%27Stop%21%27+said+Fred") + # # => "'Stop!' said Fred" + def CGI::unescape(string) + string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do + [$1.delete('%')].pack('H*') + end + end + + + # Escape special characters in HTML, namely &\"<> + # CGI::escapeHTML('Usage: foo "bar" ') + # # => "Usage: foo "bar" <baz>" + def CGI::escapeHTML(string) + string.gsub(/&/n, '&').gsub(/\"/n, '"').gsub(/>/n, '>').gsub(/ "Usage: foo \"bar\" " + def CGI::unescapeHTML(string) + string.gsub(/&(amp|quot|gt|lt|\#[0-9]+|\#x[0-9A-Fa-f]+);/n) do + match = $1.dup + case match + when 'amp' then '&' + when 'quot' then '"' + when 'gt' then '>' + when 'lt' then '<' + when /\A#0*(\d+)\z/n then + if Integer($1) < 256 + Integer($1).chr + else + if Integer($1) < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U) + [Integer($1)].pack("U") + else + "&##{$1};" + end + end + when /\A#x([0-9a-f]+)\z/ni then + if $1.hex < 256 + $1.hex.chr + else + if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U) + [$1.hex].pack("U") + else + "&#x#{$1};" + end + end + else + "&#{match};" + end + end + end + + + # Escape only the tags of certain HTML elements in +string+. + # + # Takes an element or elements or array of elements. Each element + # is specified by the name of the element, without angle brackets. + # This matches both the start and the end tag of that element. + # The attribute list of the open tag will also be escaped (for + # instance, the double-quotes surrounding attribute values). + # + # print CGI::escapeElement('
', "A", "IMG") + # # "
<A HREF="url"></A>" + # + # print CGI::escapeElement('
', ["A", "IMG"]) + # # "
<A HREF="url"></A>" + def CGI::escapeElement(string, *elements) + elements = elements[0] if elements[0].kind_of?(Array) + unless elements.empty? + string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do + CGI::escapeHTML($&) + end + else + string + end + end + + + # Undo escaping such as that done by CGI::escapeElement() + # + # print CGI::unescapeElement( + # CGI::escapeHTML('
'), "A", "IMG") + # # "<BR>" + # + # print CGI::unescapeElement( + # CGI::escapeHTML('
'), ["A", "IMG"]) + # # "<BR>" + def CGI::unescapeElement(string, *elements) + elements = elements[0] if elements[0].kind_of?(Array) + unless elements.empty? + string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do + CGI::unescapeHTML($&) + end + else + string + end + end + + + # Format a +Time+ object as a String using the format specified by RFC 1123. + # + # CGI::rfc1123_date(Time.now) + # # Sat, 01 Jan 2000 00:00:00 GMT + def CGI::rfc1123_date(time) + t = time.clone.gmtime + return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT", + RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year, + t.hour, t.min, t.sec) + end + + + # Create an HTTP header block as a string. + # + # Includes the empty line that ends the header block. + # + # +options+ can be a string specifying the Content-Type (defaults + # to text/html), or a hash of header key/value pairs. The following + # header keys are recognized: + # + # type:: the Content-Type header. Defaults to "text/html" + # charset:: the charset of the body, appended to the Content-Type header. + # nph:: a boolean value. If true, prepend protocol string and status code, and + # date; and sets default values for "server" and "connection" if not + # explicitly set. + # status:: the HTTP status code, returned as the Status header. See the + # list of available status codes below. + # server:: the server software, returned as the Server header. + # connection:: the connection type, returned as the Connection header (for + # instance, "close". + # length:: the length of the content that will be sent, returned as the + # Content-Length header. + # language:: the language of the content, returned as the Content-Language + # header. + # expires:: the time on which the current content expires, as a +Time+ + # object, returned as the Expires header. + # cookie:: a cookie or cookies, returned as one or more Set-Cookie headers. + # The value can be the literal string of the cookie; a CGI::Cookie + # object; an Array of literal cookie strings or Cookie objects; or a + # hash all of whose values are literal cookie strings or Cookie objects. + # These cookies are in addition to the cookies held in the + # @output_cookies field. + # + # Other header lines can also be set; they are appended as key: value. + # + # header + # # Content-Type: text/html + # + # header("text/plain") + # # Content-Type: text/plain + # + # header("nph" => true, + # "status" => "OK", # == "200 OK" + # # "status" => "200 GOOD", + # "server" => ENV['SERVER_SOFTWARE'], + # "connection" => "close", + # "type" => "text/html", + # "charset" => "iso-2022-jp", + # # Content-Type: text/html; charset=iso-2022-jp + # "length" => 103, + # "language" => "ja", + # "expires" => Time.now + 30, + # "cookie" => [cookie1, cookie2], + # "my_header1" => "my_value" + # "my_header2" => "my_value") + # + # The status codes are: + # + # "OK" --> "200 OK" + # "PARTIAL_CONTENT" --> "206 Partial Content" + # "MULTIPLE_CHOICES" --> "300 Multiple Choices" + # "MOVED" --> "301 Moved Permanently" + # "REDIRECT" --> "302 Found" + # "NOT_MODIFIED" --> "304 Not Modified" + # "BAD_REQUEST" --> "400 Bad Request" + # "AUTH_REQUIRED" --> "401 Authorization Required" + # "FORBIDDEN" --> "403 Forbidden" + # "NOT_FOUND" --> "404 Not Found" + # "METHOD_NOT_ALLOWED" --> "405 Method Not Allowed" + # "NOT_ACCEPTABLE" --> "406 Not Acceptable" + # "LENGTH_REQUIRED" --> "411 Length Required" + # "PRECONDITION_FAILED" --> "412 Precondition Failed" + # "SERVER_ERROR" --> "500 Internal Server Error" + # "NOT_IMPLEMENTED" --> "501 Method Not Implemented" + # "BAD_GATEWAY" --> "502 Bad Gateway" + # "VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates" + # + # This method does not perform charset conversion. + # + def header(options = "text/html") + + buf = "" + + case options + when String + options = { "type" => options } + when Hash + options = options.dup + end + + unless options.has_key?("type") + options["type"] = "text/html" + end + + if options.has_key?("charset") + options["type"] += "; charset=" + options.delete("charset") + end + + options.delete("nph") if defined?(MOD_RUBY) + if options.delete("nph") or + (/IIS\/(\d+)/n.match(env_table['SERVER_SOFTWARE']) and $1.to_i < 5) + buf += (env_table["SERVER_PROTOCOL"] or "HTTP/1.0") + " " + + (HTTP_STATUS[options["status"]] or options["status"] or "200 OK") + + EOL + + "Date: " + CGI::rfc1123_date(Time.now) + EOL + + unless options.has_key?("server") + options["server"] = (env_table['SERVER_SOFTWARE'] or "") + end + + unless options.has_key?("connection") + options["connection"] = "close" + end + + options.delete("status") + end + + if options.has_key?("status") + buf += "Status: " + + (HTTP_STATUS[options["status"]] or options["status"]) + EOL + options.delete("status") + end + + if options.has_key?("server") + buf += "Server: " + options.delete("server") + EOL + end + + if options.has_key?("connection") + buf += "Connection: " + options.delete("connection") + EOL + end + + buf += "Content-Type: " + options.delete("type") + EOL + + if options.has_key?("length") + buf += "Content-Length: " + options.delete("length").to_s + EOL + end + + if options.has_key?("language") + buf += "Content-Language: " + options.delete("language") + EOL + end + + if options.has_key?("expires") + buf += "Expires: " + CGI::rfc1123_date( options.delete("expires") ) + EOL + end + + if options.has_key?("cookie") + if options["cookie"].kind_of?(String) or + options["cookie"].kind_of?(Cookie) + buf += "Set-Cookie: " + options.delete("cookie").to_s + EOL + elsif options["cookie"].kind_of?(Array) + options.delete("cookie").each{|cookie| + buf += "Set-Cookie: " + cookie.to_s + EOL + } + elsif options["cookie"].kind_of?(Hash) + options.delete("cookie").each_value{|cookie| + buf += "Set-Cookie: " + cookie.to_s + EOL + } + end + end + if @output_cookies + for cookie in @output_cookies + buf += "Set-Cookie: " + cookie.to_s + EOL + end + end + + options.each{|key, value| + buf += key + ": " + value.to_s + EOL + } + + if defined?(MOD_RUBY) + table = Apache::request.headers_out + buf.scan(/([^:]+): (.+)#{EOL}/n){ |name, value| + warn sprintf("name:%s value:%s\n", name, value) if $DEBUG + case name + when 'Set-Cookie' + table.add(name, value) + when /^status$/ni + Apache::request.status_line = value + Apache::request.status = value.to_i + when /^content-type$/ni + Apache::request.content_type = value + when /^content-encoding$/ni + Apache::request.content_encoding = value + when /^location$/ni + if Apache::request.status == 200 + Apache::request.status = 302 + end + Apache::request.headers_out[name] = value + else + Apache::request.headers_out[name] = value + end + } + Apache::request.send_http_header + '' + else + buf + EOL + end + + end # header() + + + # Print an HTTP header and body to $DEFAULT_OUTPUT ($>) + # + # The header is provided by +options+, as for #header(). + # The body of the document is that returned by the passed- + # in block. This block takes no arguments. It is required. + # + # cgi = CGI.new + # cgi.out{ "string" } + # # Content-Type: text/html + # # Content-Length: 6 + # # + # # string + # + # cgi.out("text/plain") { "string" } + # # Content-Type: text/plain + # # Content-Length: 6 + # # + # # string + # + # cgi.out("nph" => true, + # "status" => "OK", # == "200 OK" + # "server" => ENV['SERVER_SOFTWARE'], + # "connection" => "close", + # "type" => "text/html", + # "charset" => "iso-2022-jp", + # # Content-Type: text/html; charset=iso-2022-jp + # "language" => "ja", + # "expires" => Time.now + (3600 * 24 * 30), + # "cookie" => [cookie1, cookie2], + # "my_header1" => "my_value", + # "my_header2" => "my_value") { "string" } + # + # Content-Length is automatically calculated from the size of + # the String returned by the content block. + # + # If ENV['REQUEST_METHOD'] == "HEAD", then only the header + # is outputted (the content block is still required, but it + # is ignored). + # + # If the charset is "iso-2022-jp" or "euc-jp" or "shift_jis" then + # the content is converted to this charset, and the language is set + # to "ja". + def out(options = "text/html") # :yield: + + options = { "type" => options } if options.kind_of?(String) + content = yield + + if options.has_key?("charset") + require "nkf" + case options["charset"] + when /iso-2022-jp/ni + content = NKF::nkf('-m0 -x -j', content) + options["language"] = "ja" unless options.has_key?("language") + when /euc-jp/ni + content = NKF::nkf('-m0 -x -e', content) + options["language"] = "ja" unless options.has_key?("language") + when /shift_jis/ni + content = NKF::nkf('-m0 -x -s', content) + options["language"] = "ja" unless options.has_key?("language") + end + end + + options["length"] = content.length.to_s + output = stdoutput + output.binmode if defined? output.binmode + output.print header(options) + output.print content unless "HEAD" == env_table['REQUEST_METHOD'] + end + + + # Print an argument or list of arguments to the default output stream + # + # cgi = CGI.new + # cgi.print # default: cgi.print == $DEFAULT_OUTPUT.print + def print(*options) + stdoutput.print(*options) + end + + require "delegate" + + # Class representing an HTTP cookie. + # + # In addition to its specific fields and methods, a Cookie instance + # is a delegator to the array of its values. + # + # See RFC 2965. + # + # == Examples of use + # cookie1 = CGI::Cookie::new("name", "value1", "value2", ...) + # cookie1 = CGI::Cookie::new("name" => "name", "value" => "value") + # cookie1 = CGI::Cookie::new('name' => 'name', + # 'value' => ['value1', 'value2', ...], + # 'path' => 'path', # optional + # 'domain' => 'domain', # optional + # 'expires' => Time.now, # optional + # 'secure' => true # optional + # ) + # + # cgi.out("cookie" => [cookie1, cookie2]) { "string" } + # + # name = cookie1.name + # values = cookie1.value + # path = cookie1.path + # domain = cookie1.domain + # expires = cookie1.expires + # secure = cookie1.secure + # + # cookie1.name = 'name' + # cookie1.value = ['value1', 'value2', ...] + # cookie1.path = 'path' + # cookie1.domain = 'domain' + # cookie1.expires = Time.now + 30 + # cookie1.secure = true + class Cookie < DelegateClass(Array) + + # Create a new CGI::Cookie object. + # + # The contents of the cookie can be specified as a +name+ and one + # or more +value+ arguments. Alternatively, the contents can + # be specified as a single hash argument. The possible keywords of + # this hash are as follows: + # + # name:: the name of the cookie. Required. + # value:: the cookie's value or list of values. + # path:: the path for which this cookie applies. Defaults to the + # base directory of the CGI script. + # domain:: the domain for which this cookie applies. + # expires:: the time at which this cookie expires, as a +Time+ object. + # secure:: whether this cookie is a secure cookie or not (default to + # false). Secure cookies are only transmitted to HTTPS + # servers. + # + # These keywords correspond to attributes of the cookie object. + def initialize(name = "", *value) + options = if name.kind_of?(String) + { "name" => name, "value" => value } + else + name + end + unless options.has_key?("name") + raise ArgumentError, "`name' required" + end + + @name = options["name"] + @value = Array(options["value"]) + # simple support for IE + if options["path"] + @path = options["path"] + else + %r|^(.*/)|.match(ENV["SCRIPT_NAME"]) + @path = ($1 or "") + end + @domain = options["domain"] + @expires = options["expires"] + @secure = options["secure"] == true ? true : false + + super(@value) + end + + attr_accessor("name", "value", "path", "domain", "expires") + attr_reader("secure") + + # Set whether the Cookie is a secure cookie or not. + # + # +val+ must be a boolean. + def secure=(val) + @secure = val if val == true or val == false + @secure + end + + # Convert the Cookie to its string representation. + def to_s + buf = "" + buf += @name + '=' + + if @value.kind_of?(String) + buf += CGI::escape(@value) + else + buf += @value.collect{|v| CGI::escape(v) }.join("&") + end + + if @domain + buf += '; domain=' + @domain + end + + if @path + buf += '; path=' + @path + end + + if @expires + buf += '; expires=' + CGI::rfc1123_date(@expires) + end + + if @secure == true + buf += '; secure' + end + + buf + end + + end # class Cookie + + + # Parse a raw cookie string into a hash of cookie-name=>Cookie + # pairs. + # + # cookies = CGI::Cookie::parse("raw_cookie_string") + # # { "name1" => cookie1, "name2" => cookie2, ... } + # + def Cookie::parse(raw_cookie) + cookies = Hash.new([]) + return cookies unless raw_cookie + + raw_cookie.split(/[;,]\s?/).each do |pairs| + name, values = pairs.split('=',2) + next unless name and values + name = CGI::unescape(name) + values ||= "" + values = values.split('&').collect{|v| CGI::unescape(v) } + if cookies.has_key?(name) + values = cookies[name].value + values + end + cookies[name] = Cookie::new({ "name" => name, "value" => values }) + end + + cookies + end + + # Parse an HTTP query string into a hash of key=>value pairs. + # + # params = CGI::parse("query_string") + # # {"name1" => ["value1", "value2", ...], + # # "name2" => ["value1", "value2", ...], ... } + # + def CGI::parse(query) + params = Hash.new([].freeze) + + query.split(/[&;]/n).each do |pairs| + key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) } + if params.has_key?(key) + params[key].push(value) + else + params[key] = [value] + end + end + + params + end + + # Mixin module. It provides the follow functionality groups: + # + # 1. Access to CGI environment variables as methods. See + # documentation to the CGI class for a list of these variables. + # + # 2. Access to cookies, including the cookies attribute. + # + # 3. Access to parameters, including the params attribute, and overloading + # [] to perform parameter value lookup by key. + # + # 4. The initialize_query method, for initialising the above + # mechanisms, handling multipart forms, and allowing the + # class to be used in "offline" mode. + # + module QueryExtension + + %w[ CONTENT_LENGTH SERVER_PORT ].each do |env| + define_method(env.sub(/^HTTP_/n, '').downcase) do + (val = env_table[env]) && Integer(val) + end + end + + %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO + PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST + REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME + SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE + + HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING + HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST + HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env| + define_method(env.sub(/^HTTP_/n, '').downcase) do + env_table[env] + end + end + + # Get the raw cookies as a string. + def raw_cookie + env_table["HTTP_COOKIE"] + end + + # Get the raw RFC2965 cookies as a string. + def raw_cookie2 + env_table["HTTP_COOKIE2"] + end + + # Get the cookies as a hash of cookie-name=>Cookie pairs. + attr_accessor("cookies") + + # Get the parameters as a hash of name=>values pairs, where + # values is an Array. + attr("params") + + # Set all the parameters. + def params=(hash) + @params.clear + @params.update(hash) + end + + def read_multipart(boundary, content_length) + params = Hash.new([]) + boundary = "--" + boundary + quoted_boundary = Regexp.quote(boundary, "n") + buf = "" + bufsize = 10 * 1024 + boundary_end="" + + # start multipart/form-data + stdinput.binmode if defined? stdinput.binmode + boundary_size = boundary.size + EOL.size + content_length -= boundary_size + status = stdinput.read(boundary_size) + if nil == status + raise EOFError, "no content body" + elsif boundary + EOL != status + raise EOFError, "bad content body" + end + + loop do + head = nil + if 10240 < content_length + require "tempfile" + body = Tempfile.new("CGI") + else + begin + require "stringio" + body = StringIO.new + rescue LoadError + require "tempfile" + body = Tempfile.new("CGI") + end + end + body.binmode if defined? body.binmode + + until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf) + + if (not head) and /#{EOL}#{EOL}/n.match(buf) + buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do + head = $1.dup + "" + end + next + end + + if head and ( (EOL + boundary + EOL).size < buf.size ) + body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)] + buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = "" + end + + c = if bufsize < content_length + stdinput.read(bufsize) + else + stdinput.read(content_length) + end + if c.nil? || c.empty? + raise EOFError, "bad content body" + end + buf.concat(c) + content_length -= c.size + end + + buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do + body.print $1 + if "--" == $2 + content_length = -1 + end + boundary_end = $2.dup + "" + end + + body.rewind + + /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni.match(head) + filename = ($1 or $2 or "") + if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and + /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and + (not /MSIE/ni.match(env_table['HTTP_USER_AGENT'])) + filename = CGI::unescape(filename) + end + + /Content-Type: ([^\s]*)/ni.match(head) + content_type = ($1 or "") + + (class << body; self; end).class_eval do + alias local_path path + define_method(:original_filename) {filename.dup.taint} + define_method(:content_type) {content_type.dup.taint} + end + + /Content-Disposition:.* name="?([^\";\s]*)"?/ni.match(head) + name = $1.dup + + if params.has_key?(name) + params[name].push(body) + else + params[name] = [body] + end + break if buf.size == 0 + break if content_length == -1 + end + raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/ + + params + end # read_multipart + private :read_multipart + + # offline mode. read name=value pairs on standard input. + def read_from_cmdline + require "shellwords" + + string = unless ARGV.empty? + ARGV.join(' ') + else + if STDIN.tty? + STDERR.print( + %|(offline mode: enter name=value pairs on standard input)\n| + ) + end + readlines.join(' ').gsub(/\n/n, '') + end.gsub(/\\=/n, '%3D').gsub(/\\&/n, '%26') + + words = Shellwords.shellwords(string) + + if words.find{|x| /=/n.match(x) } + words.join('&') + else + words.join('+') + end + end + private :read_from_cmdline + + # Initialize the data from the query. + # + # Handles multipart forms (in particular, forms that involve file uploads). + # Reads query parameters in the @params field, and cookies into @cookies. + def initialize_query() + if ("POST" == env_table['REQUEST_METHOD']) and + %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE']) + boundary = $1.dup + @multipart = true + @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH'])) + else + @multipart = false + @params = CGI::parse( + case env_table['REQUEST_METHOD'] + when "GET", "HEAD" + if defined?(MOD_RUBY) + Apache::request.args or "" + else + env_table['QUERY_STRING'] or "" + end + when "POST" + stdinput.binmode if defined? stdinput.binmode + stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or '' + else + read_from_cmdline + end + ) + end + + @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE'])) + end + private :initialize_query + + def multipart? + @multipart + end + + module Value # :nodoc: + def set_params(params) + @params = params + end + def [](idx, *args) + if args.size == 0 + warn "#{caller(1)[0]}:CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']" + @params[idx] + else + super[idx,*args] + end + end + def first + warn "#{caller(1)[0]}:CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']" + self + end + alias last first + def to_a + @params || [self] + end + alias to_ary to_a # to be rhs of multiple assignment + end + + # Get the value for the parameter with a given key. + # + # If the parameter has multiple values, only the first will be + # retrieved; use #params() to get the array of values. + def [](key) + params = @params[key] + return '' unless params + value = params[0] + if @multipart + if value + return value + elsif defined? StringIO + StringIO.new("") + else + Tempfile.new("CGI") + end + else + str = if value then value.dup else "" end + str.extend(Value) + str.set_params(params) + str + end + end + + # Return all parameter keys as an array. + def keys(*args) + @params.keys(*args) + end + + # Returns true if a given parameter key exists in the query. + def has_key?(*args) + @params.has_key?(*args) + end + alias key? has_key? + alias include? has_key? + + end # QueryExtension + + + # Prettify (indent) an HTML string. + # + # +string+ is the HTML string to indent. +shift+ is the indentation + # unit to use; it defaults to two spaces. + # + # print CGI::pretty("") + # # + # # + # # + # # + # + # print CGI::pretty("", "\t") + # # + # # + # # + # # + # + def CGI::pretty(string, shift = " ") + lines = string.gsub(/(?!\A)<(?:.|\n)*?>/n, "\n\\0").gsub(/<(?:.|\n)*?>(?!\n)/n, "\\0\n") + end_pos = 0 + while end_pos = lines.index(/^<\/(\w+)/n, end_pos) + element = $1.dup + start_pos = lines.rindex(/^\s*<#{element}/ni, end_pos) + lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/n, "\n" + shift) + "__" + end + lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/n, '\1') + end + + + # Base module for HTML-generation mixins. + # + # Provides methods for code generation for tags following + # the various DTD element types. + module TagMaker # :nodoc: + + # Generate code for an element with required start and end tags. + # + # - - + def nn_element_def(element) + nOE_element_def(element, <<-END) + if block_given? + yield.to_s + else + "" + end + + "" + END + end + + # Generate code for an empty element. + # + # - O EMPTY + def nOE_element_def(element, append = nil) + s = <<-END + "<#{element.upcase}" + attributes.collect{|name, value| + next unless value + " " + CGI::escapeHTML(name) + + if true == value + "" + else + '="' + CGI::escapeHTML(value) + '"' + end + }.to_s + ">" + END + s.sub!(/\Z/, " +") << append if append + s + end + + # Generate code for an element for which the end (and possibly the + # start) tag is optional. + # + # O O or - O + def nO_element_def(element) + nOE_element_def(element, <<-END) + if block_given? + yield.to_s + "" + else + "" + end + END + end + + end # TagMaker + + + # + # Mixin module providing HTML generation methods. + # + # For example, + # cgi.a("http://www.example.com") { "Example" } + # # => "Example" + # + # Modules Http3, Http4, etc., contain more basic HTML-generation methods + # (:title, :center, etc.). + # + # See class CGI for a detailed example. + # + module HtmlExtension + + + # Generate an Anchor element as a string. + # + # +href+ can either be a string, giving the URL + # for the HREF attribute, or it can be a hash of + # the element's attributes. + # + # The body of the element is the string returned by the no-argument + # block passed in. + # + # a("http://www.example.com") { "Example" } + # # => "Example" + # + # a("HREF" => "http://www.example.com", "TARGET" => "_top") { "Example" } + # # => "Example" + # + def a(href = "") # :yield: + attributes = if href.kind_of?(String) + { "HREF" => href } + else + href + end + if block_given? + super(attributes){ yield } + else + super(attributes) + end + end + + # Generate a Document Base URI element as a String. + # + # +href+ can either by a string, giving the base URL for the HREF + # attribute, or it can be a has of the element's attributes. + # + # The passed-in no-argument block is ignored. + # + # base("http://www.example.com/cgi") + # # => "" + def base(href = "") # :yield: + attributes = if href.kind_of?(String) + { "HREF" => href } + else + href + end + if block_given? + super(attributes){ yield } + else + super(attributes) + end + end + + # Generate a BlockQuote element as a string. + # + # +cite+ can either be a string, give the URI for the source of + # the quoted text, or a hash, giving all attributes of the element, + # or it can be omitted, in which case the element has no attributes. + # + # The body is provided by the passed-in no-argument block + # + # blockquote("http://www.example.com/quotes/foo.html") { "Foo!" } + # #=> "
Foo!
+ def blockquote(cite = nil) # :yield: + attributes = if cite.kind_of?(String) + { "CITE" => cite } + else + cite or "" + end + if block_given? + super(attributes){ yield } + else + super(attributes) + end + end + + + # Generate a Table Caption element as a string. + # + # +align+ can be a string, giving the alignment of the caption + # (one of top, bottom, left, or right). It can be a hash of + # all the attributes of the element. Or it can be omitted. + # + # The body of the element is provided by the passed-in no-argument block. + # + # caption("left") { "Capital Cities" } + # # => Capital Cities + def caption(align = nil) # :yield: + attributes = if align.kind_of?(String) + { "ALIGN" => align } + else + align or "" + end + if block_given? + super(attributes){ yield } + else + super(attributes) + end + end + + + # Generate a Checkbox Input element as a string. + # + # The attributes of the element can be specified as three arguments, + # +name+, +value+, and +checked+. +checked+ is a boolean value; + # if true, the CHECKED attribute will be included in the element. + # + # Alternatively, the attributes can be specified as a hash. + # + # checkbox("name") + # # = checkbox("NAME" => "name") + # + # checkbox("name", "value") + # # = checkbox("NAME" => "name", "VALUE" => "value") + # + # checkbox("name", "value", true) + # # = checkbox("NAME" => "name", "VALUE" => "value", "CHECKED" => true) + def checkbox(name = "", value = nil, checked = nil) + attributes = if name.kind_of?(String) + { "TYPE" => "checkbox", "NAME" => name, + "VALUE" => value, "CHECKED" => checked } + else + name["TYPE"] = "checkbox" + name + end + input(attributes) + end + + # Generate a sequence of checkbox elements, as a String. + # + # The checkboxes will all have the same +name+ attribute. + # Each checkbox is followed by a label. + # There will be one checkbox for each value. Each value + # can be specified as a String, which will be used both + # as the value of the VALUE attribute and as the label + # for that checkbox. A single-element array has the + # same effect. + # + # Each value can also be specified as a three-element array. + # The first element is the VALUE attribute; the second is the + # label; and the third is a boolean specifying whether this + # checkbox is CHECKED. + # + # Each value can also be specified as a two-element + # array, by omitting either the value element (defaults + # to the same as the label), or the boolean checked element + # (defaults to false). + # + # checkbox_group("name", "foo", "bar", "baz") + # # foo + # # bar + # # baz + # + # checkbox_group("name", ["foo"], ["bar", true], "baz") + # # foo + # # bar + # # baz + # + # checkbox_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz") + # # Foo + # # Bar + # # Baz + # + # checkbox_group("NAME" => "name", + # "VALUES" => ["foo", "bar", "baz"]) + # + # checkbox_group("NAME" => "name", + # "VALUES" => [["foo"], ["bar", true], "baz"]) + # + # checkbox_group("NAME" => "name", + # "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"]) + def checkbox_group(name = "", *values) + if name.kind_of?(Hash) + values = name["VALUES"] + name = name["NAME"] + end + values.collect{|value| + if value.kind_of?(String) + checkbox(name, value) + value + else + if value[value.size - 1] == true + checkbox(name, value[0], true) + + value[value.size - 2] + else + checkbox(name, value[0]) + + value[value.size - 1] + end + end + }.to_s + end + + + # Generate an File Upload Input element as a string. + # + # The attributes of the element can be specified as three arguments, + # +name+, +size+, and +maxlength+. +maxlength+ is the maximum length + # of the file's _name_, not of the file's _contents_. + # + # Alternatively, the attributes can be specified as a hash. + # + # See #multipart_form() for forms that include file uploads. + # + # file_field("name") + # # + # + # file_field("name", 40) + # # + # + # file_field("name", 40, 100) + # # + # + # file_field("NAME" => "name", "SIZE" => 40) + # # + def file_field(name = "", size = 20, maxlength = nil) + attributes = if name.kind_of?(String) + { "TYPE" => "file", "NAME" => name, + "SIZE" => size.to_s } + else + name["TYPE"] = "file" + name + end + attributes["MAXLENGTH"] = maxlength.to_s if maxlength + input(attributes) + end + + + # Generate a Form element as a string. + # + # +method+ should be either "get" or "post", and defaults to the latter. + # +action+ defaults to the current CGI script name. +enctype+ + # defaults to "application/x-www-form-urlencoded". + # + # Alternatively, the attributes can be specified as a hash. + # + # See also #multipart_form() for forms that include file uploads. + # + # form{ "string" } + # #
string
+ # + # form("get") { "string" } + # #
string
+ # + # form("get", "url") { "string" } + # #
string
+ # + # form("METHOD" => "post", "ENCTYPE" => "enctype") { "string" } + # #
string
+ def form(method = "post", action = script_name, enctype = "application/x-www-form-urlencoded") + attributes = if method.kind_of?(String) + { "METHOD" => method, "ACTION" => action, + "ENCTYPE" => enctype } + else + unless method.has_key?("METHOD") + method["METHOD"] = "post" + end + unless method.has_key?("ENCTYPE") + method["ENCTYPE"] = enctype + end + method + end + if block_given? + body = yield + else + body = "" + end + if @output_hidden + body += @output_hidden.collect{|k,v| + "" + }.to_s + end + super(attributes){body} + end + + # Generate a Hidden Input element as a string. + # + # The attributes of the element can be specified as two arguments, + # +name+ and +value+. + # + # Alternatively, the attributes can be specified as a hash. + # + # hidden("name") + # # + # + # hidden("name", "value") + # # + # + # hidden("NAME" => "name", "VALUE" => "reset", "ID" => "foo") + # # + def hidden(name = "", value = nil) + attributes = if name.kind_of?(String) + { "TYPE" => "hidden", "NAME" => name, "VALUE" => value } + else + name["TYPE"] = "hidden" + name + end + input(attributes) + end + + # Generate a top-level HTML element as a string. + # + # The attributes of the element are specified as a hash. The + # pseudo-attribute "PRETTY" can be used to specify that the generated + # HTML string should be indented. "PRETTY" can also be specified as + # a string as the sole argument to this method. The pseudo-attribute + # "DOCTYPE", if given, is used as the leading DOCTYPE SGML tag; it + # should include the entire text of this tag, including angle brackets. + # + # The body of the html element is supplied as a block. + # + # html{ "string" } + # # string + # + # html("LANG" => "ja") { "string" } + # # string + # + # html("DOCTYPE" => false) { "string" } + # # string + # + # html("DOCTYPE" => '') { "string" } + # # string + # + # html("PRETTY" => " ") { "" } + # # + # # + # # + # # + # # + # + # html("PRETTY" => "\t") { "" } + # # + # # + # # + # # + # # + # + # html("PRETTY") { "" } + # # = html("PRETTY" => " ") { "" } + # + # html(if $VERBOSE then "PRETTY" end) { "HTML string" } + # + def html(attributes = {}) # :yield: + if nil == attributes + attributes = {} + elsif "PRETTY" == attributes + attributes = { "PRETTY" => true } + end + pretty = attributes.delete("PRETTY") + pretty = " " if true == pretty + buf = "" + + if attributes.has_key?("DOCTYPE") + if attributes["DOCTYPE"] + buf += attributes.delete("DOCTYPE") + else + attributes.delete("DOCTYPE") + end + else + buf += doctype + end + + if block_given? + buf += super(attributes){ yield } + else + buf += super(attributes) + end + + if pretty + CGI::pretty(buf, pretty) + else + buf + end + + end + + # Generate an Image Button Input element as a string. + # + # +src+ is the URL of the image to use for the button. +name+ + # is the input name. +alt+ is the alternative text for the image. + # + # Alternatively, the attributes can be specified as a hash. + # + # image_button("url") + # # + # + # image_button("url", "name", "string") + # # + # + # image_button("SRC" => "url", "ATL" => "strng") + # # + def image_button(src = "", name = nil, alt = nil) + attributes = if src.kind_of?(String) + { "TYPE" => "image", "SRC" => src, "NAME" => name, + "ALT" => alt } + else + src["TYPE"] = "image" + src["SRC"] ||= "" + src + end + input(attributes) + end + + + # Generate an Image element as a string. + # + # +src+ is the URL of the image. +alt+ is the alternative text for + # the image. +width+ is the width of the image, and +height+ is + # its height. + # + # Alternatively, the attributes can be specified as a hash. + # + # img("src", "alt", 100, 50) + # # alt + # + # img("SRC" => "src", "ALT" => "alt", "WIDTH" => 100, "HEIGHT" => 50) + # # alt + def img(src = "", alt = "", width = nil, height = nil) + attributes = if src.kind_of?(String) + { "SRC" => src, "ALT" => alt } + else + src + end + attributes["WIDTH"] = width.to_s if width + attributes["HEIGHT"] = height.to_s if height + super(attributes) + end + + + # Generate a Form element with multipart encoding as a String. + # + # Multipart encoding is used for forms that include file uploads. + # + # +action+ is the action to perform. +enctype+ is the encoding + # type, which defaults to "multipart/form-data". + # + # Alternatively, the attributes can be specified as a hash. + # + # multipart_form{ "string" } + # #
string
+ # + # multipart_form("url") { "string" } + # #
string
+ def multipart_form(action = nil, enctype = "multipart/form-data") + attributes = if action == nil + { "METHOD" => "post", "ENCTYPE" => enctype } + elsif action.kind_of?(String) + { "METHOD" => "post", "ACTION" => action, + "ENCTYPE" => enctype } + else + unless action.has_key?("METHOD") + action["METHOD"] = "post" + end + unless action.has_key?("ENCTYPE") + action["ENCTYPE"] = enctype + end + action + end + if block_given? + form(attributes){ yield } + else + form(attributes) + end + end + + + # Generate a Password Input element as a string. + # + # +name+ is the name of the input field. +value+ is its default + # value. +size+ is the size of the input field display. +maxlength+ + # is the maximum length of the inputted password. + # + # Alternatively, attributes can be specified as a hash. + # + # password_field("name") + # # + # + # password_field("name", "value") + # # + # + # password_field("password", "value", 80, 200) + # # + # + # password_field("NAME" => "name", "VALUE" => "value") + # # + def password_field(name = "", value = nil, size = 40, maxlength = nil) + attributes = if name.kind_of?(String) + { "TYPE" => "password", "NAME" => name, + "VALUE" => value, "SIZE" => size.to_s } + else + name["TYPE"] = "password" + name + end + attributes["MAXLENGTH"] = maxlength.to_s if maxlength + input(attributes) + end + + # Generate a Select element as a string. + # + # +name+ is the name of the element. The +values+ are the options that + # can be selected from the Select menu. Each value can be a String or + # a one, two, or three-element Array. If a String or a one-element + # Array, this is both the value of that option and the text displayed for + # it. If a three-element Array, the elements are the option value, displayed + # text, and a boolean value specifying whether this option starts as selected. + # The two-element version omits either the option value (defaults to the same + # as the display text) or the boolean selected specifier (defaults to false). + # + # The attributes and options can also be specified as a hash. In this + # case, options are specified as an array of values as described above, + # with the hash key of "VALUES". + # + # popup_menu("name", "foo", "bar", "baz") + # # + # + # popup_menu("name", ["foo"], ["bar", true], "baz") + # # + # + # popup_menu("name", ["1", "Foo"], ["2", "Bar", true], "Baz") + # # + # + # popup_menu("NAME" => "name", "SIZE" => 2, "MULTIPLE" => true, + # "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"]) + # # + def popup_menu(name = "", *values) + + if name.kind_of?(Hash) + values = name["VALUES"] + size = name["SIZE"].to_s if name["SIZE"] + multiple = name["MULTIPLE"] + name = name["NAME"] + else + size = nil + multiple = nil + end + + select({ "NAME" => name, "SIZE" => size, + "MULTIPLE" => multiple }){ + values.collect{|value| + if value.kind_of?(String) + option({ "VALUE" => value }){ value } + else + if value[value.size - 1] == true + option({ "VALUE" => value[0], "SELECTED" => true }){ + value[value.size - 2] + } + else + option({ "VALUE" => value[0] }){ + value[value.size - 1] + } + end + end + }.to_s + } + + end + + # Generates a radio-button Input element. + # + # +name+ is the name of the input field. +value+ is the value of + # the field if checked. +checked+ specifies whether the field + # starts off checked. + # + # Alternatively, the attributes can be specified as a hash. + # + # radio_button("name", "value") + # # + # + # radio_button("name", "value", true) + # # + # + # radio_button("NAME" => "name", "VALUE" => "value", "ID" => "foo") + # # + def radio_button(name = "", value = nil, checked = nil) + attributes = if name.kind_of?(String) + { "TYPE" => "radio", "NAME" => name, + "VALUE" => value, "CHECKED" => checked } + else + name["TYPE"] = "radio" + name + end + input(attributes) + end + + # Generate a sequence of radio button Input elements, as a String. + # + # This works the same as #checkbox_group(). However, it is not valid + # to have more than one radiobutton in a group checked. + # + # radio_group("name", "foo", "bar", "baz") + # # foo + # # bar + # # baz + # + # radio_group("name", ["foo"], ["bar", true], "baz") + # # foo + # # bar + # # baz + # + # radio_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz") + # # Foo + # # Bar + # # Baz + # + # radio_group("NAME" => "name", + # "VALUES" => ["foo", "bar", "baz"]) + # + # radio_group("NAME" => "name", + # "VALUES" => [["foo"], ["bar", true], "baz"]) + # + # radio_group("NAME" => "name", + # "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"]) + def radio_group(name = "", *values) + if name.kind_of?(Hash) + values = name["VALUES"] + name = name["NAME"] + end + values.collect{|value| + if value.kind_of?(String) + radio_button(name, value) + value + else + if value[value.size - 1] == true + radio_button(name, value[0], true) + + value[value.size - 2] + else + radio_button(name, value[0]) + + value[value.size - 1] + end + end + }.to_s + end + + # Generate a reset button Input element, as a String. + # + # This resets the values on a form to their initial values. +value+ + # is the text displayed on the button. +name+ is the name of this button. + # + # Alternatively, the attributes can be specified as a hash. + # + # reset + # # + # + # reset("reset") + # # + # + # reset("VALUE" => "reset", "ID" => "foo") + # # + def reset(value = nil, name = nil) + attributes = if (not value) or value.kind_of?(String) + { "TYPE" => "reset", "VALUE" => value, "NAME" => name } + else + value["TYPE"] = "reset" + value + end + input(attributes) + end + + alias scrolling_list popup_menu + + # Generate a submit button Input element, as a String. + # + # +value+ is the text to display on the button. +name+ is the name + # of the input. + # + # Alternatively, the attributes can be specified as a hash. + # + # submit + # # + # + # submit("ok") + # # + # + # submit("ok", "button1") + # # + # + # submit("VALUE" => "ok", "NAME" => "button1", "ID" => "foo") + # # + def submit(value = nil, name = nil) + attributes = if (not value) or value.kind_of?(String) + { "TYPE" => "submit", "VALUE" => value, "NAME" => name } + else + value["TYPE"] = "submit" + value + end + input(attributes) + end + + # Generate a text field Input element, as a String. + # + # +name+ is the name of the input field. +value+ is its initial + # value. +size+ is the size of the input area. +maxlength+ + # is the maximum length of input accepted. + # + # Alternatively, the attributes can be specified as a hash. + # + # text_field("name") + # # + # + # text_field("name", "value") + # # + # + # text_field("name", "value", 80) + # # + # + # text_field("name", "value", 80, 200) + # # + # + # text_field("NAME" => "name", "VALUE" => "value") + # # + def text_field(name = "", value = nil, size = 40, maxlength = nil) + attributes = if name.kind_of?(String) + { "TYPE" => "text", "NAME" => name, "VALUE" => value, + "SIZE" => size.to_s } + else + name["TYPE"] = "text" + name + end + attributes["MAXLENGTH"] = maxlength.to_s if maxlength + input(attributes) + end + + # Generate a TextArea element, as a String. + # + # +name+ is the name of the textarea. +cols+ is the number of + # columns and +rows+ is the number of rows in the display. + # + # Alternatively, the attributes can be specified as a hash. + # + # The body is provided by the passed-in no-argument block + # + # textarea("name") + # # = textarea("NAME" => "name", "COLS" => 70, "ROWS" => 10) + # + # textarea("name", 40, 5) + # # = textarea("NAME" => "name", "COLS" => 40, "ROWS" => 5) + def textarea(name = "", cols = 70, rows = 10) # :yield: + attributes = if name.kind_of?(String) + { "NAME" => name, "COLS" => cols.to_s, + "ROWS" => rows.to_s } + else + name + end + if block_given? + super(attributes){ yield } + else + super(attributes) + end + end + + end # HtmlExtension + + + # Mixin module for HTML version 3 generation methods. + module Html3 # :nodoc: + + # The DOCTYPE declaration for this version of HTML + def doctype + %|| + end + + # Initialise the HTML generation methods for this version. + def element_init + extend TagMaker + methods = "" + # - - + for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG + DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP + APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE + STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE + CAPTION ] + methods += <<-BEGIN + nn_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # - O EMPTY + for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT + ISINDEX META ] + methods += <<-BEGIN + nOE_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # O O or - O + for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr + th td ] + methods += <<-BEGIN + nO_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + eval(methods) + end + + end # Html3 + + + # Mixin module for HTML version 4 generation methods. + module Html4 # :nodoc: + + # The DOCTYPE declaration for this version of HTML + def doctype + %|| + end + + # Initialise the HTML generation methods for this version. + def element_init + extend TagMaker + methods = "" + # - - + for element in %w[ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD + VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT + H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP + FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT + TEXTAREA FORM A BLOCKQUOTE CAPTION ] + methods += <<-BEGIN + nn_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # - O EMPTY + for element in %w[ IMG BASE BR AREA LINK PARAM HR INPUT COL META ] + methods += <<-BEGIN + nOE_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # O O or - O + for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY + COLGROUP TR TH TD HEAD] + methods += <<-BEGIN + nO_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + eval(methods) + end + + end # Html4 + + + # Mixin module for HTML version 4 transitional generation methods. + module Html4Tr # :nodoc: + + # The DOCTYPE declaration for this version of HTML + def doctype + %|| + end + + # Initialise the HTML generation methods for this version. + def element_init + extend TagMaker + methods = "" + # - - + for element in %w[ TT I B U S STRIKE BIG SMALL EM STRONG DFN + CODE SAMP KBD VAR CITE ABBR ACRONYM FONT SUB SUP SPAN BDO + ADDRESS DIV CENTER MAP OBJECT APPLET H1 H2 H3 H4 H5 H6 PRE Q + INS DEL DL OL UL DIR MENU LABEL SELECT OPTGROUP FIELDSET + LEGEND BUTTON TABLE IFRAME NOFRAMES TITLE STYLE SCRIPT + NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION ] + methods += <<-BEGIN + nn_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # - O EMPTY + for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT + COL ISINDEX META ] + methods += <<-BEGIN + nOE_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # O O or - O + for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY + COLGROUP TR TH TD HEAD ] + methods += <<-BEGIN + nO_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + eval(methods) + end + + end # Html4Tr + + + # Mixin module for generating HTML version 4 with framesets. + module Html4Fr # :nodoc: + + # The DOCTYPE declaration for this version of HTML + def doctype + %|| + end + + # Initialise the HTML generation methods for this version. + def element_init + methods = "" + # - - + for element in %w[ FRAMESET ] + methods += <<-BEGIN + nn_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + + # - O EMPTY + for element in %w[ FRAME ] + methods += <<-BEGIN + nOE_element_def(element) + <<-END + def #{element.downcase}(attributes = {}) + BEGIN + end + END + end + eval(methods) + end + + end # Html4Fr + + + # Creates a new CGI instance. + # + # +type+ specifies which version of HTML to load the HTML generation + # methods for. The following versions of HTML are supported: + # + # html3:: HTML 3.x + # html4:: HTML 4.0 + # html4Tr:: HTML 4.0 Transitional + # html4Fr:: HTML 4.0 with Framesets + # + # If not specified, no HTML generation methods will be loaded. + # + # If the CGI object is not created in a standard CGI call environment + # (that is, it can't locate REQUEST_METHOD in its environment), then + # it will run in "offline" mode. In this mode, it reads its parameters + # from the command line or (failing that) from standard input. Otherwise, + # cookies and other parameters are parsed automatically from the standard + # CGI locations, which varies according to the REQUEST_METHOD. + def initialize(type = "query") + if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE") + Apache.request.setup_cgi_env + end + + extend QueryExtension + @multipart = false + if defined?(CGI_PARAMS) + warn "do not use CGI_PARAMS and CGI_COOKIES" + @params = CGI_PARAMS.dup + @cookies = CGI_COOKIES.dup + else + initialize_query() # set @params, @cookies + end + @output_cookies = nil + @output_hidden = nil + + case type + when "html3" + extend Html3 + element_init() + extend HtmlExtension + when "html4" + extend Html4 + element_init() + extend HtmlExtension + when "html4Tr" + extend Html4Tr + element_init() + extend HtmlExtension + when "html4Fr" + extend Html4Tr + element_init() + extend Html4Fr + element_init() + extend HtmlExtension + end + end + +end # class CGI diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi/session.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi/session.rb new file mode 100644 index 00000000..5568b28d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi/session.rb @@ -0,0 +1,492 @@ +# +# cgi/session.rb - session support for cgi scripts +# +# Copyright (C) 2001 Yukihiro "Matz" Matsumoto +# Copyright (C) 2000 Network Applied Communication Laboratory, Inc. +# Copyright (C) 2000 Information-technology Promotion Agency, Japan +# +# Author: Yukihiro "Matz" Matsumoto +# +# Documentation: William Webber (william@williamwebber.com) +# +# == Overview +# +# This file provides the +CGI::Session+ class, which provides session +# support for CGI scripts. A session is a sequence of HTTP requests +# and responses linked together and associated with a single client. +# Information associated with the session is stored +# on the server between requests. A session id is passed between client +# and server with every request and response, transparently +# to the user. This adds state information to the otherwise stateless +# HTTP request/response protocol. +# +# See the documentation to the +CGI::Session+ class for more details +# and examples of usage. See cgi.rb for the +CGI+ class itself. + +require 'cgi' +require 'tmpdir' + +class CGI + + # Class representing an HTTP session. See documentation for the file + # cgi/session.rb for an introduction to HTTP sessions. + # + # == Lifecycle + # + # A CGI::Session instance is created from a CGI object. By default, + # this CGI::Session instance will start a new session if none currently + # exists, or continue the current session for this client if one does + # exist. The +new_session+ option can be used to either always or + # never create a new session. See #new() for more details. + # + # #delete() deletes a session from session storage. It + # does not however remove the session id from the client. If the client + # makes another request with the same id, the effect will be to start + # a new session with the old session's id. + # + # == Setting and retrieving session data. + # + # The Session class associates data with a session as key-value pairs. + # This data can be set and retrieved by indexing the Session instance + # using '[]', much the same as hashes (although other hash methods + # are not supported). + # + # When session processing has been completed for a request, the + # session should be closed using the close() method. This will + # store the session's state to persistent storage. If you want + # to store the session's state to persistent storage without + # finishing session processing for this request, call the update() + # method. + # + # == Storing session state + # + # The caller can specify what form of storage to use for the session's + # data with the +database_manager+ option to CGI::Session::new. The + # following storage classes are provided as part of the standard library: + # + # CGI::Session::FileStore:: stores data as plain text in a flat file. Only + # works with String data. This is the default + # storage type. + # CGI::Session::MemoryStore:: stores data in an in-memory hash. The data + # only persists for as long as the current ruby + # interpreter instance does. + # CGI::Session::PStore:: stores data in Marshalled format. Provided by + # cgi/session/pstore.rb. Supports data of any type, + # and provides file-locking and transaction support. + # + # Custom storage types can also be created by defining a class with + # the following methods: + # + # new(session, options) + # restore # returns hash of session data. + # update + # close + # delete + # + # Changing storage type mid-session does not work. Note in particular + # that by default the FileStore and PStore session data files have the + # same name. If your application switches from one to the other without + # making sure that filenames will be different + # and clients still have old sessions lying around in cookies, then + # things will break nastily! + # + # == Maintaining the session id. + # + # Most session state is maintained on the server. However, a session + # id must be passed backwards and forwards between client and server + # to maintain a reference to this session state. + # + # The simplest way to do this is via cookies. The CGI::Session class + # provides transparent support for session id communication via cookies + # if the client has cookies enabled. + # + # If the client has cookies disabled, the session id must be included + # as a parameter of all requests sent by the client to the server. The + # CGI::Session class in conjunction with the CGI class will transparently + # add the session id as a hidden input field to all forms generated + # using the CGI#form() HTML generation method. No built-in support is + # provided for other mechanisms, such as URL re-writing. The caller is + # responsible for extracting the session id from the session_id + # attribute and manually encoding it in URLs and adding it as a hidden + # input to HTML forms created by other mechanisms. Also, session expiry + # is not automatically handled. + # + # == Examples of use + # + # === Setting the user's name + # + # require 'cgi' + # require 'cgi/session' + # require 'cgi/session/pstore' # provides CGI::Session::PStore + # + # cgi = CGI.new("html4") + # + # session = CGI::Session.new(cgi, + # 'database_manager' => CGI::Session::PStore, # use PStore + # 'session_key' => '_rb_sess_id', # custom session key + # 'session_expires' => Time.now + 30 * 60, # 30 minute timeout + # 'prefix' => 'pstore_sid_') # PStore option + # if cgi.has_key?('user_name') and cgi['user_name'] != '' + # # coerce to String: cgi[] returns the + # # string-like CGI::QueryExtension::Value + # session['user_name'] = cgi['user_name'].to_s + # elsif !session['user_name'] + # session['user_name'] = "guest" + # end + # session.close + # + # === Creating a new session safely + # + # require 'cgi' + # require 'cgi/session' + # + # cgi = CGI.new("html4") + # + # # We make sure to delete an old session if one exists, + # # not just to free resources, but to prevent the session + # # from being maliciously hijacked later on. + # begin + # session = CGI::Session.new(cgi, 'new_session' => false) + # session.delete + # rescue ArgumentError # if no old session + # end + # session = CGI::Session.new(cgi, 'new_session' => true) + # session.close + # + class Session + + class NoSession < RuntimeError #:nodoc: + end + + # The id of this session. + attr_reader :session_id, :new_session + + def Session::callback(dbman) #:nodoc: + Proc.new{ + dbman[0].close unless dbman.empty? + } + end + + # Create a new session id. + # + # The session id is an MD5 hash based upon the time, + # a random number, and a constant string. This routine + # is used internally for automatically generated + # session ids. + def create_new_id + require 'digest/md5' + md5 = Digest::MD5::new + now = Time::now + md5.update(now.to_s) + md5.update(String(now.usec)) + md5.update(String(rand(0))) + md5.update(String($$)) + md5.update('foobar') + @new_session = true + md5.hexdigest + end + private :create_new_id + + # Create a new CGI::Session object for +request+. + # + # +request+ is an instance of the +CGI+ class (see cgi.rb). + # +option+ is a hash of options for initialising this + # CGI::Session instance. The following options are + # recognised: + # + # session_key:: the parameter name used for the session id. + # Defaults to '_session_id'. + # session_id:: the session id to use. If not provided, then + # it is retrieved from the +session_key+ parameter + # of the request, or automatically generated for + # a new session. + # new_session:: if true, force creation of a new session. If not set, + # a new session is only created if none currently + # exists. If false, a new session is never created, + # and if none currently exists and the +session_id+ + # option is not set, an ArgumentError is raised. + # database_manager:: the name of the class providing storage facilities + # for session state persistence. Built-in support + # is provided for +FileStore+ (the default), + # +MemoryStore+, and +PStore+ (from + # cgi/session/pstore.rb). See the documentation for + # these classes for more details. + # + # The following options are also recognised, but only apply if the + # session id is stored in a cookie. + # + # session_expires:: the time the current session expires, as a + # +Time+ object. If not set, the session will terminate + # when the user's browser is closed. + # session_domain:: the hostname domain for which this session is valid. + # If not set, defaults to the hostname of the server. + # session_secure:: if +true+, this session will only work over HTTPS. + # session_path:: the path for which this session applies. Defaults + # to the directory of the CGI script. + # + # +option+ is also passed on to the session storage class initialiser; see + # the documentation for each session storage class for the options + # they support. + # + # The retrieved or created session is automatically added to +request+ + # as a cookie, and also to its +output_hidden+ table, which is used + # to add hidden input elements to forms. + # + # *WARNING* the +output_hidden+ + # fields are surrounded by a
tag in HTML 4 generation, which + # is _not_ invisible on many browsers; you may wish to disable the + # use of fieldsets with code similar to the following + # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805) + # + # cgi = CGI.new("html4") + # class << cgi + # undef_method :fieldset + # end + # + def initialize(request, option={}) + @new_session = false + session_key = option['session_key'] || '_session_id' + session_id = option['session_id'] + unless session_id + if option['new_session'] + session_id = create_new_id + end + end + unless session_id + if request.key?(session_key) + session_id = request[session_key] + session_id = session_id.read if session_id.respond_to?(:read) + end + unless session_id + session_id, = request.cookies[session_key] + end + unless session_id + unless option.fetch('new_session', true) + raise ArgumentError, "session_key `%s' should be supplied"%session_key + end + session_id = create_new_id + end + end + @session_id = session_id + dbman = option['database_manager'] || FileStore + begin + @dbman = dbman::new(self, option) + rescue NoSession + unless option.fetch('new_session', true) + raise ArgumentError, "invalid session_id `%s'"%session_id + end + session_id = @session_id = create_new_id + retry + end + request.instance_eval do + @output_hidden = {session_key => session_id} unless option['no_hidden'] + @output_cookies = [ + Cookie::new("name" => session_key, + "value" => session_id, + "expires" => option['session_expires'], + "domain" => option['session_domain'], + "secure" => option['session_secure'], + "path" => if option['session_path'] then + option['session_path'] + elsif ENV["SCRIPT_NAME"] then + File::dirname(ENV["SCRIPT_NAME"]) + else + "" + end) + ] unless option['no_cookies'] + end + @dbprot = [@dbman] + ObjectSpace::define_finalizer(self, Session::callback(@dbprot)) + end + + # Retrieve the session data for key +key+. + def [](key) + @data ||= @dbman.restore + @data[key] + end + + # Set the session date for key +key+. + def []=(key, val) + @write_lock ||= true + @data ||= @dbman.restore + @data[key] = val + end + + # Store session data on the server. For some session storage types, + # this is a no-op. + def update + @dbman.update + end + + # Store session data on the server and close the session storage. + # For some session storage types, this is a no-op. + def close + @dbman.close + @dbprot.clear + end + + # Delete the session from storage. Also closes the storage. + # + # Note that the session's data is _not_ automatically deleted + # upon the session expiring. + def delete + @dbman.delete + @dbprot.clear + end + + # File-based session storage class. + # + # Implements session storage as a flat file of 'key=value' values. + # This storage type only works directly with String values; the + # user is responsible for converting other types to Strings when + # storing and from Strings when retrieving. + class FileStore + # Create a new FileStore instance. + # + # This constructor is used internally by CGI::Session. The + # user does not generally need to call it directly. + # + # +session+ is the session for which this instance is being + # created. The session id must only contain alphanumeric + # characters; automatically generated session ids observe + # this requirement. + # + # +option+ is a hash of options for the initialiser. The + # following options are recognised: + # + # tmpdir:: the directory to use for storing the FileStore + # file. Defaults to Dir::tmpdir (generally "/tmp" + # on Unix systems). + # prefix:: the prefix to add to the session id when generating + # the filename for this session's FileStore file. + # Defaults to the empty string. + # suffix:: the prefix to add to the session id when generating + # the filename for this session's FileStore file. + # Defaults to the empty string. + # + # This session's FileStore file will be created if it does + # not exist, or opened if it does. + def initialize(session, option={}) + dir = option['tmpdir'] || Dir::tmpdir + prefix = option['prefix'] || '' + suffix = option['suffix'] || '' + id = session.session_id + require 'digest/md5' + md5 = Digest::MD5.hexdigest(id)[0,16] + @path = dir+"/"+prefix+md5+suffix + if File::exist? @path + @hash = nil + else + unless session.new_session + raise CGI::Session::NoSession, "uninitialized session" + end + @hash = {} + end + end + + # Restore session state from the session's FileStore file. + # + # Returns the session state as a hash. + def restore + unless @hash + @hash = {} + begin + lockf = File.open(@path+".lock", "r") + lockf.flock File::LOCK_SH + f = File.open(@path, 'r') + for line in f + line.chomp! + k, v = line.split('=',2) + @hash[CGI::unescape(k)] = CGI::unescape(v) + end + ensure + f.close unless f.nil? + lockf.close if lockf + end + end + @hash + end + + # Save session state to the session's FileStore file. + def update + return unless @hash + begin + lockf = File.open(@path+".lock", File::CREAT|File::RDWR, 0600) + lockf.flock File::LOCK_EX + f = File.open(@path+".new", File::CREAT|File::TRUNC|File::WRONLY, 0600) + for k,v in @hash + f.printf "%s=%s\n", CGI::escape(k), CGI::escape(String(v)) + end + f.close + File.rename @path+".new", @path + ensure + f.close if f and !f.closed? + lockf.close if lockf + end + end + + # Update and close the session's FileStore file. + def close + update + end + + # Close and delete the session's FileStore file. + def delete + File::unlink @path+".lock" rescue nil + File::unlink @path+".new" rescue nil + File::unlink @path + rescue Errno::ENOENT + end + end + + # In-memory session storage class. + # + # Implements session storage as a global in-memory hash. Session + # data will only persist for as long as the ruby interpreter + # instance does. + class MemoryStore + GLOBAL_HASH_TABLE = {} #:nodoc: + + # Create a new MemoryStore instance. + # + # +session+ is the session this instance is associated with. + # +option+ is a list of initialisation options. None are + # currently recognised. + def initialize(session, option=nil) + @session_id = session.session_id + unless GLOBAL_HASH_TABLE.key?(@session_id) + unless session.new_session + raise CGI::Session::NoSession, "uninitialized session" + end + GLOBAL_HASH_TABLE[@session_id] = {} + end + end + + # Restore session state. + # + # Returns session data as a hash. + def restore + GLOBAL_HASH_TABLE[@session_id] + end + + # Update session state. + # + # A no-op. + def update + # don't need to update; hash is shared + end + + # Close session storage. + # + # A no-op. + def close + # don't need to close + end + + # Delete the session state. + def delete + GLOBAL_HASH_TABLE.delete(@session_id) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi/session/pstore.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi/session/pstore.rb new file mode 100644 index 00000000..bd93d0a6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/cgi/session/pstore.rb @@ -0,0 +1,111 @@ +# +# cgi/session/pstore.rb - persistent storage of marshalled session data +# +# Documentation: William Webber (william@williamwebber.com) +# +# == Overview +# +# This file provides the CGI::Session::PStore class, which builds +# persistent of session data on top of the pstore library. See +# cgi/session.rb for more details on session storage managers. + +require 'cgi/session' +require 'pstore' + +class CGI + class Session + # PStore-based session storage class. + # + # This builds upon the top-level PStore class provided by the + # library file pstore.rb. Session data is marshalled and stored + # in a file. File locking and transaction services are provided. + class PStore + # Create a new CGI::Session::PStore instance + # + # This constructor is used internally by CGI::Session. The + # user does not generally need to call it directly. + # + # +session+ is the session for which this instance is being + # created. The session id must only contain alphanumeric + # characters; automatically generated session ids observe + # this requirement. + # + # +option+ is a hash of options for the initialiser. The + # following options are recognised: + # + # tmpdir:: the directory to use for storing the PStore + # file. Defaults to Dir::tmpdir (generally "/tmp" + # on Unix systems). + # prefix:: the prefix to add to the session id when generating + # the filename for this session's PStore file. + # Defaults to the empty string. + # + # This session's PStore file will be created if it does + # not exist, or opened if it does. + def initialize(session, option={}) + dir = option['tmpdir'] || Dir::tmpdir + prefix = option['prefix'] || '' + id = session.session_id + require 'digest/md5' + md5 = Digest::MD5.hexdigest(id)[0,16] + path = dir+"/"+prefix+md5 + path.untaint + if File::exist?(path) + @hash = nil + else + unless session.new_session + raise CGI::Session::NoSession, "uninitialized session" + end + @hash = {} + end + @p = ::PStore.new(path) + @p.transaction do |p| + File.chmod(0600, p.path) + end + end + + # Restore session state from the session's PStore file. + # + # Returns the session state as a hash. + def restore + unless @hash + @p.transaction do + @hash = @p['hash'] || {} + end + end + @hash + end + + # Save session state to the session's PStore file. + def update + @p.transaction do + @p['hash'] = @hash + end + end + + # Update and close the session's PStore file. + def close + update + end + + # Close and delete the session's PStore file. + def delete + path = @p.path + File::unlink path + end + + end + end +end + +if $0 == __FILE__ + # :enddoc: + STDIN.reopen("/dev/null") + cgi = CGI.new + session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::PStore) + session['key'] = {'k' => 'v'} + puts session['key'].class + fail unless Hash === session['key'] + puts session['key'].inspect + fail unless session['key'].inspect == '{"k"=>"v"}' +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/complex.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/complex.rb new file mode 100644 index 00000000..9300f391 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/complex.rb @@ -0,0 +1,631 @@ +# +# complex.rb - +# $Release Version: 0.5 $ +# $Revision: 1.3 $ +# $Date: 1998/07/08 10:05:28 $ +# by Keiju ISHITSUKA(SHL Japan Inc.) +# +# ---- +# +# complex.rb implements the Complex class for complex numbers. Additionally, +# some methods in other Numeric classes are redefined or added to allow greater +# interoperability with Complex numbers. +# +# Complex numbers can be created in the following manner: +# - Complex(a, b) +# - Complex.polar(radius, theta) +# +# Additionally, note the following: +# - Complex::I (the mathematical constant i) +# - Numeric#im (e.g. 5.im -> 0+5i) +# +# The following +Math+ module methods are redefined to handle Complex arguments. +# They will work as normal with non-Complex arguments. +# sqrt exp cos sin tan log log10 +# cosh sinh tanh acos asin atan atan2 acosh asinh atanh +# + + +# +# Numeric is a built-in class on which Fixnum, Bignum, etc., are based. Here +# some methods are added so that all number types can be treated to some extent +# as Complex numbers. +# +class Numeric + # + # Returns a Complex number (0,self). + # + def im + Complex(0, self) + end + + # + # The real part of a complex number, i.e. self. + # + def real + self + end + + # + # The imaginary part of a complex number, i.e. 0. + # + def image + 0 + end + alias imag image + + # + # See Complex#arg. + # + def arg + if self >= 0 + return 0 + else + return Math::PI + end + end + alias angle arg + + # + # See Complex#polar. + # + def polar + return abs, arg + end + + # + # See Complex#conjugate (short answer: returns self). + # + def conjugate + self + end + alias conj conjugate +end + + +# +# Creates a Complex number. +a+ and +b+ should be Numeric. The result will be +# a+bi. +# +def Complex(a, b = 0) + if b == 0 and (a.kind_of?(Complex) or defined? Complex::Unify) + a + else + Complex.new( a.real-b.imag, a.imag+b.real ) + end +end + +# +# The complex number class. See complex.rb for an overview. +# +class Complex < Numeric + @RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-' + + undef step + + def Complex.generic?(other) # :nodoc: + other.kind_of?(Integer) or + other.kind_of?(Float) or + (defined?(Rational) and other.kind_of?(Rational)) + end + + # + # Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle). + # + def Complex.polar(r, theta) + Complex(r*Math.cos(theta), r*Math.sin(theta)) + end + + # + # Creates a +Complex+ number a+bi. + # + def Complex.new!(a, b=0) + new(a,b) + end + + def initialize(a, b) + raise TypeError, "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric + raise TypeError, "`#{a.inspect}' for 1st arg" if a.kind_of? Complex + raise TypeError, "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric + raise TypeError, "`#{b.inspect}' for 2nd arg" if b.kind_of? Complex + @real = a + @image = b + end + + # + # Addition with real or complex number. + # + def + (other) + if other.kind_of?(Complex) + re = @real + other.real + im = @image + other.image + Complex(re, im) + elsif Complex.generic?(other) + Complex(@real + other, @image) + else + x , y = other.coerce(self) + x + y + end + end + + # + # Subtraction with real or complex number. + # + def - (other) + if other.kind_of?(Complex) + re = @real - other.real + im = @image - other.image + Complex(re, im) + elsif Complex.generic?(other) + Complex(@real - other, @image) + else + x , y = other.coerce(self) + x - y + end + end + + # + # Multiplication with real or complex number. + # + def * (other) + if other.kind_of?(Complex) + re = @real*other.real - @image*other.image + im = @real*other.image + @image*other.real + Complex(re, im) + elsif Complex.generic?(other) + Complex(@real * other, @image * other) + else + x , y = other.coerce(self) + x * y + end + end + + # + # Division by real or complex number. + # + def / (other) + if other.kind_of?(Complex) + self*other.conjugate/other.abs2 + elsif Complex.generic?(other) + Complex(@real/other, @image/other) + else + x, y = other.coerce(self) + x/y + end + end + + # + # Raise this complex number to the given (real or complex) power. + # + def ** (other) + if other == 0 + return Complex(1) + end + if other.kind_of?(Complex) + r, theta = polar + ore = other.real + oim = other.image + nr = Math.exp!(ore*Math.log!(r) - oim * theta) + ntheta = theta*ore + oim*Math.log!(r) + Complex.polar(nr, ntheta) + elsif other.kind_of?(Integer) + if other > 0 + x = self + z = x + n = other - 1 + while n != 0 + while (div, mod = n.divmod(2) + mod == 0) + x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image) + n = div + end + z *= x + n -= 1 + end + z + else + if defined? Rational + (Rational(1) / self) ** -other + else + self ** Float(other) + end + end + elsif Complex.generic?(other) + r, theta = polar + Complex.polar(r**other, theta*other) + else + x, y = other.coerce(self) + x**y + end + end + + # + # Remainder after division by a real or complex number. + # + def % (other) + if other.kind_of?(Complex) + Complex(@real % other.real, @image % other.image) + elsif Complex.generic?(other) + Complex(@real % other, @image % other) + else + x , y = other.coerce(self) + x % y + end + end + +#-- +# def divmod(other) +# if other.kind_of?(Complex) +# rdiv, rmod = @real.divmod(other.real) +# idiv, imod = @image.divmod(other.image) +# return Complex(rdiv, idiv), Complex(rmod, rmod) +# elsif Complex.generic?(other) +# Complex(@real.divmod(other), @image.divmod(other)) +# else +# x , y = other.coerce(self) +# x.divmod(y) +# end +# end +#++ + + # + # Absolute value (aka modulus): distance from the zero point on the complex + # plane. + # + def abs + Math.hypot(@real, @image) + end + + # + # Square of the absolute value. + # + def abs2 + @real*@real + @image*@image + end + + # + # Argument (angle from (1,0) on the complex plane). + # + def arg + Math.atan2!(@image, @real) + end + alias angle arg + + # + # Returns the absolute value _and_ the argument. + # + def polar + return abs, arg + end + + # + # Complex conjugate (z + z.conjugate = 2 * z.real). + # + def conjugate + Complex(@real, -@image) + end + alias conj conjugate + + # + # Compares the absolute values of the two numbers. + # + def <=> (other) + self.abs <=> other.abs + end + + # + # Test for numerical equality (a == a + 0i). + # + def == (other) + if other.kind_of?(Complex) + @real == other.real and @image == other.image + elsif Complex.generic?(other) + @real == other and @image == 0 + else + other == self + end + end + + # + # Attempts to coerce +other+ to a Complex number. + # + def coerce(other) + if Complex.generic?(other) + return Complex.new!(other), self + else + super + end + end + + # + # FIXME + # + def denominator + @real.denominator.lcm(@image.denominator) + end + + # + # FIXME + # + def numerator + cd = denominator + Complex(@real.numerator*(cd/@real.denominator), + @image.numerator*(cd/@image.denominator)) + end + + # + # Standard string representation of the complex number. + # + def to_s + if @real != 0 + if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1 + if @image >= 0 + @real.to_s+"+("+@image.to_s+")i" + else + @real.to_s+"-("+(-@image).to_s+")i" + end + else + if @image >= 0 + @real.to_s+"+"+@image.to_s+"i" + else + @real.to_s+"-"+(-@image).to_s+"i" + end + end + else + if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1 + "("+@image.to_s+")i" + else + @image.to_s+"i" + end + end + end + + # + # Returns a hash code for the complex number. + # + def hash + @real.hash ^ @image.hash + end + + # + # Returns "Complex(real, image)". + # + def inspect + sprintf("Complex(%s, %s)", @real.inspect, @image.inspect) + end + + + # + # +I+ is the imaginary number. It exists at point (0,1) on the complex plane. + # + I = Complex(0,1) + + # The real part of a complex number. + attr :real + + # The imaginary part of a complex number. + attr :image + alias imag image + +end + + + + +module Math + alias sqrt! sqrt + alias exp! exp + alias log! log + alias log10! log10 + alias cos! cos + alias sin! sin + alias tan! tan + alias cosh! cosh + alias sinh! sinh + alias tanh! tanh + alias acos! acos + alias asin! asin + alias atan! atan + alias atan2! atan2 + alias acosh! acosh + alias asinh! asinh + alias atanh! atanh + + # Redefined to handle a Complex argument. + def sqrt(z) + if Complex.generic?(z) + if z >= 0 + sqrt!(z) + else + Complex(0,sqrt!(-z)) + end + else + if z.image < 0 + sqrt(z.conjugate).conjugate + else + r = z.abs + x = z.real + Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) ) + end + end + end + + # Redefined to handle a Complex argument. + def exp(z) + if Complex.generic?(z) + exp!(z) + else + Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image)) + end + end + + # Redefined to handle a Complex argument. + def cos(z) + if Complex.generic?(z) + cos!(z) + else + Complex(cos!(z.real)*cosh!(z.image), + -sin!(z.real)*sinh!(z.image)) + end + end + + # Redefined to handle a Complex argument. + def sin(z) + if Complex.generic?(z) + sin!(z) + else + Complex(sin!(z.real)*cosh!(z.image), + cos!(z.real)*sinh!(z.image)) + end + end + + # Redefined to handle a Complex argument. + def tan(z) + if Complex.generic?(z) + tan!(z) + else + sin(z)/cos(z) + end + end + + def sinh(z) + if Complex.generic?(z) + sinh!(z) + else + Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) ) + end + end + + def cosh(z) + if Complex.generic?(z) + cosh!(z) + else + Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) ) + end + end + + def tanh(z) + if Complex.generic?(z) + tanh!(z) + else + sinh(z)/cosh(z) + end + end + + # Redefined to handle a Complex argument. + def log(z) + if Complex.generic?(z) and z >= 0 + log!(z) + else + r, theta = z.polar + Complex(log!(r.abs), theta) + end + end + + # Redefined to handle a Complex argument. + def log10(z) + if Complex.generic?(z) + log10!(z) + else + log(z)/log!(10) + end + end + + def acos(z) + if Complex.generic?(z) and z >= -1 and z <= 1 + acos!(z) + else + -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) ) + end + end + + def asin(z) + if Complex.generic?(z) and z >= -1 and z <= 1 + asin!(z) + else + -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) ) + end + end + + def atan(z) + if Complex.generic?(z) + atan!(z) + else + 1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0 + end + end + + def atan2(y,x) + if Complex.generic?(y) and Complex.generic?(x) + atan2!(y,x) + else + -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) ) + end + end + + def acosh(z) + if Complex.generic?(z) and z >= 1 + acosh!(z) + else + log( z + sqrt(z*z-1.0) ) + end + end + + def asinh(z) + if Complex.generic?(z) + asinh!(z) + else + log( z + sqrt(1.0+z*z) ) + end + end + + def atanh(z) + if Complex.generic?(z) and z >= -1 and z <= 1 + atanh!(z) + else + log( (1.0+z) / (1.0-z) ) / 2.0 + end + end + + module_function :sqrt! + module_function :sqrt + module_function :exp! + module_function :exp + module_function :log! + module_function :log + module_function :log10! + module_function :log10 + module_function :cosh! + module_function :cosh + module_function :cos! + module_function :cos + module_function :sinh! + module_function :sinh + module_function :sin! + module_function :sin + module_function :tan! + module_function :tan + module_function :tanh! + module_function :tanh + module_function :acos! + module_function :acos + module_function :asin! + module_function :asin + module_function :atan! + module_function :atan + module_function :atan2! + module_function :atan2 + module_function :acosh! + module_function :acosh + module_function :asinh! + module_function :asinh + module_function :atanh! + module_function :atanh + +end + +# Documentation comments: +# - source: original (researched from pickaxe) +# - a couple of fixme's +# - RDoc output for Bignum etc. is a bit short, with nothing but an +# (undocumented) alias. No big deal. diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/csv.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/csv.rb new file mode 100644 index 00000000..5fb12142 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/csv.rb @@ -0,0 +1,992 @@ +# CSV -- module for generating/parsing CSV data. +# Copyright (C) 2000-2004 NAKAMURA, Hiroshi . + +# $Id: csv.rb 11708 2007-02-12 23:01:19Z shyouhei $ + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +class CSV + class IllegalFormatError < RuntimeError; end + + # deprecated + class Cell < String + def initialize(data = "", is_null = false) + super(is_null ? "" : data) + end + + def data + to_s + end + end + + # deprecated + class Row < Array + end + + # Open a CSV formatted file for reading or writing. + # + # For reading. + # + # EXAMPLE 1 + # CSV.open('csvfile.csv', 'r') do |row| + # p row + # end + # + # EXAMPLE 2 + # reader = CSV.open('csvfile.csv', 'r') + # row1 = reader.shift + # row2 = reader.shift + # if row2.empty? + # p 'row2 not find.' + # end + # reader.close + # + # ARGS + # filename: filename to parse. + # col_sep: Column separator. ?, by default. If you want to separate + # fields with semicolon, give ?; here. + # row_sep: Row separator. nil by default. nil means "\r\n or \n". If you + # want to separate records with \r, give ?\r here. + # + # RETURNS + # reader instance. To get parse result, see CSV::Reader#each. + # + # + # For writing. + # + # EXAMPLE 1 + # CSV.open('csvfile.csv', 'w') do |writer| + # writer << ['r1c1', 'r1c2'] + # writer << ['r2c1', 'r2c2'] + # writer << [nil, nil] + # end + # + # EXAMPLE 2 + # writer = CSV.open('csvfile.csv', 'w') + # writer << ['r1c1', 'r1c2'] << ['r2c1', 'r2c2'] << [nil, nil] + # writer.close + # + # ARGS + # filename: filename to generate. + # col_sep: Column separator. ?, by default. If you want to separate + # fields with semicolon, give ?; here. + # row_sep: Row separator. nil by default. nil means "\r\n or \n". If you + # want to separate records with \r, give ?\r here. + # + # RETURNS + # writer instance. See CSV::Writer#<< and CSV::Writer#add_row to know how + # to generate CSV string. + # + def CSV.open(path, mode, fs = nil, rs = nil, &block) + if mode == 'r' or mode == 'rb' + open_reader(path, mode, fs, rs, &block) + elsif mode == 'w' or mode == 'wb' + open_writer(path, mode, fs, rs, &block) + else + raise ArgumentError.new("'mode' must be 'r', 'rb', 'w', or 'wb'") + end + end + + def CSV.foreach(path, rs = nil, &block) + open_reader(path, 'r', ',', rs, &block) + end + + def CSV.read(path, length = nil, offset = nil) + CSV.parse(IO.read(path, length, offset)) + end + + def CSV.readlines(path, rs = nil) + reader = open_reader(path, 'r', ',', rs) + begin + reader.collect { |row| row } + ensure + reader.close + end + end + + def CSV.generate(path, fs = nil, rs = nil, &block) + open_writer(path, 'w', fs, rs, &block) + end + + # Parse lines from given string or stream. Return rows as an Array of Arrays. + def CSV.parse(str_or_readable, fs = nil, rs = nil, &block) + if File.exist?(str_or_readable) + STDERR.puts("CSV.parse(filename) is deprecated." + + " Use CSV.open(filename, 'r') instead.") + return open_reader(str_or_readable, 'r', fs, rs, &block) + end + if block + CSV::Reader.parse(str_or_readable, fs, rs) do |row| + yield(row) + end + nil + else + CSV::Reader.create(str_or_readable, fs, rs).collect { |row| row } + end + end + + # Parse a line from given string. Bear in mind it parses ONE LINE. Rest of + # the string is ignored for example "a,b\r\nc,d" => ['a', 'b'] and the + # second line 'c,d' is ignored. + # + # If you don't know whether a target string to parse is exactly 1 line or + # not, use CSV.parse_row instead of this method. + def CSV.parse_line(src, fs = nil, rs = nil) + fs ||= ',' + if fs.is_a?(Fixnum) + fs = fs.chr + end + if !rs.nil? and rs.is_a?(Fixnum) + rs = rs.chr + end + idx = 0 + res_type = :DT_COLSEP + row = [] + begin + while res_type == :DT_COLSEP + res_type, idx, cell = parse_body(src, idx, fs, rs) + row << cell + end + rescue IllegalFormatError + return [] + end + row + end + + # Create a line from cells. each cell is stringified by to_s. + def CSV.generate_line(row, fs = nil, rs = nil) + if row.size == 0 + return '' + end + fs ||= ',' + if fs.is_a?(Fixnum) + fs = fs.chr + end + if !rs.nil? and rs.is_a?(Fixnum) + rs = rs.chr + end + res_type = :DT_COLSEP + result_str = '' + idx = 0 + while true + generate_body(row[idx], result_str, fs, rs) + idx += 1 + if (idx == row.size) + break + end + generate_separator(:DT_COLSEP, result_str, fs, rs) + end + result_str + end + + # Parse a line from string. Consider using CSV.parse_line instead. + # To parse lines in CSV string, see EXAMPLE below. + # + # EXAMPLE + # src = "a,b\r\nc,d\r\ne,f" + # idx = 0 + # begin + # parsed = [] + # parsed_cells, idx = CSV.parse_row(src, idx, parsed) + # puts "Parsed #{ parsed_cells } cells." + # p parsed + # end while parsed_cells > 0 + # + # ARGS + # src: a CSV data to be parsed. Must respond '[](idx)'. + # src[](idx) must return a char. (Not a string such as 'a', but 97). + # src[](idx_out_of_bounds) must return nil. A String satisfies this + # requirement. + # idx: index of parsing location of 'src'. 0 origin. + # out_dev: buffer for parsed cells. Must respond '<<(aString)'. + # col_sep: Column separator. ?, by default. If you want to separate + # fields with semicolon, give ?; here. + # row_sep: Row separator. nil by default. nil means "\r\n or \n". If you + # want to separate records with \r, give ?\r here. + # + # RETURNS + # parsed_cells: num of parsed cells. + # idx: index of next parsing location of 'src'. + # + def CSV.parse_row(src, idx, out_dev, fs = nil, rs = nil) + fs ||= ',' + if fs.is_a?(Fixnum) + fs = fs.chr + end + if !rs.nil? and rs.is_a?(Fixnum) + rs = rs.chr + end + idx_backup = idx + parsed_cells = 0 + res_type = :DT_COLSEP + begin + while res_type != :DT_ROWSEP + res_type, idx, cell = parse_body(src, idx, fs, rs) + if res_type == :DT_EOS + if idx == idx_backup #((parsed_cells == 0) and cell.nil?) + return 0, 0 + end + res_type = :DT_ROWSEP + end + parsed_cells += 1 + out_dev << cell + end + rescue IllegalFormatError + return 0, 0 + end + return parsed_cells, idx + end + + # Convert a line from cells data to string. Consider using CSV.generate_line + # instead. To generate multi-row CSV string, see EXAMPLE below. + # + # EXAMPLE + # row1 = ['a', 'b'] + # row2 = ['c', 'd'] + # row3 = ['e', 'f'] + # src = [row1, row2, row3] + # buf = '' + # src.each do |row| + # parsed_cells = CSV.generate_row(row, 2, buf) + # puts "Created #{ parsed_cells } cells." + # end + # p buf + # + # ARGS + # src: an Array of String to be converted to CSV string. Must respond to + # 'size' and '[](idx)'. src[idx] must return String. + # cells: num of cells in a line. + # out_dev: buffer for generated CSV string. Must respond to '<<(string)'. + # col_sep: Column separator. ?, by default. If you want to separate + # fields with semicolon, give ?; here. + # row_sep: Row separator. nil by default. nil means "\r\n or \n". If you + # want to separate records with \r, give ?\r here. + # + # RETURNS + # parsed_cells: num of converted cells. + # + def CSV.generate_row(src, cells, out_dev, fs = nil, rs = nil) + fs ||= ',' + if fs.is_a?(Fixnum) + fs = fs.chr + end + if !rs.nil? and rs.is_a?(Fixnum) + rs = rs.chr + end + src_size = src.size + if (src_size == 0) + if cells == 0 + generate_separator(:DT_ROWSEP, out_dev, fs, rs) + end + return 0 + end + res_type = :DT_COLSEP + parsed_cells = 0 + generate_body(src[parsed_cells], out_dev, fs, rs) + parsed_cells += 1 + while ((parsed_cells < cells) and (parsed_cells != src_size)) + generate_separator(:DT_COLSEP, out_dev, fs, rs) + generate_body(src[parsed_cells], out_dev, fs, rs) + parsed_cells += 1 + end + if (parsed_cells == cells) + generate_separator(:DT_ROWSEP, out_dev, fs, rs) + else + generate_separator(:DT_COLSEP, out_dev, fs, rs) + end + parsed_cells + end + + # Private class methods. + class << self + private + + def open_reader(path, mode, fs, rs, &block) + file = File.open(path, mode) + if block + begin + CSV::Reader.parse(file, fs, rs) do |row| + yield(row) + end + ensure + file.close + end + nil + else + reader = CSV::Reader.create(file, fs, rs) + reader.close_on_terminate + reader + end + end + + def open_writer(path, mode, fs, rs, &block) + file = File.open(path, mode) + if block + begin + CSV::Writer.generate(file, fs, rs) do |writer| + yield(writer) + end + ensure + file.close + end + nil + else + writer = CSV::Writer.create(file, fs, rs) + writer.close_on_terminate + writer + end + end + + def parse_body(src, idx, fs, rs) + fs_str = fs + fs_size = fs_str.size + rs_str = rs || "\n" + rs_size = rs_str.size + fs_idx = rs_idx = 0 + cell = Cell.new + state = :ST_START + quoted = cr = false + c = nil + last_idx = idx + while c = src[idx] + unless quoted + fschar = (c == fs_str[fs_idx]) + rschar = (c == rs_str[rs_idx]) + # simple 1 char backtrack + if !fschar and c == fs_str[0] + fs_idx = 0 + fschar = true + if state == :ST_START + state = :ST_DATA + elsif state == :ST_QUOTE + raise IllegalFormatError + end + end + if !rschar and c == rs_str[0] + rs_idx = 0 + rschar = true + if state == :ST_START + state = :ST_DATA + elsif state == :ST_QUOTE + raise IllegalFormatError + end + end + end + if c == ?" + fs_idx = rs_idx = 0 + if cr + raise IllegalFormatError + end + cell << src[last_idx, (idx - last_idx)] + last_idx = idx + if state == :ST_DATA + if quoted + last_idx += 1 + quoted = false + state = :ST_QUOTE + else + raise IllegalFormatError + end + elsif state == :ST_QUOTE + cell << c.chr + last_idx += 1 + quoted = true + state = :ST_DATA + else # :ST_START + quoted = true + last_idx += 1 + state = :ST_DATA + end + elsif fschar or rschar + if fschar + fs_idx += 1 + end + if rschar + rs_idx += 1 + end + sep = nil + if fs_idx == fs_size + if state == :ST_START and rs_idx > 0 and fs_idx < rs_idx + state = :ST_DATA + end + cell << src[last_idx, (idx - last_idx - (fs_size - 1))] + last_idx = idx + fs_idx = rs_idx = 0 + if cr + raise IllegalFormatError + end + sep = :DT_COLSEP + elsif rs_idx == rs_size + if state == :ST_START and fs_idx > 0 and rs_idx < fs_idx + state = :ST_DATA + end + if !(rs.nil? and cr) + cell << src[last_idx, (idx - last_idx - (rs_size - 1))] + last_idx = idx + end + fs_idx = rs_idx = 0 + sep = :DT_ROWSEP + end + if sep + if state == :ST_DATA + return sep, idx + 1, cell; + elsif state == :ST_QUOTE + return sep, idx + 1, cell; + else # :ST_START + return sep, idx + 1, nil + end + end + elsif rs.nil? and c == ?\r + # special \r treatment for backward compatibility + fs_idx = rs_idx = 0 + if cr + raise IllegalFormatError + end + cell << src[last_idx, (idx - last_idx)] + last_idx = idx + if quoted + state = :ST_DATA + else + cr = true + end + else + fs_idx = rs_idx = 0 + if state == :ST_DATA or state == :ST_START + if cr + raise IllegalFormatError + end + state = :ST_DATA + else # :ST_QUOTE + raise IllegalFormatError + end + end + idx += 1 + end + if state == :ST_START + if fs_idx > 0 or rs_idx > 0 + state = :ST_DATA + else + return :DT_EOS, idx, nil + end + elsif quoted + raise IllegalFormatError + elsif cr + raise IllegalFormatError + end + cell << src[last_idx, (idx - last_idx)] + last_idx = idx + return :DT_EOS, idx, cell + end + + def generate_body(cell, out_dev, fs, rs) + if cell.nil? + # empty + else + cell = cell.to_s + row_data = cell.dup + if (row_data.gsub!('"', '""') or + row_data.index(fs) or + (rs and row_data.index(rs)) or + (/[\r\n]/ =~ row_data) or + (cell.empty?)) + out_dev << '"' << row_data << '"' + else + out_dev << row_data + end + end + end + + def generate_separator(type, out_dev, fs, rs) + case type + when :DT_COLSEP + out_dev << fs + when :DT_ROWSEP + out_dev << (rs || "\n") + end + end + end + + + # CSV formatted string/stream reader. + # + # EXAMPLE + # read CSV lines untill the first column is 'stop'. + # + # CSV::Reader.parse(File.open('bigdata', 'rb')) do |row| + # p row + # break if !row[0].is_null && row[0].data == 'stop' + # end + # + class Reader + include Enumerable + + # Parse CSV data and get lines. Given block is called for each parsed row. + # Block value is always nil. Rows are not cached for performance reason. + def Reader.parse(str_or_readable, fs = ',', rs = nil, &block) + reader = Reader.create(str_or_readable, fs, rs) + if block + reader.each do |row| + yield(row) + end + reader.close + nil + else + reader + end + end + + # Returns reader instance. + def Reader.create(str_or_readable, fs = ',', rs = nil) + case str_or_readable + when IO + IOReader.new(str_or_readable, fs, rs) + when String + StringReader.new(str_or_readable, fs, rs) + else + IOReader.new(str_or_readable, fs, rs) + end + end + + def each + while true + row = [] + parsed_cells = get_row(row) + if parsed_cells == 0 + break + end + yield(row) + end + nil + end + + def shift + row = [] + parsed_cells = get_row(row) + row + end + + def close + terminate + end + + private + + def initialize(dev) + raise RuntimeError.new('Do not instanciate this class directly.') + end + + def get_row(row) + raise NotImplementedError.new('Method get_row must be defined in a derived class.') + end + + def terminate + # Define if needed. + end + end + + + class StringReader < Reader + def initialize(string, fs = ',', rs = nil) + @fs = fs + @rs = rs + @dev = string + @idx = 0 + if @dev[0, 3] == "\xef\xbb\xbf" + @idx += 3 + end + end + + private + + def get_row(row) + parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs) + if parsed_cells == 0 and next_idx == 0 and @idx != @dev.size + raise IllegalFormatError.new + end + @idx = next_idx + parsed_cells + end + end + + + class IOReader < Reader + def initialize(io, fs = ',', rs = nil) + @io = io + @fs = fs + @rs = rs + @dev = CSV::IOBuf.new(@io) + @idx = 0 + if @dev[0] == 0xef and @dev[1] == 0xbb and @dev[2] == 0xbf + @idx += 3 + end + @close_on_terminate = false + end + + # Tell this reader to close the IO when terminated (Triggered by invoking + # CSV::IOReader#close). + def close_on_terminate + @close_on_terminate = true + end + + private + + def get_row(row) + parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs) + if parsed_cells == 0 and next_idx == 0 and !@dev.is_eos? + raise IllegalFormatError.new + end + dropped = @dev.drop(next_idx) + @idx = next_idx - dropped + parsed_cells + end + + def terminate + if @close_on_terminate + @io.close + end + + if @dev + @dev.close + end + end + end + + + # CSV formatted string/stream writer. + # + # EXAMPLE + # Write rows to 'csvout' file. + # + # outfile = File.open('csvout', 'wb') + # CSV::Writer.generate(outfile) do |csv| + # csv << ['c1', nil, '', '"', "\r\n", 'c2'] + # ... + # end + # + # outfile.close + # + class Writer + # Given block is called with the writer instance. str_or_writable must + # handle '<<(string)'. + def Writer.generate(str_or_writable, fs = ',', rs = nil, &block) + writer = Writer.create(str_or_writable, fs, rs) + if block + yield(writer) + writer.close + nil + else + writer + end + end + + # str_or_writable must handle '<<(string)'. + def Writer.create(str_or_writable, fs = ',', rs = nil) + BasicWriter.new(str_or_writable, fs, rs) + end + + # dump CSV stream to the device. argument must be an Array of String. + def <<(row) + CSV.generate_row(row, row.size, @dev, @fs, @rs) + self + end + alias add_row << + + def close + terminate + end + + private + + def initialize(dev) + raise RuntimeError.new('Do not instanciate this class directly.') + end + + def terminate + # Define if needed. + end + end + + + class BasicWriter < Writer + def initialize(str_or_writable, fs = ',', rs = nil) + @fs = fs + @rs = rs + @dev = str_or_writable + @close_on_terminate = false + end + + # Tell this writer to close the IO when terminated (Triggered by invoking + # CSV::BasicWriter#close). + def close_on_terminate + @close_on_terminate = true + end + + private + + def terminate + if @close_on_terminate + @dev.close + end + end + end + +private + + # Buffered stream. + # + # EXAMPLE 1 -- an IO. + # class MyBuf < StreamBuf + # # Do initialize myself before a super class. Super class might call my + # # method 'read'. (Could be awful for C++ user. :-) + # def initialize(s) + # @s = s + # super() + # end + # + # # define my own 'read' method. + # # CAUTION: Returning nil means EnfOfStream. + # def read(size) + # @s.read(size) + # end + # + # # release buffers. in Ruby which has GC, you do not have to call this... + # def terminate + # @s = nil + # super() + # end + # end + # + # buf = MyBuf.new(STDIN) + # my_str = '' + # p buf[0, 0] # => '' (null string) + # p buf[0] # => 97 (char code of 'a') + # p buf[0, 1] # => 'a' + # my_str = buf[0, 5] + # p my_str # => 'abcde' (5 chars) + # p buf[0, 6] # => "abcde\n" (6 chars) + # p buf[0, 7] # => "abcde\n" (6 chars) + # p buf.drop(3) # => 3 (dropped chars) + # p buf.get(0, 2) # => 'de' (2 chars) + # p buf.is_eos? # => false (is not EOS here) + # p buf.drop(5) # => 3 (dropped chars) + # p buf.is_eos? # => true (is EOS here) + # p buf[0] # => nil (is EOS here) + # + # EXAMPLE 2 -- String. + # This is a conceptual example. No pros with this. + # + # class StrBuf < StreamBuf + # def initialize(s) + # @str = s + # @idx = 0 + # super() + # end + # + # def read(size) + # str = @str[@idx, size] + # @idx += str.size + # str + # end + # end + # + class StreamBuf + # get a char or a partial string from the stream. + # idx: index of a string to specify a start point of a string to get. + # unlike String instance, idx < 0 returns nil. + # n: size of a string to get. + # returns char at idx if n == nil. + # returns a partial string, from idx to (idx + n) if n != nil. at EOF, + # the string size could not equal to arg n. + def [](idx, n = nil) + if idx < 0 + return nil + end + if (idx_is_eos?(idx)) + if n and (@offset + idx == buf_size(@cur_buf)) + # Like a String, 'abc'[4, 1] returns nil and + # 'abc'[3, 1] returns '' not nil. + return '' + else + return nil + end + end + my_buf = @cur_buf + my_offset = @offset + next_idx = idx + while (my_offset + next_idx >= buf_size(my_buf)) + if (my_buf == @buf_tail_idx) + unless add_buf + break + end + end + next_idx = my_offset + next_idx - buf_size(my_buf) + my_buf += 1 + my_offset = 0 + end + loc = my_offset + next_idx + if !n + return @buf_list[my_buf][loc] # Fixnum of char code. + elsif (loc + n - 1 < buf_size(my_buf)) + return @buf_list[my_buf][loc, n] # String. + else # should do loop insted of (tail) recursive call... + res = @buf_list[my_buf][loc, BufSize] + size_added = buf_size(my_buf) - loc + if size_added > 0 + idx += size_added + n -= size_added + ret = self[idx, n] + if ret + res << ret + end + end + return res + end + end + alias get [] + + # drop a string from the stream. + # returns dropped size. at EOF, dropped size might not equals to arg n. + # Once you drop the head of the stream, access to the dropped part via [] + # or get returns nil. + def drop(n) + if is_eos? + return 0 + end + size_dropped = 0 + while (n > 0) + if !@is_eos or (@cur_buf != @buf_tail_idx) + if (@offset + n < buf_size(@cur_buf)) + size_dropped += n + @offset += n + n = 0 + else + size = buf_size(@cur_buf) - @offset + size_dropped += size + n -= size + @offset = 0 + unless rel_buf + unless add_buf + break + end + @cur_buf = @buf_tail_idx + end + end + end + end + size_dropped + end + + def is_eos? + return idx_is_eos?(0) + end + + # WARN: Do not instantiate this class directly. Define your own class + # which derives this class and define 'read' instance method. + def initialize + @buf_list = [] + @cur_buf = @buf_tail_idx = -1 + @offset = 0 + @is_eos = false + add_buf + @cur_buf = @buf_tail_idx + end + + protected + + def terminate + while (rel_buf); end + end + + # protected method 'read' must be defined in derived classes. + # CAUTION: Returning a string which size is not equal to 'size' means + # EnfOfStream. When it is not at EOS, you must block the callee, try to + # read and return the sized string. + def read(size) # raise EOFError + raise NotImplementedError.new('Method read must be defined in a derived class.') + end + + private + + def buf_size(idx) + @buf_list[idx].size + end + + def add_buf + if @is_eos + return false + end + begin + str_read = read(BufSize) + rescue EOFError + str_read = nil + rescue + terminate + raise + end + if str_read.nil? + @is_eos = true + @buf_list.push('') + @buf_tail_idx += 1 + false + else + @buf_list.push(str_read) + @buf_tail_idx += 1 + true + end + end + + def rel_buf + if (@cur_buf < 0) + return false + end + @buf_list[@cur_buf] = nil + if (@cur_buf == @buf_tail_idx) + @cur_buf = -1 + return false + else + @cur_buf += 1 + return true + end + end + + def idx_is_eos?(idx) + (@is_eos and ((@cur_buf < 0) or (@cur_buf == @buf_tail_idx))) + end + + BufSize = 1024 * 8 + end + + # Buffered IO. + # + # EXAMPLE + # # File 'bigdata' could be a giga-byte size one! + # buf = CSV::IOBuf.new(File.open('bigdata', 'rb')) + # CSV::Reader.new(buf).each do |row| + # p row + # break if row[0].data == 'admin' + # end + # + class IOBuf < StreamBuf + def initialize(s) + @s = s + super() + end + + def close + terminate + end + + private + + def read(size) + @s.read(size) + end + + def terminate + super() + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date.rb new file mode 100644 index 00000000..1de2383b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date.rb @@ -0,0 +1,1707 @@ +# +# date.rb - date and time library +# +# Author: Tadayoshi Funaba 1998-2006 +# +# Documentation: William Webber +# +#-- +# $Id: date.rb,v 2.33 2007-12-22 14:41:34+09 tadf Exp $ +#++ +# +# == Overview +# +# This file provides two classes for working with +# dates and times. +# +# The first class, Date, represents dates. +# It works with years, months, weeks, and days. +# See the Date class documentation for more details. +# +# The second, DateTime, extends Date to include hours, +# minutes, seconds, and fractions of a second. It +# provides basic support for time zones. See the +# DateTime class documentation for more details. +# +# === Ways of calculating the date. +# +# In common usage, the date is reckoned in years since or +# before the Common Era (CE/BCE, also known as AD/BC), then +# as a month and day-of-the-month within the current year. +# This is known as the *Civil* *Date*, and abbreviated +# as +civil+ in the Date class. +# +# Instead of year, month-of-the-year, and day-of-the-month, +# the date can also be reckoned in terms of year and +# day-of-the-year. This is known as the *Ordinal* *Date*, +# and is abbreviated as +ordinal+ in the Date class. (Note +# that referring to this as the Julian date is incorrect.) +# +# The date can also be reckoned in terms of year, week-of-the-year, +# and day-of-the-week. This is known as the *Commercial* +# *Date*, and is abbreviated as +commercial+ in the +# Date class. The commercial week runs Monday (day-of-the-week +# 1) to Sunday (day-of-the-week 7), in contrast to the civil +# week which runs Sunday (day-of-the-week 0) to Saturday +# (day-of-the-week 6). The first week of the commercial year +# starts on the Monday on or before January 1, and the commercial +# year itself starts on this Monday, not January 1. +# +# For scientific purposes, it is convenient to refer to a date +# simply as a day count, counting from an arbitrary initial +# day. The date first chosen for this was January 1, 4713 BCE. +# A count of days from this date is the *Julian* *Day* *Number* +# or *Julian* *Date*, which is abbreviated as +jd+ in the +# Date class. This is in local time, and counts from midnight +# on the initial day. The stricter usage is in UTC, and counts +# from midday on the initial day. This is referred to in the +# Date class as the *Astronomical* *Julian* *Day* *Number*, and +# abbreviated as +ajd+. In the Date class, the Astronomical +# Julian Day Number includes fractional days. +# +# Another absolute day count is the *Modified* *Julian* *Day* +# *Number*, which takes November 17, 1858 as its initial day. +# This is abbreviated as +mjd+ in the Date class. There +# is also an *Astronomical* *Modified* *Julian* *Day* *Number*, +# which is in UTC and includes fractional days. This is +# abbreviated as +amjd+ in the Date class. Like the Modified +# Julian Day Number (and unlike the Astronomical Julian +# Day Number), it counts from midnight. +# +# Alternative calendars such as the Chinese Lunar Calendar, +# the Islamic Calendar, or the French Revolutionary Calendar +# are not supported by the Date class; nor are calendars that +# are based on an Era different from the Common Era, such as +# the Japanese Imperial Calendar. +# +# === Calendar Reform +# +# The standard civil year is 365 days long. However, the +# solar year is fractionally longer than this. To account +# for this, a *leap* *year* is occasionally inserted. This +# is a year with 366 days, the extra day falling on February 29. +# In the early days of the civil calendar, every fourth +# year without exception was a leap year. This way of +# reckoning leap years is the *Julian* *Calendar*. +# +# However, the solar year is marginally shorter than 365 1/4 +# days, and so the *Julian* *Calendar* gradually ran slow +# over the centuries. To correct this, every 100th year +# (but not every 400th year) was excluded as a leap year. +# This way of reckoning leap years, which we use today, is +# the *Gregorian* *Calendar*. +# +# The Gregorian Calendar was introduced at different times +# in different regions. The day on which it was introduced +# for a particular region is the *Day* *of* *Calendar* +# *Reform* for that region. This is abbreviated as +sg+ +# (for Start of Gregorian calendar) in the Date class. +# +# Two such days are of particular +# significance. The first is October 15, 1582, which was +# the Day of Calendar Reform for Italy and most Catholic +# countries. The second is September 14, 1752, which was +# the Day of Calendar Reform for England and its colonies +# (including what is now the United States). These two +# dates are available as the constants Date::ITALY and +# Date::ENGLAND, respectively. (By comparison, Germany and +# Holland, less Catholic than Italy but less stubborn than +# England, changed over in 1698; Sweden in 1753; Russia not +# till 1918, after the Revolution; and Greece in 1923. Many +# Orthodox churches still use the Julian Calendar. A complete +# list of Days of Calendar Reform can be found at +# http://www.polysyllabic.com/GregConv.html.) +# +# Switching from the Julian to the Gregorian calendar +# involved skipping a number of days to make up for the +# accumulated lag, and the later the switch was (or is) +# done, the more days need to be skipped. So in 1582 in Italy, +# 4th October was followed by 15th October, skipping 10 days; in 1752 +# in England, 2nd September was followed by 14th September, skipping +# 11 days; and if I decided to switch from Julian to Gregorian +# Calendar this midnight, I would go from 27th July 2003 (Julian) +# today to 10th August 2003 (Gregorian) tomorrow, skipping +# 13 days. The Date class is aware of this gap, and a supposed +# date that would fall in the middle of it is regarded as invalid. +# +# The Day of Calendar Reform is relevant to all date representations +# involving years. It is not relevant to the Julian Day Numbers, +# except for converting between them and year-based representations. +# +# In the Date and DateTime classes, the Day of Calendar Reform or +# +sg+ can be specified a number of ways. First, it can be as +# the Julian Day Number of the Day of Calendar Reform. Second, +# it can be using the constants Date::ITALY or Date::ENGLAND; these +# are in fact the Julian Day Numbers of the Day of Calendar Reform +# of the respective regions. Third, it can be as the constant +# Date::JULIAN, which means to always use the Julian Calendar. +# Finally, it can be as the constant Date::GREGORIAN, which means +# to always use the Gregorian Calendar. +# +# Note: in the Julian Calendar, New Years Day was March 25. The +# Date class does not follow this convention. +# +# === Time Zones +# +# DateTime objects support a simple representation +# of time zones. Time zones are represented as an offset +# from UTC, as a fraction of a day. This offset is the +# how much local time is later (or earlier) than UTC. +# UTC offset 0 is centred on England (also known as GMT). +# As you travel east, the offset increases until you +# reach the dateline in the middle of the Pacific Ocean; +# as you travel west, the offset decreases. This offset +# is abbreviated as +of+ in the Date class. +# +# This simple representation of time zones does not take +# into account the common practice of Daylight Savings +# Time or Summer Time. +# +# Most DateTime methods return the date and the +# time in local time. The two exceptions are +# #ajd() and #amjd(), which return the date and time +# in UTC time, including fractional days. +# +# The Date class does not support time zone offsets, in that +# there is no way to create a Date object with a time zone. +# However, methods of the Date class when used by a +# DateTime instance will use the time zone offset of this +# instance. +# +# == Examples of use +# +# === Print out the date of every Sunday between two dates. +# +# def print_sundays(d1, d2) +# d1 +=1 while (d1.wday != 0) +# d1.step(d2, 7) do |date| +# puts "#{Date::MONTHNAMES[date.mon]} #{date.day}" +# end +# end +# +# print_sundays(Date::civil(2003, 4, 8), Date::civil(2003, 5, 23)) +# +# === Calculate how many seconds to go till midnight on New Year's Day. +# +# def secs_to_new_year(now = DateTime::now()) +# new_year = DateTime.new(now.year + 1, 1, 1) +# dif = new_year - now +# hours, mins, secs, ignore_fractions = Date::day_fraction_to_time(dif) +# return hours * 60 * 60 + mins * 60 + secs +# end +# +# puts secs_to_new_year() + +require 'rational' +require 'date/format' + +# Class representing a date. +# +# See the documentation to the file date.rb for an overview. +# +# Internally, the date is represented as an Astronomical +# Julian Day Number, +ajd+. The Day of Calendar Reform, +sg+, is +# also stored, for conversions to other date formats. (There +# is also an +of+ field for a time zone offset, but this +# is only for the use of the DateTime subclass.) +# +# A new Date object is created using one of the object creation +# class methods named after the corresponding date format, and the +# arguments appropriate to that date format; for instance, +# Date::civil() (aliased to Date::new()) with year, month, +# and day-of-month, or Date::ordinal() with year and day-of-year. +# All of these object creation class methods also take the +# Day of Calendar Reform as an optional argument. +# +# Date objects are immutable once created. +# +# Once a Date has been created, date values +# can be retrieved for the different date formats supported +# using instance methods. For instance, #mon() gives the +# Civil month, #cwday() gives the Commercial day of the week, +# and #yday() gives the Ordinal day of the year. Date values +# can be retrieved in any format, regardless of what format +# was used to create the Date instance. +# +# The Date class includes the Comparable module, allowing +# date objects to be compared and sorted, ranges of dates +# to be created, and so forth. +class Date + + include Comparable + + # Full month names, in English. Months count from 1 to 12; a + # month's numerical representation indexed into this array + # gives the name of that month (hence the first element is nil). + MONTHNAMES = [nil] + %w(January February March April May June July + August September October November December) + + # Full names of days of the week, in English. Days of the week + # count from 0 to 6 (except in the commercial week); a day's numerical + # representation indexed into this array gives the name of that day. + DAYNAMES = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) + + # Abbreviated month names, in English. + ABBR_MONTHNAMES = [nil] + %w(Jan Feb Mar Apr May Jun + Jul Aug Sep Oct Nov Dec) + + # Abbreviated day names, in English. + ABBR_DAYNAMES = %w(Sun Mon Tue Wed Thu Fri Sat) + + [MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYNAMES].each do |xs| + xs.each{|x| x.freeze unless x.nil?}.freeze + end + + class Infinity < Numeric # :nodoc: + + include Comparable + + def initialize(d=1) @d = d <=> 0 end + + def d() @d end + + protected :d + + def zero? () false end + def finite? () false end + def infinite? () d.nonzero? end + def nan? () d.zero? end + + def abs() self.class.new end + + def -@ () self.class.new(-d) end + def +@ () self.class.new(+d) end + + def <=> (other) + case other + when Infinity; d <=> other.d + when Numeric; d + else + begin + l, r = other.coerce(self) + return l <=> r + rescue NoMethodError + end + end + nil + end + + def coerce(other) + case other + when Numeric; return -d, d + else + super + end + end + + end + + # The Julian Day Number of the Day of Calendar Reform for Italy + # and the Catholic countries. + ITALY = 2299161 # 1582-10-15 + + # The Julian Day Number of the Day of Calendar Reform for England + # and her Colonies. + ENGLAND = 2361222 # 1752-09-14 + + # A constant used to indicate that a Date should always use the + # Julian calendar. + JULIAN = Infinity.new + + # A constant used to indicate that a Date should always use the + # Gregorian calendar. + GREGORIAN = -Infinity.new + + UNIXEPOCH = 2440588 # 1970-01-01 :nodoc: + + # Does a given Julian Day Number fall inside the old-style (Julian) + # calendar? + # + # +jd+ is the Julian Day Number in question. +sg+ may be Date::GREGORIAN, + # in which case the answer is false; it may be Date::JULIAN, in which case + # the answer is true; or it may a number representing the Day of + # Calendar Reform. Date::ENGLAND and Date::ITALY are two possible such + # days. + + def self.julian? (jd, sg) + case sg + when Numeric + jd < sg + else + if $VERBOSE + warn("#{caller.shift.sub(/:in .*/, '')}: " \ +"warning: do not use non-numerical object as julian day number anymore") + end + not sg + end + end + + # Does a given Julian Day Number fall inside the new-style (Gregorian) + # calendar? + # + # The reverse of self.os? See the documentation for that method for + # more details. + def self.gregorian? (jd, sg) !julian?(jd, sg) end + + def self.fix_style(jd, sg) # :nodoc: + if julian?(jd, sg) + then JULIAN + else GREGORIAN end + end + + private_class_method :fix_style + + # Convert an Ordinal Date to a Julian Day Number. + # + # +y+ and +d+ are the year and day-of-year to convert. + # +sg+ specifies the Day of Calendar Reform. + # + # Returns the corresponding Julian Day Number. + def self.ordinal_to_jd(y, d, sg=GREGORIAN) + civil_to_jd(y, 1, d, sg) + end + + # Convert a Julian Day Number to an Ordinal Date. + # + # +jd+ is the Julian Day Number to convert. + # +sg+ specifies the Day of Calendar Reform. + # + # Returns the corresponding Ordinal Date as + # [year, day_of_year] + def self.jd_to_ordinal(jd, sg=GREGORIAN) + y = jd_to_civil(jd, sg)[0] + doy = jd - civil_to_jd(y - 1, 12, 31, fix_style(jd, sg)) + return y, doy + end + + # Convert a Civil Date to a Julian Day Number. + # +y+, +m+, and +d+ are the year, month, and day of the + # month. +sg+ specifies the Day of Calendar Reform. + # + # Returns the corresponding Julian Day Number. + def self.civil_to_jd(y, m, d, sg=GREGORIAN) + if m <= 2 + y -= 1 + m += 12 + end + a = (y / 100.0).floor + b = 2 - a + (a / 4.0).floor + jd = (365.25 * (y + 4716)).floor + + (30.6001 * (m + 1)).floor + + d + b - 1524 + if julian?(jd, sg) + jd -= b + end + jd + end + + # Convert a Julian Day Number to a Civil Date. +jd+ is + # the Julian Day Number. +sg+ specifies the Day of + # Calendar Reform. + # + # Returns the corresponding [year, month, day_of_month] + # as a three-element array. + def self.jd_to_civil(jd, sg=GREGORIAN) + if julian?(jd, sg) + a = jd + else + x = ((jd - 1867216.25) / 36524.25).floor + a = jd + 1 + x - (x / 4.0).floor + end + b = a + 1524 + c = ((b - 122.1) / 365.25).floor + d = (365.25 * c).floor + e = ((b - d) / 30.6001).floor + dom = b - d - (30.6001 * e).floor + if e <= 13 + m = e - 1 + y = c - 4716 + else + m = e - 13 + y = c - 4715 + end + return y, m, dom + end + + # Convert a Commercial Date to a Julian Day Number. + # + # +y+, +w+, and +d+ are the (commercial) year, week of the year, + # and day of the week of the Commercial Date to convert. + # +sg+ specifies the Day of Calendar Reform. + def self.commercial_to_jd(y, w, d, ns=GREGORIAN) + jd = civil_to_jd(y, 1, 4, ns) + (jd - (((jd - 1) + 1) % 7)) + + 7 * (w - 1) + + (d - 1) + end + + # Convert a Julian Day Number to a Commercial Date + # + # +jd+ is the Julian Day Number to convert. + # +sg+ specifies the Day of Calendar Reform. + # + # Returns the corresponding Commercial Date as + # [commercial_year, week_of_year, day_of_week] + def self.jd_to_commercial(jd, sg=GREGORIAN) + ns = fix_style(jd, sg) + a = jd_to_civil(jd - 3, ns)[0] + y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end + w = 1 + ((jd - commercial_to_jd(y, 1, 1, ns)) / 7).floor + d = (jd + 1) % 7 + d = 7 if d == 0 + return y, w, d + end + + def self.weeknum_to_jd(y, w, d, f=0, ns=GREGORIAN) # :nodoc: + a = civil_to_jd(y, 1, 1, ns) + 6 + (a - ((a - f) + 1) % 7 - 7) + 7 * w + d + end + + def self.jd_to_weeknum(jd, f=0, sg=GREGORIAN) # :nodoc: + ns = fix_style(jd, sg) + y, m, d = jd_to_civil(jd, ns) + a = civil_to_jd(y, 1, 1, ns) + 6 + w, d = (jd - (a - ((a - f) + 1) % 7) + 7).divmod(7) + return y, w, d + end + + private_class_method :weeknum_to_jd, :jd_to_weeknum + + # Convert an Astronomical Julian Day Number to a (civil) Julian + # Day Number. + # + # +ajd+ is the Astronomical Julian Day Number to convert. + # +of+ is the offset from UTC as a fraction of a day (defaults to 0). + # + # Returns the (civil) Julian Day Number as [day_number, + # fraction] where +fraction+ is always 1/2. + def self.ajd_to_jd(ajd, of=0) (ajd + of + 1.to_r/2).divmod(1) end + + # Convert a (civil) Julian Day Number to an Astronomical Julian + # Day Number. + # + # +jd+ is the Julian Day Number to convert, and +fr+ is a + # fractional day. + # +of+ is the offset from UTC as a fraction of a day (defaults to 0). + # + # Returns the Astronomical Julian Day Number as a single + # numeric value. + def self.jd_to_ajd(jd, fr, of=0) jd + fr - of - 1.to_r/2 end + + # Convert a fractional day +fr+ to [hours, minutes, seconds, + # fraction_of_a_second] + def self.day_fraction_to_time(fr) + h, fr = fr.divmod(1.to_r/24) + min, fr = fr.divmod(1.to_r/1440) + s, fr = fr.divmod(1.to_r/86400) + return h, min, s, fr + end + + # Convert an +h+ hour, +min+ minutes, +s+ seconds period + # to a fractional day. + def self.time_to_day_fraction(h, min, s) + h.to_r/24 + min.to_r/1440 + s.to_r/86400 + end + + # Convert an Astronomical Modified Julian Day Number to an + # Astronomical Julian Day Number. + def self.amjd_to_ajd(amjd) amjd + 4800001.to_r/2 end + + # Convert an Astronomical Julian Day Number to an + # Astronomical Modified Julian Day Number. + def self.ajd_to_amjd(ajd) ajd - 4800001.to_r/2 end + + # Convert a Modified Julian Day Number to a Julian + # Day Number. + def self.mjd_to_jd(mjd) mjd + 2400001 end + + # Convert a Julian Day Number to a Modified Julian Day + # Number. + def self.jd_to_mjd(jd) jd - 2400001 end + + # Convert a count of the number of days since the adoption + # of the Gregorian Calendar (in Italy) to a Julian Day Number. + def self.ld_to_jd(ld) ld + 2299160 end + + # Convert a Julian Day Number to the number of days since + # the adoption of the Gregorian Calendar (in Italy). + def self.jd_to_ld(jd) jd - 2299160 end + + # Convert a Julian Day Number to the day of the week. + # + # Sunday is day-of-week 0; Saturday is day-of-week 6. + def self.jd_to_wday(jd) (jd + 1) % 7 end + + # Is a year a leap year in the Julian calendar? + # + # All years divisible by 4 are leap years in the Julian calendar. + def self.julian_leap? (y) y % 4 == 0 end + + # Is a year a leap year in the Gregorian calendar? + # + # All years divisible by 4 are leap years in the Gregorian calendar, + # except for years divisible by 100 and not by 400. + def self.gregorian_leap? (y) y % 4 == 0 && y % 100 != 0 || y % 400 == 0 end + + class << self; alias_method :leap?, :gregorian_leap? end + class << self; alias_method :new!, :new end + + # Is +jd+ a valid Julian Day Number? + # + # If it is, returns it. In fact, any value is treated as a valid + # Julian Day Number. + def self.valid_jd? (jd, sg=ITALY) jd end + + # Do the year +y+ and day-of-year +d+ make a valid Ordinal Date? + # Returns the corresponding Julian Day Number if they do, or + # nil if they don't. + # + # +d+ can be a negative number, in which case it counts backwards + # from the end of the year (-1 being the last day of the year). + # No year wraparound is performed, however, so valid values of + # +d+ are -365 .. -1, 1 .. 365 on a non-leap-year, + # -366 .. -1, 1 .. 366 on a leap year. + # A date falling in the period skipped in the Day of Calendar Reform + # adjustment is not valid. + # + # +sg+ specifies the Day of Calendar Reform. + def self.valid_ordinal? (y, d, sg=ITALY) + if d < 0 + ny, = (y + 1).divmod(1) + jd = ordinal_to_jd(ny, d + 1, sg) + ns = fix_style(jd, sg) + return unless [y] == jd_to_ordinal(jd, sg)[0..0] + return unless [ny, 1] == jd_to_ordinal(jd - d, ns) + else + jd = ordinal_to_jd(y, d, sg) + return unless [y, d] == jd_to_ordinal(jd, sg) + end + jd + end + + # Do year +y+, month +m+, and day-of-month +d+ make a + # valid Civil Date? Returns the corresponding Julian + # Day Number if they do, nil if they don't. + # + # +m+ and +d+ can be negative, in which case they count + # backwards from the end of the year and the end of the + # month respectively. No wraparound is performed, however, + # and invalid values cause an ArgumentError to be raised. + # A date falling in the period skipped in the Day of Calendar + # Reform adjustment is not valid. + # + # +sg+ specifies the Day of Calendar Reform. + def self.valid_civil? (y, m, d, sg=ITALY) + if m < 0 + m += 13 + end + if d < 0 + ny, nm = (y * 12 + m).divmod(12) + nm, = (nm + 1).divmod(1) + jd = civil_to_jd(ny, nm, d + 1, sg) + ns = fix_style(jd, sg) + return unless [y, m] == jd_to_civil(jd, sg)[0..1] + return unless [ny, nm, 1] == jd_to_civil(jd - d, ns) + else + jd = civil_to_jd(y, m, d, sg) + return unless [y, m, d] == jd_to_civil(jd, sg) + end + jd + end + + class << self; alias_method :valid_date?, :valid_civil? end + + # Do year +y+, week-of-year +w+, and day-of-week +d+ make a + # valid Commercial Date? Returns the corresponding Julian + # Day Number if they do, nil if they don't. + # + # Monday is day-of-week 1; Sunday is day-of-week 7. + # + # +w+ and +d+ can be negative, in which case they count + # backwards from the end of the year and the end of the + # week respectively. No wraparound is performed, however, + # and invalid values cause an ArgumentError to be raised. + # A date falling in the period skipped in the Day of Calendar + # Reform adjustment is not valid. + # + # +sg+ specifies the Day of Calendar Reform. + def self.valid_commercial? (y, w, d, sg=ITALY) + if d < 0 + d += 8 + end + if w < 0 + ny, nw, nd = + jd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7) + return unless ny == y + w = nw + end + jd = commercial_to_jd(y, w, d) + return unless gregorian?(jd, sg) + return unless [y, w, d] == jd_to_commercial(jd) + jd + end + + def self.valid_weeknum? (y, w, d, f, sg=ITALY) # :nodoc: + if d < 0 + d += 7 + end + if w < 0 + ny, nw, nd, nf = + jd_to_weeknum(weeknum_to_jd(y + 1, 1, f, f) + w * 7, f) + return unless ny == y + w = nw + end + jd = weeknum_to_jd(y, w, d, f) + return unless gregorian?(jd, sg) + return unless [y, w, d] == jd_to_weeknum(jd, f) + jd + end + + private_class_method :valid_weeknum? + + # Do hour +h+, minute +min+, and second +s+ constitute a valid time? + # + # If they do, returns their value as a fraction of a day. If not, + # returns nil. + # + # The 24-hour clock is used. Negative values of +h+, +min+, and + # +sec+ are treating as counting backwards from the end of the + # next larger unit (e.g. a +min+ of -2 is treated as 58). No + # wraparound is performed. + def self.valid_time? (h, min, s) + h += 24 if h < 0 + min += 60 if min < 0 + s += 60 if s < 0 + return unless ((0..23) === h && + (0..59) === min && + (0..59) === s) || + (24 == h && + 0 == min && + 0 == s) + time_to_day_fraction(h, min, s) + end + + # Create a new Date object from a Julian Day Number. + # + # +jd+ is the Julian Day Number; if not specified, it defaults to + # 0. + # +sg+ specifies the Day of Calendar Reform. + def self.jd(jd=0, sg=ITALY) + jd = valid_jd?(jd, sg) + new!(jd_to_ajd(jd, 0, 0), 0, sg) + end + + # Create a new Date object from an Ordinal Date, specified + # by year +y+ and day-of-year +d+. +d+ can be negative, + # in which it counts backwards from the end of the year. + # No year wraparound is performed, however. An invalid + # value for +d+ results in an ArgumentError being raised. + # + # +y+ defaults to -4712, and +d+ to 1; this is Julian Day + # Number day 0. + # + # +sg+ specifies the Day of Calendar Reform. + def self.ordinal(y=-4712, d=1, sg=ITALY) + unless jd = valid_ordinal?(y, d, sg) + raise ArgumentError, 'invalid date' + end + new!(jd_to_ajd(jd, 0, 0), 0, sg) + end + + # Create a new Date object for the Civil Date specified by + # year +y+, month +m+, and day-of-month +d+. + # + # +m+ and +d+ can be negative, in which case they count + # backwards from the end of the year and the end of the + # month respectively. No wraparound is performed, however, + # and invalid values cause an ArgumentError to be raised. + # can be negative + # + # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is + # Julian Day Number day 0. + # + # +sg+ specifies the Day of Calendar Reform. + def self.civil(y=-4712, m=1, d=1, sg=ITALY) + unless jd = valid_civil?(y, m, d, sg) + raise ArgumentError, 'invalid date' + end + new!(jd_to_ajd(jd, 0, 0), 0, sg) + end + + class << self; alias_method :new, :civil end + + # Create a new Date object for the Commercial Date specified by + # year +y+, week-of-year +w+, and day-of-week +d+. + # + # Monday is day-of-week 1; Sunday is day-of-week 7. + # + # +w+ and +d+ can be negative, in which case they count + # backwards from the end of the year and the end of the + # week respectively. No wraparound is performed, however, + # and invalid values cause an ArgumentError to be raised. + # + # +y+ defaults to 1582, +w+ to 41, and +d+ to 5, the Day of + # Calendar Reform for Italy and the Catholic countries. + # + # +sg+ specifies the Day of Calendar Reform. + def self.commercial(y=1582, w=41, d=5, sg=ITALY) + unless jd = valid_commercial?(y, w, d, sg) + raise ArgumentError, 'invalid date' + end + new!(jd_to_ajd(jd, 0, 0), 0, sg) + end + + def self.weeknum(y=1582, w=41, d=5, f=0, sg=ITALY) # :nodoc: + unless jd = valid_weeknum?(y, w, d, f, sg) + raise ArgumentError, 'invalid date' + end + new!(jd_to_ajd(jd, 0, 0), 0, sg) + end + + private_class_method :weeknum + + def self.rewrite_frags(elem) # :nodoc: + elem ||= {} + if seconds = elem[:seconds] + d, fr = seconds.divmod(86400) + h, fr = fr.divmod(3600) + min, fr = fr.divmod(60) + s, fr = fr.divmod(1) + elem[:jd] = UNIXEPOCH + d + elem[:hour] = h + elem[:min] = min + elem[:sec] = s + elem[:sec_fraction] = fr + elem.delete(:seconds) + elem.delete(:offset) + end + elem + end + + private_class_method :rewrite_frags + + def self.complete_frags(elem) # :nodoc: + i = 0 + g = [[:time, [:hour, :min, :sec]], + [nil, [:jd]], + [:ordinal, [:year, :yday, :hour, :min, :sec]], + [:civil, [:year, :mon, :mday, :hour, :min, :sec]], + [:commercial, [:cwyear, :cweek, :cwday, :hour, :min, :sec]], + [:wday, [:wday, :hour, :min, :sec]], + [:wnum0, [:year, :wnum0, :wday, :hour, :min, :sec]], + [:wnum1, [:year, :wnum1, :wday, :hour, :min, :sec]], + [nil, [:cwyear, :cweek, :wday, :hour, :min, :sec]], + [nil, [:year, :wnum0, :cwday, :hour, :min, :sec]], + [nil, [:year, :wnum1, :cwday, :hour, :min, :sec]]]. + collect{|k, a| e = elem.values_at(*a).compact; [k, a, e]}. + select{|k, a, e| e.size > 0}. + sort_by{|k, a, e| [e.size, i -= 1]}.last + + d = nil + + if g && g[0] && (g[1].size - g[2].size) != 0 + d ||= Date.today + + case g[0] + when :ordinal + elem[:year] ||= d.year + elem[:yday] ||= 1 + when :civil + g[1].each do |e| + break if elem[e] + elem[e] = d.__send__(e) + end + elem[:mon] ||= 1 + elem[:mday] ||= 1 + when :commercial + g[1].each do |e| + break if elem[e] + elem[e] = d.__send__(e) + end + elem[:cweek] ||= 1 + elem[:cwday] ||= 1 + when :wday + elem[:jd] ||= (d - d.wday + elem[:wday]).jd + when :wnum0 + g[1].each do |e| + break if elem[e] + elem[e] = d.__send__(e) + end + elem[:wnum0] ||= 0 + elem[:wday] ||= 0 + when :wnum1 + g[1].each do |e| + break if elem[e] + elem[e] = d.__send__(e) + end + elem[:wnum1] ||= 0 + elem[:wday] ||= 0 + end + end + + if g && g[0] == :time + if self <= DateTime + d ||= Date.today + elem[:jd] ||= d.jd + end + end + + elem[:hour] ||= 0 + elem[:min] ||= 0 + elem[:sec] ||= 0 + elem[:sec] = [elem[:sec], 59].min + + elem + end + + private_class_method :complete_frags + + def self.valid_date_frags?(elem, sg) # :nodoc: + catch :jd do + a = elem.values_at(:jd) + if a.all? + if jd = valid_jd?(*(a << sg)) + throw :jd, jd + end + end + + a = elem.values_at(:year, :yday) + if a.all? + if jd = valid_ordinal?(*(a << sg)) + throw :jd, jd + end + end + + a = elem.values_at(:year, :mon, :mday) + if a.all? + if jd = valid_civil?(*(a << sg)) + throw :jd, jd + end + end + + a = elem.values_at(:cwyear, :cweek, :cwday) + if a[2].nil? && elem[:wday] + a[2] = elem[:wday].nonzero? || 7 + end + if a.all? + if jd = valid_commercial?(*(a << sg)) + throw :jd, jd + end + end + + a = elem.values_at(:year, :wnum0, :wday) + if a[2].nil? && elem[:cwday] + a[2] = elem[:cwday] % 7 + end + if a.all? + if jd = valid_weeknum?(*(a << 0 << sg)) + throw :jd, jd + end + end + + a = elem.values_at(:year, :wnum1, :wday) + if a[2] + a[2] = (a[2] - 1) % 7 + end + if a[2].nil? && elem[:cwday] + a[2] = (elem[:cwday] - 1) % 7 + end + if a.all? + if jd = valid_weeknum?(*(a << 1 << sg)) + throw :jd, jd + end + end + end + end + + private_class_method :valid_date_frags? + + def self.valid_time_frags? (elem) # :nodoc: + h, min, s = elem.values_at(:hour, :min, :sec) + valid_time?(h, min, s) + end + + private_class_method :valid_time_frags? + + def self.new_by_frags(elem, sg) # :nodoc: + elem = rewrite_frags(elem) + elem = complete_frags(elem) + unless jd = valid_date_frags?(elem, sg) + raise ArgumentError, 'invalid date' + end + new!(jd_to_ajd(jd, 0, 0), 0, sg) + end + + private_class_method :new_by_frags + + # Create a new Date object by parsing from a String + # according to a specified format. + # + # +str+ is a String holding a date representation. + # +fmt+ is the format that the date is in. See + # date/format.rb for details on supported formats. + # + # The default +str+ is '-4712-01-01', and the default + # +fmt+ is '%F', which means Year-Month-Day_of_Month. + # This gives Julian Day Number day 0. + # + # +sg+ specifies the Day of Calendar Reform. + # + # An ArgumentError will be raised if +str+ cannot be + # parsed. + def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY) + elem = _strptime(str, fmt) + new_by_frags(elem, sg) + end + + # Create a new Date object by parsing from a String, + # without specifying the format. + # + # +str+ is a String holding a date representation. + # +comp+ specifies whether to interpret 2-digit years + # as 19XX (>= 69) or 20XX (< 69); the default is not to. + # The method will attempt to parse a date from the String + # using various heuristics; see #_parse in date/format.rb + # for more details. If parsing fails, an ArgumentError + # will be raised. + # + # The default +str+ is '-4712-01-01'; this is Julian + # Day Number day 0. + # + # +sg+ specifies the Day of Calendar Reform. + def self.parse(str='-4712-01-01', comp=false, sg=ITALY) + elem = _parse(str, comp) + new_by_frags(elem, sg) + end + + class << self + + def once(*ids) # :nodoc: + for id in ids + module_eval <<-"end;" + alias_method :__#{id.to_i}__, :#{id.to_s} + private :__#{id.to_i}__ + def #{id.to_s}(*args, &block) + (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0] + end + end; + end + end + + private :once + + end + + # *NOTE* this is the documentation for the method new!(). If + # you are reading this as the documentation for new(), that is + # because rdoc doesn't fully support the aliasing of the + # initialize() method. + # new() is in + # fact an alias for #civil(): read the documentation for that + # method instead. + # + # Create a new Date object. + # + # +ajd+ is the Astronomical Julian Day Number. + # +of+ is the offset from UTC as a fraction of a day. + # Both default to 0. + # + # +sg+ specifies the Day of Calendar Reform to use for this + # Date object. + # + # Using one of the factory methods such as Date::civil is + # generally easier and safer. + def initialize(ajd=0, of=0, sg=ITALY) @ajd, @of, @sg = ajd, of, sg end + + # Get the date as an Astronomical Julian Day Number. + def ajd() @ajd end + + # Get the date as an Astronomical Modified Julian Day Number. + def amjd() self.class.ajd_to_amjd(@ajd) end + + once :amjd + + # Get the date as a Julian Day Number. + def jd() self.class.ajd_to_jd(@ajd, @of)[0] end + + # Get any fractional day part of the date. + def day_fraction() self.class.ajd_to_jd(@ajd, @of)[1] end + + # Get the date as a Modified Julian Day Number. + def mjd() self.class.jd_to_mjd(jd) end + + # Get the date as the number of days since the Day of Calendar + # Reform (in Italy and the Catholic countries). + def ld() self.class.jd_to_ld(jd) end + + once :jd, :day_fraction, :mjd, :ld + + # Get the date as a Civil Date, [year, month, day_of_month] + def civil() self.class.jd_to_civil(jd, @sg) end # :nodoc: + + # Get the date as an Ordinal Date, [year, day_of_year] + def ordinal() self.class.jd_to_ordinal(jd, @sg) end # :nodoc: + + # Get the date as a Commercial Date, [year, week_of_year, day_of_week] + def commercial() self.class.jd_to_commercial(jd, @sg) end # :nodoc: + + def weeknum0() self.class.__send__(:jd_to_weeknum, jd, 0, @sg) end # :nodoc: + def weeknum1() self.class.__send__(:jd_to_weeknum, jd, 1, @sg) end # :nodoc: + + once :civil, :ordinal, :commercial, :weeknum0, :weeknum1 + private :civil, :ordinal, :commercial, :weeknum0, :weeknum1 + + # Get the year of this date. + def year() civil[0] end + + # Get the day-of-the-year of this date. + # + # January 1 is day-of-the-year 1 + def yday() ordinal[1] end + + # Get the month of this date. + # + # January is month 1. + def mon() civil[1] end + + # Get the day-of-the-month of this date. + def mday() civil[2] end + + alias_method :month, :mon + alias_method :day, :mday + + def wnum0() weeknum0[1] end # :nodoc: + def wnum1() weeknum1[1] end # :nodoc: + + private :wnum0, :wnum1 + + # Get the time of this date as [hours, minutes, seconds, + # fraction_of_a_second] + def time() self.class.day_fraction_to_time(day_fraction) end # :nodoc: + + once :time + private :time + + # Get the hour of this date. + def hour() time[0] end + + # Get the minute of this date. + def min() time[1] end + + # Get the second of this date. + def sec() time[2] end + + # Get the fraction-of-a-second of this date. The unit is in days. + # I do NOT recommend you to use this method. + def sec_fraction() time[3] end + + private :hour, :min, :sec, :sec_fraction + + def zone() strftime('%:z') end + + private :zone + + # Get the commercial year of this date. See *Commercial* *Date* + # in the introduction for how this differs from the normal year. + def cwyear() commercial[0] end + + # Get the commercial week of the year of this date. + def cweek() commercial[1] end + + # Get the commercial day of the week of this date. Monday is + # commercial day-of-week 1; Sunday is commercial day-of-week 7. + def cwday() commercial[2] end + + # Get the week day of this date. Sunday is day-of-week 0; + # Saturday is day-of-week 6. + def wday() self.class.jd_to_wday(jd) end + + once :wday + +=begin + MONTHNAMES.each_with_index do |n, i| + if n + define_method(n.downcase + '?'){mon == i} + end + end + + DAYNAMES.each_with_index do |n, i| + define_method(n.downcase + '?'){wday == i} + end +=end + + # Is the current date old-style (Julian Calendar)? + def julian? () self.class.julian?(jd, @sg) end + + # Is the current date new-style (Gregorian Calendar)? + def gregorian? () self.class.gregorian?(jd, @sg) end + + once :julian?, :gregorian? + + def fix_style # :nodoc: + if julian? + then self.class::JULIAN + else self.class::GREGORIAN end + end + + private :fix_style + + # Is this a leap year? + def leap? + self.class.jd_to_civil(self.class.civil_to_jd(year, 3, 1, fix_style) - 1, + fix_style)[-1] == 29 + end + + once :leap? + + # When is the Day of Calendar Reform for this Date object? + def start() @sg end + + # Create a copy of this Date object using a new Day of Calendar Reform. + def new_start(sg=self.class::ITALY) self.class.new!(@ajd, @of, sg) end + + # Create a copy of this Date object that uses the Italian/Catholic + # Day of Calendar Reform. + def italy() new_start(self.class::ITALY) end + + # Create a copy of this Date object that uses the English/Colonial + # Day of Calendar Reform. + def england() new_start(self.class::ENGLAND) end + + # Create a copy of this Date object that always uses the Julian + # Calendar. + def julian() new_start(self.class::JULIAN) end + + # Create a copy of this Date object that always uses the Gregorian + # Calendar. + def gregorian() new_start(self.class::GREGORIAN) end + + def offset() @of end + + def new_offset(of=0) + if String === of + of = (self.class.zone_to_diff(of) || 0).to_r/86400 + end + self.class.new!(@ajd, of, @sg) + end + + private :offset, :new_offset + + # Return a new Date object that is +n+ days later than the + # current one. + # + # +n+ may be a negative value, in which case the new Date + # is earlier than the current one; however, #-() might be + # more intuitive. + # + # If +n+ is not a Numeric, a TypeError will be thrown. In + # particular, two Dates cannot be added to each other. + def + (n) + case n + when Numeric; return self.class.new!(@ajd + n, @of, @sg) + end + raise TypeError, 'expected numeric' + end + + # If +x+ is a Numeric value, create a new Date object that is + # +x+ days earlier than the current one. + # + # If +x+ is a Date, return the number of days between the + # two dates; or, more precisely, how many days later the current + # date is than +x+. + # + # If +x+ is neither Numeric nor a Date, a TypeError is raised. + def - (x) + case x + when Numeric; return self.class.new!(@ajd - x, @of, @sg) + when Date; return @ajd - x.ajd + end + raise TypeError, 'expected numeric or date' + end + + # Compare this date with another date. + # + # +other+ can also be a Numeric value, in which case it is + # interpreted as an Astronomical Julian Day Number. + # + # Comparison is by Astronomical Julian Day Number, including + # fractional days. This means that both the time and the + # timezone offset are taken into account when comparing + # two DateTime instances. When comparing a DateTime instance + # with a Date instance, the time of the latter will be + # considered as falling on midnight UTC. + def <=> (other) + case other + when Numeric; return @ajd <=> other + when Date; return @ajd <=> other.ajd + end + nil + end + + # The relationship operator for Date. + # + # Compares dates by Julian Day Number. When comparing + # two DateTime instances, or a DateTime with a Date, + # the instances will be regarded as equivalent if they + # fall on the same date in local time. + def === (other) + case other + when Numeric; return jd == other + when Date; return jd == other.jd + end + false + end + + def next_day(n=1) self + n end +# def prev_day(n=1) self - n end + + private :next_day + + # Return a new Date one day after this one. + def next() next_day end + + alias_method :succ, :next + + # Return a new Date object that is +n+ months later than + # the current one. + # + # If the day-of-the-month of the current Date is greater + # than the last day of the target month, the day-of-the-month + # of the returned Date will be the last day of the target month. + def >> (n) + y, m = (year * 12 + (mon - 1) + n).divmod(12) + m, = (m + 1) .divmod(1) + d = mday + d -= 1 until jd2 = self.class.valid_civil?(y, m, d, fix_style) + self + (jd2 - jd) + end + + # Return a new Date object that is +n+ months earlier than + # the current one. + # + # If the day-of-the-month of the current Date is greater + # than the last day of the target month, the day-of-the-month + # of the returned Date will be the last day of the target month. + def << (n) self >> -n end + +=begin + def next_month(n=1) self >> n end + def prev_month(n=1) self << n end + + def next_year(n=1) self >> n * 12 end + def prev_year(n=1) self << n * 12 end +=end + +# require 'enumerator' + + # Step the current date forward +step+ days at a + # time (or backward, if +step+ is negative) until + # we reach +limit+ (inclusive), yielding the resultant + # date at each step. + def step(limit, step=1) # :yield: date +=begin + unless block_given? + return to_enum(:step, limit, step) + end +=end + da = self + op = %w(- <= >=)[step <=> 0] + while da.__send__(op, limit) + yield da + da += step + end + self + end + + # Step forward one day at a time until we reach +max+ + # (inclusive), yielding each date as we go. + def upto(max, &block) # :yield: date + step(max, +1, &block) + end + + # Step backward one day at a time until we reach +min+ + # (inclusive), yielding each date as we go. + def downto(min, &block) # :yield: date + step(min, -1, &block) + end + + # Is this Date equal to +other+? + # + # +other+ must both be a Date object, and represent the same date. + def eql? (other) Date === other && self == other end + + # Calculate a hash value for this date. + def hash() @ajd.hash end + + # Return internal object state as a programmer-readable string. + def inspect() format('#<%s: %s,%s,%s>', self.class, @ajd, @of, @sg) end + + # Return the date as a human-readable string. + # + # The format used is YYYY-MM-DD. + def to_s() strftime end + + # Dump to Marshal format. + def _dump(limit) Marshal.dump([@ajd, @of, @sg], -1) end + +# def self._load(str) new!(*Marshal.load(str)) end + + # Load from Marshall format. + def self._load(str) + a = Marshal.load(str) + if a.size == 2 + ajd, sg = a + of = 0 + ajd -= 1.to_r/2 + else + ajd, of, sg = a + end + new!(ajd, of, sg) + end + +end + +# Class representing a date and time. +# +# See the documentation to the file date.rb for an overview. +# +# DateTime objects are immutable once created. +# +# == Other methods. +# +# The following methods are defined in Date, but declared private +# there. They are made public in DateTime. They are documented +# here. +# +# === hour() +# +# Get the hour-of-the-day of the time. This is given +# using the 24-hour clock, counting from midnight. The first +# hour after midnight is hour 0; the last hour of the day is +# hour 23. +# +# === min() +# +# Get the minute-of-the-hour of the time. +# +# === sec() +# +# Get the second-of-the-minute of the time. +# +# === sec_fraction() +# +# Get the fraction of a second of the time. This is returned as +# a +Rational+. The unit is in days. +# I do NOT recommend you to use this method. +# +# === zone() +# +# Get the time zone as a String. This is representation of the +# time offset such as "+1000", not the true time-zone name. +# +# === offset() +# +# Get the time zone offset as a fraction of a day. This is returned +# as a +Rational+. +# +# === new_offset(of=0) +# +# Create a new DateTime object, identical to the current one, except +# with a new time zone offset of +of+. +of+ is the new offset from +# UTC as a fraction of a day. +# +class DateTime < Date + + # Create a new DateTime object corresponding to the specified + # Julian Day Number +jd+ and hour +h+, minute +min+, second +s+. + # + # The 24-hour clock is used. Negative values of +h+, +min+, and + # +sec+ are treating as counting backwards from the end of the + # next larger unit (e.g. a +min+ of -2 is treated as 58). No + # wraparound is performed. If an invalid time portion is specified, + # an ArgumentError is raised. + # + # +of+ is the offset from UTC as a fraction of a day (defaults to 0). + # +sg+ specifies the Day of Calendar Reform. + # + # All day/time values default to 0. + def self.jd(jd=0, h=0, min=0, s=0, of=0, sg=ITALY) + unless (jd = valid_jd?(jd, sg)) && + (fr = valid_time?(h, min, s)) + raise ArgumentError, 'invalid date' + end + if String === of + of = (zone_to_diff(of) || 0).to_r/86400 + end + new!(jd_to_ajd(jd, fr, of), of, sg) + end + + # Create a new DateTime object corresponding to the specified + # Ordinal Date and hour +h+, minute +min+, second +s+. + # + # The 24-hour clock is used. Negative values of +h+, +min+, and + # +sec+ are treating as counting backwards from the end of the + # next larger unit (e.g. a +min+ of -2 is treated as 58). No + # wraparound is performed. If an invalid time portion is specified, + # an ArgumentError is raised. + # + # +of+ is the offset from UTC as a fraction of a day (defaults to 0). + # +sg+ specifies the Day of Calendar Reform. + # + # +y+ defaults to -4712, and +d+ to 1; this is Julian Day Number + # day 0. The time values default to 0. + def self.ordinal(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY) + unless (jd = valid_ordinal?(y, d, sg)) && + (fr = valid_time?(h, min, s)) + raise ArgumentError, 'invalid date' + end + if String === of + of = (zone_to_diff(of) || 0).to_r/86400 + end + new!(jd_to_ajd(jd, fr, of), of, sg) + end + + # Create a new DateTime object corresponding to the specified + # Civil Date and hour +h+, minute +min+, second +s+. + # + # The 24-hour clock is used. Negative values of +h+, +min+, and + # +sec+ are treating as counting backwards from the end of the + # next larger unit (e.g. a +min+ of -2 is treated as 58). No + # wraparound is performed. If an invalid time portion is specified, + # an ArgumentError is raised. + # + # +of+ is the offset from UTC as a fraction of a day (defaults to 0). + # +sg+ specifies the Day of Calendar Reform. + # + # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is Julian Day + # Number day 0. The time values default to 0. + def self.civil(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY) + unless (jd = valid_civil?(y, m, d, sg)) && + (fr = valid_time?(h, min, s)) + raise ArgumentError, 'invalid date' + end + if String === of + of = (zone_to_diff(of) || 0).to_r/86400 + end + new!(jd_to_ajd(jd, fr, of), of, sg) + end + + class << self; alias_method :new, :civil end + + # Create a new DateTime object corresponding to the specified + # Commercial Date and hour +h+, minute +min+, second +s+. + # + # The 24-hour clock is used. Negative values of +h+, +min+, and + # +sec+ are treating as counting backwards from the end of the + # next larger unit (e.g. a +min+ of -2 is treated as 58). No + # wraparound is performed. If an invalid time portion is specified, + # an ArgumentError is raised. + # + # +of+ is the offset from UTC as a fraction of a day (defaults to 0). + # +sg+ specifies the Day of Calendar Reform. + # + # +y+ defaults to 1582, +w+ to 41, and +d+ to 5; this is the Day of + # Calendar Reform for Italy and the Catholic countries. + # The time values default to 0. + def self.commercial(y=1582, w=41, d=5, h=0, min=0, s=0, of=0, sg=ITALY) + unless (jd = valid_commercial?(y, w, d, sg)) && + (fr = valid_time?(h, min, s)) + raise ArgumentError, 'invalid date' + end + if String === of + of = (zone_to_diff(of) || 0).to_r/86400 + end + new!(jd_to_ajd(jd, fr, of), of, sg) + end + + def self.weeknum(y=1582, w=41, d=5, f=0, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc: + unless (jd = valid_weeknum?(y, w, d, f, sg)) && + (fr = valid_time?(h, min, s)) + raise ArgumentError, 'invalid date' + end + if String === of + of = (zone_to_diff(of) || 0).to_r/86400 + end + new!(jd_to_ajd(jd, fr, of), of, sg) + end + + private_class_method :weeknum + + def self.new_by_frags(elem, sg) # :nodoc: + elem = rewrite_frags(elem) + elem = complete_frags(elem) + unless (jd = valid_date_frags?(elem, sg)) && + (fr = valid_time_frags?(elem)) + raise ArgumentError, 'invalid date' + end + sf = (elem[:sec_fraction] || 0) + fr += sf/86400 + of = (elem[:offset] || 0) + of = of.to_r/86400 + new!(jd_to_ajd(jd, fr, of), of, sg) + end + + private_class_method :new_by_frags + + # Create a new DateTime object by parsing from a String + # according to a specified format. + # + # +str+ is a String holding a date-time representation. + # +fmt+ is the format that the date-time is in. See + # date/format.rb for details on supported formats. + # + # The default +str+ is '-4712-01-01T00:00:00+00:00', and the default + # +fmt+ is '%FT%T%z'. This gives midnight on Julian Day Number day 0. + # + # +sg+ specifies the Day of Calendar Reform. + # + # An ArgumentError will be raised if +str+ cannot be + # parsed. + def self.strptime(str='-4712-01-01T00:00:00+00:00', fmt='%FT%T%z', sg=ITALY) + elem = _strptime(str, fmt) + new_by_frags(elem, sg) + end + + # Create a new DateTime object by parsing from a String, + # without specifying the format. + # + # +str+ is a String holding a date-time representation. + # +comp+ specifies whether to interpret 2-digit years + # as 19XX (>= 69) or 20XX (< 69); the default is not to. + # The method will attempt to parse a date-time from the String + # using various heuristics; see #_parse in date/format.rb + # for more details. If parsing fails, an ArgumentError + # will be raised. + # + # The default +str+ is '-4712-01-01T00:00:00+00:00'; this is Julian + # Day Number day 0. + # + # +sg+ specifies the Day of Calendar Reform. + def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY) + elem = _parse(str, comp) + new_by_frags(elem, sg) + end + + public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset + +end + +class Time + +# def to_time() getlocal end + + def to_date + jd = Date.civil_to_jd(year, mon, mday, Date::ITALY) + Date.new!(Date.jd_to_ajd(jd, 0, 0), 0, Date::ITALY) + end + + def to_datetime + jd = DateTime.civil_to_jd(year, mon, mday, DateTime::ITALY) + fr = DateTime.time_to_day_fraction(hour, min, [sec, 59].min) + + usec.to_r/86400000000 + of = utc_offset.to_r/86400 + DateTime.new!(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY) + end + + private :to_date, :to_datetime + +end + +class Date + +=begin + def to_time() Time.local(year, mon, mday) end + def to_date() self end + def to_datetime() DateTime.new!(self.class.jd_to_ajd(jd, 0, 0), @of, @sg) end +=end + + # Create a new Date object representing today. + # + # +sg+ specifies the Day of Calendar Reform. + def self.today(sg=ITALY) Time.now.__send__(:to_date) .new_start(sg) end + + # Create a new DateTime object representing the current time. + # + # +sg+ specifies the Day of Calendar Reform. + def self.now (sg=ITALY) Time.now.__send__(:to_datetime).new_start(sg) end + + private_class_method :now + +end + +class DateTime < Date + +=begin + def to_time + d = new_offset(0) + d.instance_eval do + Time.utc(year, mon, mday, hour, min, sec, + (sec_fraction * 86400000000).to_i) + end. + getlocal + end + + def to_date() Date.new!(self.class.jd_to_ajd(jd, 0, 0), 0, @sg) end + def to_datetime() self end +=end + + private_class_method :today + public_class_method :now + +end + +class Date + + [ %w(os? julian?), + %w(ns? gregorian?), + %w(exist1? valid_jd?), + %w(exist2? valid_ordinal?), + %w(exist3? valid_date?), + %w(exist? valid_date?), + %w(existw? valid_commercial?), + %w(new0 new!), + %w(new1 jd), + %w(new2 ordinal), + %w(new3 new), + %w(neww commercial) + ].each do |old, new| + module_eval <<-"end;" + def self.#{old}(*args, &block) + if $VERBOSE + warn("\#{caller.shift.sub(/:in .*/, '')}: " \ + "warning: \#{self}::#{old} is deprecated; " \ + "use \#{self}::#{new}") + end + #{new}(*args, &block) + end + end; + end + + [ %w(os? julian?), + %w(ns? gregorian?), + %w(sg start), + %w(newsg new_start), + %w(of offset), + %w(newof new_offset) + ].each do |old, new| + module_eval <<-"end;" + def #{old}(*args, &block) + if $VERBOSE + warn("\#{caller.shift.sub(/:in .*/, '')}: " \ + "warning: \#{self.class}\##{old} is deprecated; " \ + "use \#{self.class}\##{new}") + end + #{new}(*args, &block) + end + end; + end + + private :of, :newof + +end + +class DateTime < Date + + public :of, :newof + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date/format.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date/format.rb new file mode 100644 index 00000000..8bd14c7f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date/format.rb @@ -0,0 +1,1088 @@ +# format.rb: Written by Tadayoshi Funaba 1999-2007 +# $Id: format.rb,v 2.30 2007-01-07 09:16:24+09 tadf Exp $ + +require 'rational' + +class Date + + module Format # :nodoc: + + MONTHS = { + 'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4, + 'may' => 5, 'june' => 6, 'july' => 7, 'august' => 8, + 'september'=> 9, 'october' =>10, 'november' =>11, 'december' =>12 + } + + DAYS = { + 'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday'=> 3, + 'thursday' => 4, 'friday' => 5, 'saturday' => 6 + } + + ABBR_MONTHS = { + 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, + 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, + 'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 + } + + ABBR_DAYS = { + 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3, + 'thu' => 4, 'fri' => 5, 'sat' => 6 + } + + ZONES = { + 'ut' => 0*3600, 'gmt' => 0*3600, 'est' => -5*3600, 'edt' => -4*3600, + 'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600, + 'pst' => -8*3600, 'pdt' => -7*3600, + 'a' => 1*3600, 'b' => 2*3600, 'c' => 3*3600, 'd' => 4*3600, + 'e' => 5*3600, 'f' => 6*3600, 'g' => 7*3600, 'h' => 8*3600, + 'i' => 9*3600, 'k' => 10*3600, 'l' => 11*3600, 'm' => 12*3600, + 'n' => -1*3600, 'o' => -2*3600, 'p' => -3*3600, 'q' => -4*3600, + 'r' => -5*3600, 's' => -6*3600, 't' => -7*3600, 'u' => -8*3600, + 'v' => -9*3600, 'w' =>-10*3600, 'x' =>-11*3600, 'y' =>-12*3600, + 'z' => 0*3600, + 'utc' => 0*3600, 'wet' => 0*3600, 'bst' => 1*3600, 'wat' => -1*3600, + 'at' => -2*3600, 'ast' => -4*3600, 'adt' => -3*3600, 'yst' => -9*3600, + 'ydt' => -8*3600, 'hst' =>-10*3600, 'hdt' => -9*3600, 'cat' =>-10*3600, + 'ahst'=>-10*3600, 'nt' =>-11*3600, 'idlw'=>-12*3600, 'cet' => 1*3600, + 'met' => 1*3600, 'mewt'=> 1*3600, 'mest'=> 2*3600, 'mesz'=> 2*3600, + 'swt' => 1*3600, 'sst' => 2*3600, 'fwt' => 1*3600, 'fst' => 2*3600, + 'eet' => 2*3600, 'bt' => 3*3600, 'zp4' => 4*3600, 'zp5' => 5*3600, + 'zp6' => 6*3600, 'wast'=> 7*3600, 'wadt'=> 8*3600, 'cct' => 8*3600, + 'jst' => 9*3600, 'east'=> 10*3600, 'eadt'=> 11*3600, 'gst' => 10*3600, + 'nzt' => 12*3600, 'nzst'=> 12*3600, 'nzdt'=> 13*3600, 'idle'=> 12*3600, + + 'afghanistan' => 16200, 'alaskan' => -32400, + 'arab' => 10800, 'arabian' => 14400, + 'arabic' => 10800, 'atlantic' => -14400, + 'aus central' => 34200, 'aus eastern' => 36000, + 'azores' => -3600, 'canada central' => -21600, + 'cape verde' => -3600, 'caucasus' => 14400, + 'cen. australia' => 34200, 'central america' => -21600, + 'central asia' => 21600, 'central europe' => 3600, + 'central european' => 3600, 'central pacific' => 39600, + 'central' => -21600, 'china' => 28800, + 'dateline' => -43200, 'e. africa' => 10800, + 'e. australia' => 36000, 'e. europe' => 7200, + 'e. south america' => -10800, 'eastern' => -18000, + 'egypt' => 7200, 'ekaterinburg' => 18000, + 'fiji' => 43200, 'fle' => 7200, + 'greenland' => -10800, 'greenwich' => 0, + 'gtb' => 7200, 'hawaiian' => -36000, + 'india' => 19800, 'iran' => 12600, + 'jerusalem' => 7200, 'korea' => 32400, + 'mexico' => -21600, 'mid-atlantic' => -7200, + 'mountain' => -25200, 'myanmar' => 23400, + 'n. central asia' => 21600, 'nepal' => 20700, + 'new zealand' => 43200, 'newfoundland' => -12600, + 'north asia east' => 28800, 'north asia' => 25200, + 'pacific sa' => -14400, 'pacific' => -28800, + 'romance' => 3600, 'russian' => 10800, + 'sa eastern' => -10800, 'sa pacific' => -18000, + 'sa western' => -14400, 'samoa' => -39600, + 'se asia' => 25200, 'malay peninsula' => 28800, + 'south africa' => 7200, 'sri lanka' => 21600, + 'taipei' => 28800, 'tasmania' => 36000, + 'tokyo' => 32400, 'tonga' => 46800, + 'us eastern' => -18000, 'us mountain' => -25200, + 'vladivostok' => 36000, 'w. australia' => 28800, + 'w. central africa' => 3600, 'w. europe' => 3600, + 'west asia' => 18000, 'west pacific' => 36000, + 'yakutsk' => 32400 + } + + [MONTHS, DAYS, ABBR_MONTHS, ABBR_DAYS, ZONES].each do |x| + x.freeze + end + + class Bag # :nodoc: + + def initialize + @elem = {} + end + + def method_missing(t, *args, &block) + t = t.to_s + set = t.chomp!('=') + t = t.intern + if set + @elem[t] = args[0] + else + @elem[t] + end + end + + def to_hash + @elem.reject{|k, v| /\A_/ =~ k.to_s || v.nil?} + end + + end + + end + + def emit(e, f) # :nodoc: + case e + when Numeric + sign = %w(+ + -)[e <=> 0] + e = e.abs + end + + s = e.to_s + + if f[:s] && f[:p] == '0' + f[:w] -= 1 + end + + if f[:s] && f[:p] == "\s" + s[0,0] = sign + end + + if f[:p] != '-' + s = s.rjust(f[:w], f[:p]) + end + + if f[:s] && f[:p] != "\s" + s[0,0] = sign + end + + s = s.upcase if f[:u] + s = s.downcase if f[:d] + s + end + + def emit_w(e, w, f) # :nodoc: + f[:w] = [f[:w], w].compact.max + emit(e, f) + end + + def emit_n(e, w, f) # :nodoc: + f[:p] ||= '0' + emit_w(e, w, f) + end + + def emit_sn(e, w, f) # :nodoc: + if e < 0 + w += 1 + f[:s] = true + end + emit_n(e, w, f) + end + + def emit_z(e, w, f) # :nodoc: + w += 1 + f[:s] = true + emit_n(e, w, f) + end + + def emit_a(e, w, f) # :nodoc: + f[:p] ||= "\s" + emit_w(e, w, f) + end + + def emit_ad(e, w, f) # :nodoc: + if f[:x] + f[:u] = true + f[:d] = false + end + emit_a(e, w, f) + end + + def emit_au(e, w, f) # :nodoc: + if f[:x] + f[:u] = false + f[:d] = true + end + emit_a(e, w, f) + end + + private :emit, :emit_w, :emit_n, :emit_sn, :emit_z, + :emit_a, :emit_ad, :emit_au + + def strftime(fmt='%F') + fmt.gsub(/%([-_0^#]+)?(\d+)?[EO]?(:{1,3}z|.)/m) do |m| + f = {} + s, w, c = $1, $2, $3 + if s + s.scan(/./) do |k| + case k + when '-'; f[:p] = '-' + when '_'; f[:p] = "\s" + when '0'; f[:p] = '0' + when '^'; f[:u] = true + when '#'; f[:x] = true + end + end + end + if w + f[:w] = w.to_i + end + case c + when 'A'; emit_ad(DAYNAMES[wday], 0, f) + when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f) + when 'B'; emit_ad(MONTHNAMES[mon], 0, f) + when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f) + when 'C'; emit_sn((year / 100).floor, 2, f) + when 'c'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f) + when 'D'; emit_a(strftime('%m/%d/%y'), 0, f) + when 'd'; emit_n(mday, 2, f) + when 'e'; emit_a(mday, 2, f) + when 'F' + if m == '%F' + format('%.4d-%02d-%02d', year, mon, mday) # 4p + else + emit_a(strftime('%Y-%m-%d'), 0, f) + end + when 'G'; emit_sn(cwyear, 4, f) + when 'g'; emit_n(cwyear % 100, 2, f) + when 'H'; emit_n(hour, 2, f) + when 'h'; emit_ad(strftime('%b'), 0, f) + when 'I'; emit_n((hour % 12).nonzero? || 12, 2, f) + when 'j'; emit_n(yday, 3, f) + when 'k'; emit_a(hour, 2, f) + when 'L' + emit_n((sec_fraction / (1.to_r/86400/(10**3))).round, 3, f) + when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f) + when 'M'; emit_n(min, 2, f) + when 'm'; emit_n(mon, 2, f) + when 'N' + emit_n((sec_fraction / (1.to_r/86400/(10**9))).round, 9, f) + when 'n'; "\n" + when 'P'; emit_ad(strftime('%p').downcase, 0, f) + when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f) + when 'Q' + d = ajd - self.class.jd_to_ajd(self.class::UNIXEPOCH, 0) + s = (d * 86400*10**3).to_i + emit_sn(s, 1, f) + when 'R'; emit_a(strftime('%H:%M'), 0, f) + when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f) + when 'S'; emit_n(sec, 2, f) + when 's' + d = ajd - self.class.jd_to_ajd(self.class::UNIXEPOCH, 0) + s = (d * 86400).to_i + emit_sn(s, 1, f) + when 'T' + if m == '%T' + format('%02d:%02d:%02d', hour, min, sec) # 4p + else + emit_a(strftime('%H:%M:%S'), 0, f) + end + when 't'; "\t" + when 'U', 'W' + emit_n(if c == 'U' then wnum0 else wnum1 end, 2, f) + when 'u'; emit_n(cwday, 1, f) + when 'V'; emit_n(cweek, 2, f) + when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f) + when 'w'; emit_n(wday, 1, f) + when 'X'; emit_a(strftime('%H:%M:%S'), 0, f) + when 'x'; emit_a(strftime('%m/%d/%y'), 0, f) + when 'Y'; emit_sn(year, 4, f) + when 'y'; emit_n(year % 100, 2, f) + when 'Z'; emit_au(strftime('%:z'), 0, f) + when /\A(:{0,3})z/ + t = $1.size + sign = if offset < 0 then -1 else +1 end + fr = offset.abs + hh, fr = fr.divmod(1.to_r/24) + mm, fr = fr.divmod(1.to_r/1440) + ss, fr = fr.divmod(1.to_r/86400) + if t == 3 + if ss.nonzero? then t = 2 + elsif mm.nonzero? then t = 1 + else t = -1 + end + end + case t + when -1 + tail = [] + sep = '' + when 0 + f[:w] -= 2 if f[:w] + tail = ['%02d' % mm] + sep = '' + when 1 + f[:w] -= 3 if f[:w] + tail = ['%02d' % mm] + sep = ':' + when 2 + f[:w] -= 6 if f[:w] + tail = ['%02d' % mm, '%02d' % ss] + sep = ':' + end + ([emit_z(sign * hh, 2, f)] + tail).join(sep) + when '%'; emit_a('%', 0, f) + when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f) + when '1' + if $VERBOSE + warn("warning: strftime: %1 is deprecated; forget this") + end + emit_n(jd, 1, f) + when '2' + if $VERBOSE + warn("warning: strftime: %2 is deprecated; use '%Y-%j'") + end + emit_a(strftime('%Y-%j'), 0, f) + when '3' + if $VERBOSE + warn("warning: strftime: %3 is deprecated; use '%F'") + end + emit_a(strftime('%F'), 0, f) + else + c + end + end + end + +# alias_method :format, :strftime + + def asctime() strftime('%c') end + + alias_method :ctime, :asctime + +=begin + def iso8601() strftime('%F') end + + def rfc3339() iso8601 end + + def rfc2822() strftime('%a, %-d %b %Y %T %z') end + + alias_method :rfc822, :rfc2822 + + def jisx0301 + if jd < 2405160 + iso8601 + else + case jd + when 2405160...2419614 + g = 'M%02d' % (year - 1867) + when 2419614...2424875 + g = 'T%02d' % (year - 1911) + when 2424875...2447535 + g = 'S%02d' % (year - 1925) + else + g = 'H%02d' % (year - 1988) + end + g + strftime('.%m.%d') + end + end + + def beat(n=0) + i, f = (new_offset(1.to_r/24).day_fraction * 1000).divmod(1) + ('@%03d' % i) + + if n < 1 + '' + else + '.%0*d' % [n, (f / (1.to_r/(10**n))).round] + end + end +=end + + def self.num_pattern? (s) # :nodoc: + /\A%[EO]?[CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy\d]/ =~ s || /\A\d/ =~ s + end + + private_class_method :num_pattern? + + def self._strptime_i(str, fmt, e) # :nodoc: + fmt.scan(/%[EO]?(:{1,3}z|.)|(.)/m) do |s, c| + if s + case s + when 'A', 'a' + return unless str.sub!(/\A(#{Format::DAYS.keys.join('|')})/io, '') || + str.sub!(/\A(#{Format::ABBR_DAYS.keys.join('|')})/io, '') + val = Format::DAYS[$1.downcase] || Format::ABBR_DAYS[$1.downcase] + return unless val + e.wday = val + when 'B', 'b', 'h' + return unless str.sub!(/\A(#{Format::MONTHS.keys.join('|')})/io, '') || + str.sub!(/\A(#{Format::ABBR_MONTHS.keys.join('|')})/io, '') + val = Format::MONTHS[$1.downcase] || Format::ABBR_MONTHS[$1.downcase] + return unless val + e.mon = val + when 'C' + return unless str.sub!(if num_pattern?($') + then /\A([-+]?\d{1,2})/ + else /\A([-+]?\d{1,})/ + end, '') + val = $1.to_i + e._cent = val + when 'c' + return unless _strptime_i(str, '%a %b %e %H:%M:%S %Y', e) + when 'D' + return unless _strptime_i(str, '%m/%d/%y', e) + when 'd', 'e' + return unless str.sub!(/\A( \d|\d{1,2})/, '') + val = $1.to_i + return unless (1..31) === val + e.mday = val + when 'F' + return unless _strptime_i(str, '%Y-%m-%d', e) + when 'G' + return unless str.sub!(if num_pattern?($') + then /\A([-+]?\d{1,4})/ + else /\A([-+]?\d{1,})/ + end, '') + val = $1.to_i + e.cwyear = val + when 'g' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (0..99) === val + e.cwyear = val + e._cent ||= if val >= 69 then 19 else 20 end + when 'H', 'k' + return unless str.sub!(/\A( \d|\d{1,2})/, '') + val = $1.to_i + return unless (0..24) === val + e.hour = val + when 'I', 'l' + return unless str.sub!(/\A( \d|\d{1,2})/, '') + val = $1.to_i + return unless (1..12) === val + e.hour = val + when 'j' + return unless str.sub!(/\A(\d{1,3})/, '') + val = $1.to_i + return unless (1..366) === val + e.yday = val + when 'L' + return unless str.sub!(if num_pattern?($') + then /\A([-+]?\d{1,3})/ + else /\A([-+]?\d{1,})/ + end, '') +# val = $1.to_i.to_r / (10**3) + val = $1.to_i.to_r / (10**$1.size) + e.sec_fraction = val + when 'M' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (0..59) === val + e.min = val + when 'm' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (1..12) === val + e.mon = val + when 'N' + return unless str.sub!(if num_pattern?($') + then /\A([-+]?\d{1,9})/ + else /\A([-+]?\d{1,})/ + end, '') +# val = $1.to_i.to_r / (10**9) + val = $1.to_i.to_r / (10**$1.size) + e.sec_fraction = val + when 'n', 't' + return unless _strptime_i(str, "\s", e) + when 'P', 'p' + return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/i, '') + e._merid = if $1.downcase == 'a' then 0 else 12 end + when 'Q' + return unless str.sub!(/\A(-?\d{1,})/, '') + val = $1.to_i.to_r / 10**3 + e.seconds = val + when 'R' + return unless _strptime_i(str, '%H:%M', e) + when 'r' + return unless _strptime_i(str, '%I:%M:%S %p', e) + when 'S' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (0..60) === val + e.sec = val + when 's' + return unless str.sub!(/\A(-?\d{1,})/, '') + val = $1.to_i + e.seconds = val + when 'T' + return unless _strptime_i(str, '%H:%M:%S', e) + when 'U', 'W' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (0..53) === val + e.__send__(if s == 'U' then :wnum0= else :wnum1= end, val) + when 'u' + return unless str.sub!(/\A(\d{1})/, '') + val = $1.to_i + return unless (1..7) === val + e.cwday = val + when 'V' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (1..53) === val + e.cweek = val + when 'v' + return unless _strptime_i(str, '%e-%b-%Y', e) + when 'w' + return unless str.sub!(/\A(\d{1})/, '') + val = $1.to_i + return unless (0..6) === val + e.wday = val + when 'X' + return unless _strptime_i(str, '%H:%M:%S', e) + when 'x' + return unless _strptime_i(str, '%m/%d/%y', e) + when 'Y' + return unless str.sub!(if num_pattern?($') + then /\A([-+]?\d{1,4})/ + else /\A([-+]?\d{1,})/ + end, '') + val = $1.to_i + e.year = val + when 'y' + return unless str.sub!(/\A(\d{1,2})/, '') + val = $1.to_i + return unless (0..99) === val + e.year = val + e._cent ||= if val >= 69 then 19 else 20 end + when 'Z', /\A:{0,3}z/ + return unless str.sub!(/\A((?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)? + |[a-z.\s]+(?:standard|daylight)\s+time\b + |[a-z]+(?:\s+dst)?\b + )/ix, '') + val = $1 + e.zone = val + offset = zone_to_diff(val) + e.offset = offset + when '%' + return unless str.sub!(/\A%/, '') + when '+' + return unless _strptime_i(str, '%a %b %e %H:%M:%S %Z %Y', e) + when '1' + if $VERBOSE + warn("warning: strptime: %1 is deprecated; forget this") + end + return unless str.sub!(/\A(\d+)/, '') + val = $1.to_i + e.jd = val + when '2' + if $VERBOSE + warn("warning: strptime: %2 is deprecated; use '%Y-%j'") + end + return unless _strptime_i(str, '%Y-%j', e) + when '3' + if $VERBOSE + warn("warning: strptime: %3 is deprecated; use '%F'") + end + return unless _strptime_i(str, '%F', e) + else + return unless str.sub!(Regexp.new('\\A' + Regexp.quote(s)), '') + end + else + case c + when /\A[\s\v]/ + str.sub!(/\A[\s\v]+/, '') + else + return unless str.sub!(Regexp.new('\\A' + Regexp.quote(c)), '') + end + end + end + end + + private_class_method :_strptime_i + + def self._strptime(str, fmt='%F') + e = Format::Bag.new + return unless _strptime_i(str.dup, fmt, e) + + if e._cent + if e.cwyear + e.cwyear += e._cent * 100 + end + if e.year + e. year += e._cent * 100 + end + end + + if e._merid + if e.hour + e.hour %= 12 + e.hour += e._merid + end + end + + e.to_hash + end + + def self.s3e(e, y, m, d, bc=false) + unless String === m + m = m.to_s + end + + if y == nil + if d && d.size > 2 + y = d + d = nil + end + if d && d[0,1] == "'" + y = d + d = nil + end + end + + if y + y.scan(/(\d+)(.+)?/) + if $2 + y, d = d, $1 + end + end + + if m + if m[0,1] == "'" || m.size > 2 + y, m, d = m, d, y # us -> be + end + end + + if d + if d[0,1] == "'" || d.size > 2 + y, d = d, y + end + end + + if y + y =~ /([-+])?(\d+)/ + if $1 || $2.size > 2 + c = false + end + iy = $&.to_i + if bc + iy = -iy + 1 + end + e.year = iy + end + + if m + m =~ /\d+/ + e.mon = $&.to_i + end + + if d + d =~ /\d+/ + e.mday = $&.to_i + end + + if c != nil + e._comp = c + end + + end + + private_class_method :s3e + + def self._parse_day(str, e) # :nodoc: + if str.sub!(/\b(#{Format::ABBR_DAYS.keys.join('|')})[^-\d\s]*/ino, ' ') + e.wday = Format::ABBR_DAYS[$1.downcase] + true +=begin + elsif str.sub!(/\b(?!\dth)(su|mo|tu|we|th|fr|sa)\b/in, ' ') + e.wday = %w(su mo tu we th fr sa).index($1.downcase) + true +=end + end + end + + def self._parse_time(str, e) # :nodoc: + if str.sub!( + /( + (?: + \d+\s*:\s*\d+ + (?: + \s*:\s*\d+(?:[,.]\d*)? + )? + | + \d+\s*h(?:\s*\d+m?(?:\s*\d+s?)?)? + ) + (?: + \s* + [ap](?:m\b|\.m\.) + )? + | + \d+\s*[ap](?:m\b|\.m\.) + ) + (?: + \s* + ( + (?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)? + | + [a-z.\s]+(?:standard|daylight)\stime\b + | + [a-z]+(?:\sdst)?\b + ) + )? + /inx, + ' ') + + t = $1 + e.zone = $2 if $2 + + t =~ /\A(\d+)h? + (?:\s*:?\s*(\d+)m? + (?: + \s*:?\s*(\d+)(?:[,.](\d+))?s? + )? + )? + (?:\s*([ap])(?:m\b|\.m\.))?/inx + + e.hour = $1.to_i + e.min = $2.to_i if $2 + e.sec = $3.to_i if $3 + e.sec_fraction = $4.to_i.to_r / (10**$4.size) if $4 + + if $5 + e.hour %= 12 + if $5.downcase == 'p' + e.hour += 12 + end + end + true + end + end + + def self._parse_beat(str, e) # :nodoc: + if str.sub!(/@\s*(\d+)(?:[,.](\d*))?/, ' ') + beat = $1.to_i.to_r + beat += $2.to_i.to_r / (10**$2.size) if $2 + secs = beat.to_r / 1000 + h, min, s, fr = self.day_fraction_to_time(secs) + e.hour = h + e.min = min + e.sec = s + e.sec_fraction = fr * 86400 + e.zone = '+01:00' + true + end + end + + def self._parse_eu(str, e) # :nodoc: + if str.sub!( + /'?(\d+)[^-\d\s]* + \s* + (#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']* + (?: + \s* + (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))? + \s* + ('?-?\d+(?:(?:st|nd|rd|th)\b)?) + )? + /inox, + ' ') # ' + s3e(e, $4, Format::ABBR_MONTHS[$2.downcase], $1, + $3 && $3[0,1].downcase == 'b') + true + end + end + + def self._parse_us(str, e) # :nodoc: + if str.sub!( + /\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-\d\s']* + \s* + ('?\d+)[^-\d\s']* + (?: + \s* + (c(?:e|\.e\.)|b(?:ce|\.c\.e\.)|a(?:d|\.d\.)|b(?:c|\.c\.))? + \s* + ('?-?\d+) + )? + /inox, + ' ') # ' + s3e(e, $4, Format::ABBR_MONTHS[$1.downcase], $2, + $3 && $3[0,1].downcase == 'b') + true + end + end + + def self._parse_iso(str, e) # :nodoc: + if str.sub!(/('?[-+]?\d+)-(\d+)-('?-?\d+)/n, ' ') + s3e(e, $1, $2, $3) + true + end + end + + def self._parse_iso2(str, e) # :nodoc: + if str.sub!(/\b(\d{2}|\d{4})?-?w(\d{2})(?:-?(\d+))?/in, ' ') + e.cwyear = $1.to_i if $1 + e.cweek = $2.to_i + e.cwday = $3.to_i if $3 + true + elsif str.sub!(/--(\d{2})-(\d{2})\b/n, ' ') + e.mon = $1.to_i + e.mday = $2.to_i + true + elsif str.sub!(/\b(\d{2}|\d{4})-(\d{2,3})\b/n, ' ') + e.year = $1.to_i + if $2.size < 3 + e.mon = $2.to_i + else + e.yday = $2.to_i + end + true + end + end + + def self._parse_jis(str, e) # :nodoc: + if str.sub!(/\b([MTSH])(\d+)\.(\d+)\.(\d+)/in, ' ') + era = { 'm'=>1867, + 't'=>1911, + 's'=>1925, + 'h'=>1988 + }[$1.downcase] + e.year = $2.to_i + era + e.mon = $3.to_i + e.mday = $4.to_i + true + end + end + + def self._parse_vms(str, e) # :nodoc: + if str.sub!(/('?-?\d+)-(#{Format::ABBR_MONTHS.keys.join('|')})[^-]* + -('?-?\d+)/inox, ' ') + s3e(e, $3, Format::ABBR_MONTHS[$2.downcase], $1) + true + elsif str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-]* + -('?-?\d+)(?:-('?-?\d+))?/inox, ' ') + s3e(e, $3, Format::ABBR_MONTHS[$1.downcase], $2) + true + end + end + + def self._parse_sla_ja(str, e) # :nodoc: + if str.sub!(%r|('?-?\d+)[/.]\s*('?\d+)(?:[^\d]\s*('?-?\d+))?|n, ' ') # ' + s3e(e, $1, $2, $3) + true + end + end + + def self._parse_sla_eu(str, e) # :nodoc: + if str.sub!(%r|('?-?\d+)[/.]\s*('?\d+)(?:[^\d]\s*('?-?\d+))?|n, ' ') # ' + s3e(e, $3, $2, $1) + true + end + end + + def self._parse_sla_us(str, e) # :nodoc: + if str.sub!(%r|('?-?\d+)[/.]\s*('?\d+)(?:[^\d]\s*('?-?\d+))?|n, ' ') # ' + s3e(e, $3, $1, $2) + true + end + end + + def self._parse_year(str, e) # :nodoc: + if str.sub!(/'(\d+)\b/in, ' ') + e.year = $1.to_i + true + end + end + + def self._parse_mon(str, e) # :nodoc: + if str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})\S*/ino, ' ') + e.mon = Format::ABBR_MONTHS[$1.downcase] + true + end + end + + def self._parse_mday(str, e) # :nodoc: + if str.sub!(/(\d+)(st|nd|rd|th)\b/in, ' ') + e.mday = $1.to_i + true + end + end + + def self._parse_ddd(str, e) # :nodoc: + if str.sub!( + /([-+]?)(\d{2,14}) + (?: + \s* + T? + \s* + (\d{2,6})(?:[,.](\d*))? + )? + (?: + \s* + ( + Z + | + [-+]\d{1,4} + ) + \b + )? + /inx, + ' ') + case $2.size + when 2 + e.mday = $2[ 0, 2].to_i + when 4 + e.mon = $2[ 0, 2].to_i + e.mday = $2[ 2, 2].to_i + when 6 + e.year = ($1 + $2[ 0, 2]).to_i + e.mon = $2[ 2, 2].to_i + e.mday = $2[ 4, 2].to_i + when 8, 10, 12, 14 + e.year = ($1 + $2[ 0, 4]).to_i + e.mon = $2[ 4, 2].to_i + e.mday = $2[ 6, 2].to_i + e.hour = $2[ 8, 2].to_i if $2.size >= 10 + e.min = $2[10, 2].to_i if $2.size >= 12 + e.sec = $2[12, 2].to_i if $2.size >= 14 + e._comp = false + when 3 + e.yday = $2[ 0, 3].to_i + when 5 + e.year = ($1 + $2[ 0, 2]).to_i + e.yday = $2[ 2, 3].to_i + when 7 + e.year = ($1 + $2[ 0, 4]).to_i + e.yday = $2[ 4, 3].to_i + end + if $3 + case $3.size + when 2, 4, 6 + e.hour = $3[ 0, 2].to_i + e.min = $3[ 2, 2].to_i if $3.size >= 4 + e.sec = $3[ 4, 2].to_i if $3.size >= 6 + end + end + if $4 + e.sec_fraction = $4.to_i.to_r / (10**$4.size) + end + if $5 + e.zone = $5 + end + true + end + end + + private_class_method :_parse_day, :_parse_time, :_parse_beat, + :_parse_eu, :_parse_us, :_parse_iso, :_parse_iso2, + :_parse_jis, :_parse_vms, + :_parse_sla_ja, :_parse_sla_eu, :_parse_sla_us, + :_parse_year, :_parse_mon, :_parse_mday, :_parse_ddd + + def self._parse(str, comp=false) + str = str.dup + + e = Format::Bag.new + + e._comp = comp + + str.gsub!(/[^-+',.\/:0-9@a-z\x80-\xff]+/in, ' ') + + _parse_time(str, e) # || _parse_beat(str, e) + _parse_day(str, e) + + _parse_eu(str, e) || + _parse_us(str, e) || + _parse_iso(str, e) || + _parse_jis(str, e) || + _parse_vms(str, e) || + _parse_sla_us(str, e) || + _parse_iso2(str, e) || + _parse_year(str, e) || + _parse_mon(str, e) || + _parse_mday(str, e) || + _parse_ddd(str, e) + + if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/in, ' ') + if e.year + e.year = -e.year + 1 + end + end + + if str.sub!(/\A\s*(\d{1,2})\s*\z/n, ' ') + if e.hour && !e.mday + v = $1.to_i + if (1..31) === v + e.mday = v + end + end + if e.mday && !e.hour + v = $1.to_i + if (0..24) === v + e.hour = v + end + end + end + + if e._comp and e.year + if e.year >= 0 and e.year <= 99 + if e.year >= 69 + e.year += 1900 + else + e.year += 2000 + end + end + end + + e.offset ||= zone_to_diff(e.zone) if e.zone + + e.to_hash + end + + def self.zone_to_diff(zone) # :nodoc: + zone = zone.downcase + if zone.sub!(/\s+(standard|daylight)\s+time\z/, '') + dst = $1 == 'daylight' + else + dst = zone.sub!(/\s+dst\z/, '') + end + if Format::ZONES.include?(zone) + offset = Format::ZONES[zone] + offset += 3600 if dst + elsif zone.sub!(/\A(?:gmt|utc?)?([-+])/, '') + sign = $1 + if zone.include?(':') + hour, min, sec, = zone.split(':') + elsif zone.include?(',') || zone.include?('.') + hour, fr, = zone.split(/[,.]/) + min = fr.to_i.to_r / (10**fr.size) * 60 + else + case zone.size + when 3 + hour = zone[0,1] + min = zone[1,2] + else + hour = zone[0,2] + min = zone[2,2] + sec = zone[4,2] + end + end + offset = hour.to_i * 3600 + min.to_i * 60 + sec.to_i + offset *= -1 if sign == '-' + end + offset + end + +end + +class DateTime < Date + + def strftime(fmt='%FT%T%:z') + super(fmt) + end + + def self._strptime(str, fmt='%FT%T%z') + super(str, fmt) + end + +=begin + def iso8601_timediv(n) # :nodoc: + strftime('T%T' + + if n < 1 + '' + else + '.%0*d' % [n, (sec_fraction / (1.to_r/86400/(10**n))).round] + end + + '%:z') + end + + private :iso8601_timediv + + def iso8601(n=0) + super() + iso8601_timediv(n) + end + + def rfc3339(n=0) iso8601(n) end + + def jisx0301(n=0) + super() + iso8601_timediv(n) + end +=end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date2.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date2.rb new file mode 100644 index 00000000..f7da78f6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/date2.rb @@ -0,0 +1,5 @@ +# date2 was overridden by date. +# To be precise, date was overridden by date2, +# and date2 was renamed to date. + +require 'date' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/debug.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/debug.rb new file mode 100644 index 00000000..9ae119f8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/debug.rb @@ -0,0 +1,947 @@ +# Copyright (C) 2000 Network Applied Communication Laboratory, Inc. +# Copyright (C) 2000 Information-technology Promotion Agency, Japan +# Copyright (C) 2000-2003 NAKAMURA, Hiroshi + +if $SAFE > 0 + STDERR.print "-r debug.rb is not available in safe mode\n" + exit 1 +end + +require 'tracer' +require 'pp' + +class Tracer + def Tracer.trace_func(*vars) + Single.trace_func(*vars) + end +end + +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ + +class DEBUGGER__ +class Mutex + def initialize + @locker = nil + @waiting = [] + @locked = false; + end + + def locked? + @locked + end + + def lock + return if Thread.critical + return if @locker == Thread.current + while (Thread.critical = true; @locked) + @waiting.push Thread.current + Thread.stop + end + @locked = true + @locker = Thread.current + Thread.critical = false + self + end + + def unlock + return if Thread.critical + return unless @locked + unless @locker == Thread.current + raise RuntimeError, "unlocked by other" + end + Thread.critical = true + t = @waiting.shift + @locked = false + @locker = nil + Thread.critical = false + t.run if t + self + end +end +MUTEX = Mutex.new + +class Context + DEBUG_LAST_CMD = [] + + begin + require 'readline' + def readline(prompt, hist) + Readline::readline(prompt, hist) + end + rescue LoadError + def readline(prompt, hist) + STDOUT.print prompt + STDOUT.flush + line = STDIN.gets + exit unless line + line.chomp! + line + end + USE_READLINE = false + end + + def initialize + if Thread.current == Thread.main + @stop_next = 1 + else + @stop_next = 0 + end + @last_file = nil + @file = nil + @line = nil + @no_step = nil + @frames = [] + @finish_pos = 0 + @trace = false + @catch = "StandardError" + @suspend_next = false + end + + def stop_next(n=1) + @stop_next = n + end + + def set_suspend + @suspend_next = true + end + + def clear_suspend + @suspend_next = false + end + + def suspend_all + DEBUGGER__.suspend + end + + def resume_all + DEBUGGER__.resume + end + + def check_suspend + return if Thread.critical + while (Thread.critical = true; @suspend_next) + DEBUGGER__.waiting.push Thread.current + @suspend_next = false + Thread.stop + end + Thread.critical = false + end + + def trace? + @trace + end + + def set_trace(arg) + @trace = arg + end + + def stdout + DEBUGGER__.stdout + end + + def break_points + DEBUGGER__.break_points + end + + def display + DEBUGGER__.display + end + + def context(th) + DEBUGGER__.context(th) + end + + def set_trace_all(arg) + DEBUGGER__.set_trace(arg) + end + + def set_last_thread(th) + DEBUGGER__.set_last_thread(th) + end + + def debug_eval(str, binding) + begin + val = eval(str, binding) + rescue StandardError, ScriptError => e + at = eval("caller(1)", binding) + stdout.printf "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '') + for i in at + stdout.printf "\tfrom %s\n", i + end + throw :debug_error + end + end + + def debug_silent_eval(str, binding) + begin + eval(str, binding) + rescue StandardError, ScriptError + nil + end + end + + def var_list(ary, binding) + ary.sort! + for v in ary + stdout.printf " %s => %s\n", v, eval(v, binding).inspect + end + end + + def debug_variable_info(input, binding) + case input + when /^\s*g(?:lobal)?\s*$/ + var_list(global_variables, binding) + + when /^\s*l(?:ocal)?\s*$/ + var_list(eval("local_variables", binding), binding) + + when /^\s*i(?:nstance)?\s+/ + obj = debug_eval($', binding) + var_list(obj.instance_variables, obj.instance_eval{binding()}) + + when /^\s*c(?:onst(?:ant)?)?\s+/ + obj = debug_eval($', binding) + unless obj.kind_of? Module + stdout.print "Should be Class/Module: ", $', "\n" + else + var_list(obj.constants, obj.module_eval{binding()}) + end + end + end + + def debug_method_info(input, binding) + case input + when /^i(:?nstance)?\s+/ + obj = debug_eval($', binding) + + len = 0 + for v in obj.methods.sort + len += v.size + 1 + if len > 70 + len = v.size + 1 + stdout.print "\n" + end + stdout.print v, " " + end + stdout.print "\n" + + else + obj = debug_eval(input, binding) + unless obj.kind_of? Module + stdout.print "Should be Class/Module: ", input, "\n" + else + len = 0 + for v in obj.instance_methods(false).sort + len += v.size + 1 + if len > 70 + len = v.size + 1 + stdout.print "\n" + end + stdout.print v, " " + end + stdout.print "\n" + end + end + end + + def thnum + num = DEBUGGER__.instance_eval{@thread_list[Thread.current]} + unless num + DEBUGGER__.make_thread_list + num = DEBUGGER__.instance_eval{@thread_list[Thread.current]} + end + num + end + + def debug_command(file, line, id, binding) + MUTEX.lock + unless defined?($debugger_restart) and $debugger_restart + callcc{|c| $debugger_restart = c} + end + set_last_thread(Thread.current) + frame_pos = 0 + binding_file = file + binding_line = line + previous_line = nil + if ENV['EMACS'] + stdout.printf "\032\032%s:%d:\n", binding_file, binding_line + else + stdout.printf "%s:%d:%s", binding_file, binding_line, + line_at(binding_file, binding_line) + end + @frames[0] = [binding, file, line, id] + display_expressions(binding) + prompt = true + while prompt and input = readline("(rdb:%d) "%thnum(), true) + catch(:debug_error) do + if input == "" + next unless DEBUG_LAST_CMD[0] + input = DEBUG_LAST_CMD[0] + stdout.print input, "\n" + else + DEBUG_LAST_CMD[0] = input + end + + case input + when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/ + if defined?( $2 ) + if $1 == 'on' + set_trace_all true + else + set_trace_all false + end + elsif defined?( $1 ) + if $1 == 'on' + set_trace true + else + set_trace false + end + end + if trace? + stdout.print "Trace on.\n" + else + stdout.print "Trace off.\n" + end + + when /^\s*b(?:reak)?\s+(?:(.+):)?([^.:]+)$/ + pos = $2 + if $1 + klass = debug_silent_eval($1, binding) + file = $1 + end + if pos =~ /^\d+$/ + pname = pos + pos = pos.to_i + else + pname = pos = pos.intern.id2name + end + break_points.push [true, 0, klass || file, pos] + stdout.printf "Set breakpoint %d at %s:%s\n", break_points.size, klass || file, pname + + when /^\s*b(?:reak)?\s+(.+)[#.]([^.:]+)$/ + pos = $2.intern.id2name + klass = debug_eval($1, binding) + break_points.push [true, 0, klass, pos] + stdout.printf "Set breakpoint %d at %s.%s\n", break_points.size, klass, pos + + when /^\s*wat(?:ch)?\s+(.+)$/ + exp = $1 + break_points.push [true, 1, exp] + stdout.printf "Set watchpoint %d:%s\n", break_points.size, exp + + when /^\s*b(?:reak)?$/ + if break_points.find{|b| b[1] == 0} + n = 1 + stdout.print "Breakpoints:\n" + for b in break_points + if b[0] and b[1] == 0 + stdout.printf " %d %s:%s\n", n, b[2], b[3] + end + n += 1 + end + end + if break_points.find{|b| b[1] == 1} + n = 1 + stdout.print "\n" + stdout.print "Watchpoints:\n" + for b in break_points + if b[0] and b[1] == 1 + stdout.printf " %d %s\n", n, b[2] + end + n += 1 + end + end + if break_points.size == 0 + stdout.print "No breakpoints\n" + else + stdout.print "\n" + end + + when /^\s*del(?:ete)?(?:\s+(\d+))?$/ + pos = $1 + unless pos + input = readline("Clear all breakpoints? (y/n) ", false) + if input == "y" + for b in break_points + b[0] = false + end + end + else + pos = pos.to_i + if break_points[pos-1] + break_points[pos-1][0] = false + else + stdout.printf "Breakpoint %d is not defined\n", pos + end + end + + when /^\s*disp(?:lay)?\s+(.+)$/ + exp = $1 + display.push [true, exp] + stdout.printf "%d: ", display.size + display_expression(exp, binding) + + when /^\s*disp(?:lay)?$/ + display_expressions(binding) + + when /^\s*undisp(?:lay)?(?:\s+(\d+))?$/ + pos = $1 + unless pos + input = readline("Clear all expressions? (y/n) ", false) + if input == "y" + for d in display + d[0] = false + end + end + else + pos = pos.to_i + if display[pos-1] + display[pos-1][0] = false + else + stdout.printf "Display expression %d is not defined\n", pos + end + end + + when /^\s*c(?:ont)?$/ + prompt = false + + when /^\s*s(?:tep)?(?:\s+(\d+))?$/ + if $1 + lev = $1.to_i + else + lev = 1 + end + @stop_next = lev + prompt = false + + when /^\s*n(?:ext)?(?:\s+(\d+))?$/ + if $1 + lev = $1.to_i + else + lev = 1 + end + @stop_next = lev + @no_step = @frames.size - frame_pos + prompt = false + + when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/ + display_frames(frame_pos) + + when /^\s*l(?:ist)?(?:\s+(.+))?$/ + if not $1 + b = previous_line ? previous_line + 10 : binding_line - 5 + e = b + 9 + elsif $1 == '-' + b = previous_line ? previous_line - 10 : binding_line - 5 + e = b + 9 + else + b, e = $1.split(/[-,]/) + if e + b = b.to_i + e = e.to_i + else + b = b.to_i - 5 + e = b + 9 + end + end + previous_line = b + display_list(b, e, binding_file, binding_line) + + when /^\s*up(?:\s+(\d+))?$/ + previous_line = nil + if $1 + lev = $1.to_i + else + lev = 1 + end + frame_pos += lev + if frame_pos >= @frames.size + frame_pos = @frames.size - 1 + stdout.print "At toplevel\n" + end + binding, binding_file, binding_line = @frames[frame_pos] + stdout.print format_frame(frame_pos) + + when /^\s*down(?:\s+(\d+))?$/ + previous_line = nil + if $1 + lev = $1.to_i + else + lev = 1 + end + frame_pos -= lev + if frame_pos < 0 + frame_pos = 0 + stdout.print "At stack bottom\n" + end + binding, binding_file, binding_line = @frames[frame_pos] + stdout.print format_frame(frame_pos) + + when /^\s*fin(?:ish)?$/ + if frame_pos == @frames.size + stdout.print "\"finish\" not meaningful in the outermost frame.\n" + else + @finish_pos = @frames.size - frame_pos + frame_pos = 0 + prompt = false + end + + when /^\s*cat(?:ch)?(?:\s+(.+))?$/ + if $1 + excn = $1 + if excn == 'off' + @catch = nil + stdout.print "Clear catchpoint.\n" + else + @catch = excn + stdout.printf "Set catchpoint %s.\n", @catch + end + else + if @catch + stdout.printf "Catchpoint %s.\n", @catch + else + stdout.print "No catchpoint.\n" + end + end + + when /^\s*q(?:uit)?$/ + input = readline("Really quit? (y/n) ", false) + if input == "y" + exit! # exit -> exit!: No graceful way to stop threads... + end + + when /^\s*v(?:ar)?\s+/ + debug_variable_info($', binding) + + when /^\s*m(?:ethod)?\s+/ + debug_method_info($', binding) + + when /^\s*th(?:read)?\s+/ + if DEBUGGER__.debug_thread_info($', binding) == :cont + prompt = false + end + + when /^\s*pp\s+/ + PP.pp(debug_eval($', binding), stdout) + + when /^\s*p\s+/ + stdout.printf "%s\n", debug_eval($', binding).inspect + + when /^\s*r(?:estart)?$/ + $debugger_restart.call + + when /^\s*h(?:elp)?$/ + debug_print_help() + + else + v = debug_eval(input, binding) + stdout.printf "%s\n", v.inspect + end + end + end + MUTEX.unlock + resume_all + end + + def debug_print_help + stdout.print < + b[reak] [class.] + set breakpoint to some position + wat[ch] set watchpoint to some expression + cat[ch] (|off) set catchpoint to an exception + b[reak] list breakpoints + cat[ch] show catchpoint + del[ete][ nnn] delete some or all breakpoints + disp[lay] add expression into display expression list + undisp[lay][ nnn] delete one particular or all display expressions + c[ont] run until program ends or hit breakpoint + s[tep][ nnn] step (into methods) one line or till line nnn + n[ext][ nnn] go over one line or till line nnn + w[here] display frames + f[rame] alias for where + l[ist][ (-|nn-mm)] list program, - lists backwards + nn-mm lists given lines + up[ nn] move to higher frame + down[ nn] move to lower frame + fin[ish] return to outer frame + tr[ace] (on|off) set trace mode of current thread + tr[ace] (on|off) all set trace mode of all threads + q[uit] exit from debugger + v[ar] g[lobal] show global variables + v[ar] l[ocal] show local variables + v[ar] i[nstance] show instance variables of object + v[ar] c[onst] show constants of object + m[ethod] i[nstance] show methods of object + m[ethod] show instance methods of class or module + th[read] l[ist] list all threads + th[read] c[ur[rent]] show current thread + th[read] [sw[itch]] switch thread context to nnn + th[read] stop stop thread nnn + th[read] resume resume thread nnn + p expression evaluate expression and print its value + h[elp] print this help + evaluate +EOHELP + end + + def display_expressions(binding) + n = 1 + for d in display + if d[0] + stdout.printf "%d: ", n + display_expression(d[1], binding) + end + n += 1 + end + end + + def display_expression(exp, binding) + stdout.printf "%s = %s\n", exp, debug_silent_eval(exp, binding).to_s + end + + def frame_set_pos(file, line) + if @frames[0] + @frames[0][1] = file + @frames[0][2] = line + end + end + + def display_frames(pos) + 0.upto(@frames.size - 1) do |n| + if n == pos + stdout.print "--> " + else + stdout.print " " + end + stdout.print format_frame(n) + end + end + + def format_frame(pos) + bind, file, line, id = @frames[pos] + sprintf "#%d %s:%s%s\n", pos + 1, file, line, + (id ? ":in `#{id.id2name}'" : "") + end + + def display_list(b, e, file, line) + stdout.printf "[%d, %d] in %s\n", b, e, file + if lines = SCRIPT_LINES__[file] and lines != true + n = 0 + b.upto(e) do |n| + if n > 0 && lines[n-1] + if n == line + stdout.printf "=> %d %s\n", n, lines[n-1].chomp + else + stdout.printf " %d %s\n", n, lines[n-1].chomp + end + end + end + else + stdout.printf "No sourcefile available for %s\n", file + end + end + + def line_at(file, line) + lines = SCRIPT_LINES__[file] + if lines + return "\n" if lines == true + line = lines[line-1] + return "\n" unless line + return line + end + return "\n" + end + + def debug_funcname(id) + if id.nil? + "toplevel" + else + id.id2name + end + end + + def check_break_points(file, klass, pos, binding, id) + return false if break_points.empty? + n = 1 + for b in break_points + if b[0] # valid + if b[1] == 0 # breakpoint + if (b[2] == file and b[3] == pos) or + (klass and b[2] == klass and b[3] == pos) + stdout.printf "Breakpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos + return true + end + elsif b[1] == 1 # watchpoint + if debug_silent_eval(b[2], binding) + stdout.printf "Watchpoint %d, %s at %s:%s\n", n, debug_funcname(id), file, pos + return true + end + end + end + n += 1 + end + return false + end + + def excn_handle(file, line, id, binding) + if $!.class <= SystemExit + set_trace_func nil + exit + end + + if @catch and ($!.class.ancestors.find { |e| e.to_s == @catch }) + stdout.printf "%s:%d: `%s' (%s)\n", file, line, $!, $!.class + fs = @frames.size + tb = caller(0)[-fs..-1] + if tb + for i in tb + stdout.printf "\tfrom %s\n", i + end + end + suspend_all + debug_command(file, line, id, binding) + end + end + + def trace_func(event, file, line, id, binding, klass) + Tracer.trace_func(event, file, line, id, binding, klass) if trace? + context(Thread.current).check_suspend + @file = file + @line = line + case event + when 'line' + frame_set_pos(file, line) + if !@no_step or @frames.size == @no_step + @stop_next -= 1 + @stop_next = -1 if @stop_next < 0 + elsif @frames.size < @no_step + @stop_next = 0 # break here before leaving... + else + # nothing to do. skipped. + end + if @stop_next == 0 or check_break_points(file, nil, line, binding, id) + @no_step = nil + suspend_all + debug_command(file, line, id, binding) + end + + when 'call' + @frames.unshift [binding, file, line, id] + if check_break_points(file, klass, id.id2name, binding, id) + suspend_all + debug_command(file, line, id, binding) + end + + when 'c-call' + frame_set_pos(file, line) + + when 'class' + @frames.unshift [binding, file, line, id] + + when 'return', 'end' + if @frames.size == @finish_pos + @stop_next = 1 + @finish_pos = 0 + end + @frames.shift + + when 'end' + @frames.shift + + when 'raise' + excn_handle(file, line, id, binding) + + end + @last_file = file + end +end + +trap("INT") { DEBUGGER__.interrupt } +@last_thread = Thread::main +@max_thread = 1 +@thread_list = {Thread::main => 1} +@break_points = [] +@display = [] +@waiting = [] +@stdout = STDOUT + +class << DEBUGGER__ + def stdout + @stdout + end + + def stdout=(s) + @stdout = s + end + + def display + @display + end + + def break_points + @break_points + end + + def waiting + @waiting + end + + def set_trace( arg ) + saved_crit = Thread.critical + Thread.critical = true + make_thread_list + for th, in @thread_list + context(th).set_trace arg + end + Thread.critical = saved_crit + arg + end + + def set_last_thread(th) + @last_thread = th + end + + def suspend + saved_crit = Thread.critical + Thread.critical = true + make_thread_list + for th, in @thread_list + next if th == Thread.current + context(th).set_suspend + end + Thread.critical = saved_crit + # Schedule other threads to suspend as soon as possible. + Thread.pass unless Thread.critical + end + + def resume + saved_crit = Thread.critical + Thread.critical = true + make_thread_list + for th, in @thread_list + next if th == Thread.current + context(th).clear_suspend + end + waiting.each do |th| + th.run + end + waiting.clear + Thread.critical = saved_crit + # Schedule other threads to restart as soon as possible. + Thread.pass + end + + def context(thread=Thread.current) + c = thread[:__debugger_data__] + unless c + thread[:__debugger_data__] = c = Context.new + end + c + end + + def interrupt + context(@last_thread).stop_next + end + + def get_thread(num) + th = @thread_list.index(num) + unless th + @stdout.print "No thread ##{num}\n" + throw :debug_error + end + th + end + + def thread_list(num) + th = get_thread(num) + if th == Thread.current + @stdout.print "+" + else + @stdout.print " " + end + @stdout.printf "%d ", num + @stdout.print th.inspect, "\t" + file = context(th).instance_eval{@file} + if file + @stdout.print file,":",context(th).instance_eval{@line} + end + @stdout.print "\n" + end + + def thread_list_all + for th in @thread_list.values.sort + thread_list(th) + end + end + + def make_thread_list + hash = {} + for th in Thread::list + if @thread_list.key? th + hash[th] = @thread_list[th] + else + @max_thread += 1 + hash[th] = @max_thread + end + end + @thread_list = hash + end + + def debug_thread_info(input, binding) + case input + when /^l(?:ist)?/ + make_thread_list + thread_list_all + + when /^c(?:ur(?:rent)?)?$/ + make_thread_list + thread_list(@thread_list[Thread.current]) + + when /^(?:sw(?:itch)?\s+)?(\d+)/ + make_thread_list + th = get_thread($1.to_i) + if th == Thread.current + @stdout.print "It's the current thread.\n" + else + thread_list(@thread_list[th]) + context(th).stop_next + th.run + return :cont + end + + when /^stop\s+(\d+)/ + make_thread_list + th = get_thread($1.to_i) + if th == Thread.current + @stdout.print "It's the current thread.\n" + elsif th.stop? + @stdout.print "Already stopped.\n" + else + thread_list(@thread_list[th]) + context(th).suspend + end + + when /^resume\s+(\d+)/ + make_thread_list + th = get_thread($1.to_i) + if th == Thread.current + @stdout.print "It's the current thread.\n" + elsif !th.stop? + @stdout.print "Already running." + else + thread_list(@thread_list[th]) + th.run + end + end + end +end + +stdout.printf "Debug.rb\n" +stdout.printf "Emacs support available.\n\n" +set_trace_func proc { |event, file, line, id, binding, klass, *rest| + DEBUGGER__.context.trace_func event, file, line, id, binding, klass +} +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/delegate.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/delegate.rb new file mode 100644 index 00000000..ee5fe8d7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/delegate.rb @@ -0,0 +1,339 @@ +# = delegate -- Support for the Delegation Pattern +# +# Documentation by James Edward Gray II and Gavin Sinclair +# +# == Introduction +# +# This library provides three different ways to delegate method calls to an +# object. The easiest to use is SimpleDelegator. Pass an object to the +# constructor and all methods supported by the object will be delegated. This +# object can be changed later. +# +# Going a step further, the top level DelegateClass method allows you to easily +# setup delegation through class inheritance. This is considerably more +# flexible and thus probably the most common use for this library. +# +# Finally, if you need full control over the delegation scheme, you can inherit +# from the abstract class Delegator and customize as needed. (If you find +# yourself needing this control, have a look at _forwardable_, also in the +# standard library. It may suit your needs better.) +# +# == Notes +# +# Be advised, RDoc will not detect delegated methods. +# +# delegate.rb provides full-class delegation via the +# DelegateClass() method. For single-method delegation via +# def_delegator(), see forwardable.rb. +# +# == Examples +# +# === SimpleDelegator +# +# Here's a simple example that takes advantage of the fact that +# SimpleDelegator's delegation object can be changed at any time. +# +# class Stats +# def initialize +# @source = SimpleDelegator.new([]) +# end +# +# def stats( records ) +# @source.__setobj__(records) +# +# "Elements: #{@source.size}\n" + +# " Non-Nil: #{@source.compact.size}\n" + +# " Unique: #{@source.uniq.size}\n" +# end +# end +# +# s = Stats.new +# puts s.stats(%w{James Edward Gray II}) +# puts +# puts s.stats([1, 2, 3, nil, 4, 5, 1, 2]) +# +# Prints: +# +# Elements: 4 +# Non-Nil: 4 +# Unique: 4 +# +# Elements: 8 +# Non-Nil: 7 +# Unique: 6 +# +# === DelegateClass() +# +# Here's a sample of use from tempfile.rb. +# +# A _Tempfile_ object is really just a _File_ object with a few special rules +# about storage location and/or when the File should be deleted. That makes for +# an almost textbook perfect example of how to use delegation. +# +# class Tempfile < DelegateClass(File) +# # constant and class member data initialization... +# +# def initialize(basename, tmpdir=Dir::tmpdir) +# # build up file path/name in var tmpname... +# +# @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600) +# +# # ... +# +# super(@tmpfile) +# +# # below this point, all methods of File are supported... +# end +# +# # ... +# end +# +# === Delegator +# +# SimpleDelegator's implementation serves as a nice example here. +# +# class SimpleDelegator < Delegator +# def initialize(obj) +# super # pass obj to Delegator constructor, required +# @_sd_obj = obj # store obj for future use +# end +# +# def __getobj__ +# @_sd_obj # return object we are delegating to, required +# end +# +# def __setobj__(obj) +# @_sd_obj = obj # change delegation object, a feature we're providing +# end +# +# # ... +# end + +# +# Delegator is an abstract class used to build delegator pattern objects from +# subclasses. Subclasses should redefine \_\_getobj\_\_. For a concrete +# implementation, see SimpleDelegator. +# +class Delegator + + # + # Pass in the _obj_ to delegate method calls to. All methods supported by + # _obj_ will be delegated to. + # + def initialize(obj) + preserved = ::Kernel.public_instance_methods(false) + preserved -= ["to_s","to_a","inspect","==","=~","==="] + for t in self.class.ancestors + preserved |= t.public_instance_methods(false) + preserved |= t.private_instance_methods(false) + preserved |= t.protected_instance_methods(false) + break if t == Delegator + end + preserved << "singleton_method_added" + for method in obj.methods + next if preserved.include? method + begin + eval <<-EOS + def self.#{method}(*args, &block) + begin + __getobj__.__send__(:#{method}, *args, &block) + rescue Exception + $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` + $@.delete_if{|s| /^\\(eval\\):/ =~ s} + Kernel::raise + end + end + EOS + rescue SyntaxError + raise NameError, "invalid identifier %s" % method, caller(4) + end + end + end + alias initialize_methods initialize + + # Handles the magic of delegation through \_\_getobj\_\_. + def method_missing(m, *args) + target = self.__getobj__ + unless target.respond_to?(m) + super(m, *args) + end + target.__send__(m, *args) + end + + # + # Checks for a method provided by this the delegate object by fowarding the + # call through \_\_getobj\_\_. + # + def respond_to?(m, include_private = false) + return true if super + return self.__getobj__.respond_to?(m, include_private) + end + + # + # This method must be overridden by subclasses and should return the object + # method calls are being delegated to. + # + def __getobj__ + raise NotImplementedError, "need to define `__getobj__'" + end + + # Serialization support for the object returned by \_\_getobj\_\_. + def marshal_dump + __getobj__ + end + # Reinitializes delegation from a serialized object. + def marshal_load(obj) + initialize_methods(obj) + __setobj__(obj) + end +end + +# +# A concrete implementation of Delegator, this class provides the means to +# delegate all supported method calls to the object passed into the constructor +# and even to change the object being delegated to at a later time with +# \_\_setobj\_\_ . +# +class SimpleDelegator Edward + # names.__setobj__(%w{Gavin Sinclair}) + # puts names[1] # => Sinclair + # + def __setobj__(obj) + raise ArgumentError, "cannot delegate to self" if self.equal?(obj) + @_sd_obj = obj + end + + # Clone support for the object returned by \_\_getobj\_\_. + def clone + new = super + new.__setobj__(__getobj__.clone) + new + end + # Duplication support for the object returned by \_\_getobj\_\_. + def dup + new = super + new.__setobj__(__getobj__.clone) + new + end +end + +# :stopdoc: +# backward compatibility ^_^;;; +Delegater = Delegator +SimpleDelegater = SimpleDelegator +# :startdoc: + +# +# The primary interface to this library. Use to setup delegation when defining +# your class. +# +# class MyClass < DelegateClass( ClassToDelegateTo ) # Step 1 +# def initiaize +# super(obj_of_ClassToDelegateTo) # Step 2 +# end +# end +# +def DelegateClass(superclass) + klass = Class.new + methods = superclass.public_instance_methods(true) + methods -= ::Kernel.public_instance_methods(false) + methods |= ["to_s","to_a","inspect","==","=~","==="] + klass.module_eval { + def initialize(obj) # :nodoc: + @_dc_obj = obj + end + def method_missing(m, *args) # :nodoc: + unless @_dc_obj.respond_to?(m) + super(m, *args) + end + @_dc_obj.__send__(m, *args) + end + def respond_to?(m, include_private = false) # :nodoc: + return true if super + return @_dc_obj.respond_to?(m, include_private) + end + def __getobj__ # :nodoc: + @_dc_obj + end + def __setobj__(obj) # :nodoc: + raise ArgumentError, "cannot delegate to self" if self.equal?(obj) + @_dc_obj = obj + end + def clone # :nodoc: + new = super + new.__setobj__(__getobj__.clone) + new + end + def dup # :nodoc: + new = super + new.__setobj__(__getobj__.clone) + new + end + } + for method in methods + begin + klass.module_eval <<-EOS + def #{method}(*args, &block) + begin + @_dc_obj.__send__(:#{method}, *args, &block) + rescue + $@[0,2] = nil + raise + end + end + EOS + rescue SyntaxError + raise NameError, "invalid identifier %s" % method, caller(3) + end + end + return klass +end + +# :enddoc: + +if __FILE__ == $0 + class ExtArray true + foo2.error # raise error! +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/digest.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/digest.rb new file mode 100644 index 00000000..0c4ee3c2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/digest.rb @@ -0,0 +1,50 @@ +require 'digest.so' + +module Digest + def self.const_missing(name) + case name + when :SHA256, :SHA384, :SHA512 + lib = 'digest/sha2.so' + else + lib = File.join('digest', name.to_s.downcase) + end + + begin + require lib + rescue LoadError => e + raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1) + end + unless Digest.const_defined?(name) + raise NameError, "uninitialized constant Digest::#{name}", caller(1) + end + Digest.const_get(name) + end + + class ::Digest::Class + # creates a digest object and reads a given file, _name_. + # + # p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest + # # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534" + def self.file(name) + new.file(name) + end + end + + module Instance + # updates the digest with the contents of a given file _name_ and + # returns self. + def file(name) + File.open(name, "rb") {|f| + buf = "" + while f.read(16384, buf) + update buf + end + } + self + end + end +end + +def Digest(name) + Digest.const_get(name) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/digest/sha2.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/digest/sha2.rb new file mode 100644 index 00000000..c16305dc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/digest/sha2.rb @@ -0,0 +1,73 @@ +#-- +# sha2.rb - defines Digest::SHA2 class which wraps up the SHA256, +# SHA384, and SHA512 classes. +#++ +# Copyright (c) 2006 Akinori MUSHA +# +# All rights reserved. You can redistribute and/or modify it under the same +# terms as Ruby. +# +# $Id: sha2.rb 11708 2007-02-12 23:01:19Z shyouhei $ + +require 'digest' + +module Digest + # + # A meta digest provider class for SHA256, SHA384 and SHA512. + # + class SHA2 < Digest::Class + # call-seq: + # Digest::SHA2.new(bitlen = 256) -> digest_obj + # + # Creates a new SHA2 hash object with a given bit length. + def initialize(bitlen = 256) + case bitlen + when 256 + @sha2 = Digest::SHA256.new + when 384 + @sha2 = Digest::SHA384.new + when 512 + @sha2 = Digest::SHA512.new + else + raise ArgumentError, "unsupported bit length: %s" % bitlen.inspect + end + @bitlen = bitlen + end + + # :nodoc: + def reset + @sha2.reset + self + end + + # :nodoc: + def update(str) + @sha2.update(str) + self + end + alias << update + + def finish + @sha2.digest! + end + private :finish + + def block_length + @sha2.block_length + end + + def digest_length + @sha2.digest_length + end + + # :nodoc: + def initialize_copy(other) + @sha2 = other.instance_eval { @sha2.clone } + end + + # :nodoc: + def inspect + "#<%s:%d %s>" % [self.class.name, @bitlen, hexdigest] + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/import.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/import.rb new file mode 100644 index 00000000..01ee2490 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/import.rb @@ -0,0 +1,225 @@ +# -*- ruby -*- + +require 'dl' +require 'dl/types' + +module DL + module Importable + LIB_MAP = {} + + module Internal + def init_types() + @types ||= ::DL::Types.new + end + + def init_sym() + @SYM ||= {} + end + + def [](name) + return @SYM[name.to_s][0] + end + + def dlload(*libnames) + if( !defined?(@LIBS) ) + @LIBS = [] + end + libnames.each{|libname| + if( !LIB_MAP[libname] ) + LIB_MAP[libname] = DL.dlopen(libname) + end + @LIBS.push(LIB_MAP[libname]) + } + end + alias dllink :dlload + + def parse_cproto(proto) + proto = proto.gsub(/\s+/, " ").strip + case proto + when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/ + ret = $1 + args = $2.strip() + ret = ret.split(/\s+/) + args = args.split(/\s*,\s*/) + func = ret.pop() + if( func =~ /^\*/ ) + func.gsub!(/^\*+/,"") + ret.push("*") + end + ret = ret.join(" ") + return [func, ret, args] + else + raise(RuntimeError,"can't parse the function prototype: #{proto}") + end + end + + # example: + # extern "int strlen(char*)" + # + def extern(proto) + func,ret,args = parse_cproto(proto) + return import(func, ret, args) + end + + # example: + # callback "int method_name(int, char*)" + # + def callback(proto) + func,ret,args = parse_cproto(proto) + + init_types() + init_sym() + + rty,renc,rdec = @types.encode_return_type(ret) + if( !rty ) + raise(TypeError, "unsupported type: #{ret}") + end + ty,enc,dec = encode_argument_types(args) + symty = rty + ty + + module_eval("module_function :#{func}") + sym = module_eval([ + "DL::callback(\"#{symty}\"){|*args|", + " sym,rdec,enc,dec = @SYM['#{func}']", + " args = enc.call(args) if enc", + " r,rs = #{func}(*args)", + " r = renc.call(r) if rdec", + " rs = dec.call(rs) if (dec && rs)", + " @retval = r", + " @args = rs", + " r", + "}", + ].join("\n")) + + @SYM[func] = [sym,rdec,enc,dec] + + return sym + end + + # example: + # typealias("uint", "unsigned int") + # + def typealias(alias_type, ty1, enc1=nil, dec1=nil, ty2=nil, enc2=nil, dec2=nil) + init_types() + @types.typealias(alias_type, ty1, enc1, dec1, + ty2||ty1, enc2, dec2) + end + + # example: + # symbol "foo_value" + # symbol "foo_func", "IIP" + # + def symbol(name, ty = nil) + sym = nil + @LIBS.each{|lib| + begin + if( ty ) + sym = lib[name, ty] + else + sym = lib[name] + end + rescue + next + end + } + if( !sym ) + raise(RuntimeError, "can't find the symbol `#{name}'") + end + return sym + end + + # example: + # import("get_length", "int", ["void*", "int"]) + # + def import(name, rettype, argtypes = nil) + init_types() + init_sym() + + rty,_,rdec = @types.encode_return_type(rettype) + if( !rty ) + raise(TypeError, "unsupported type: #{rettype}") + end + ty,enc,dec = encode_argument_types(argtypes) + symty = rty + ty + + sym = symbol(name, symty) + + mname = name.dup + if( ?A <= mname[0] && mname[0] <= ?Z ) + mname[0,1] = mname[0,1].downcase + end + @SYM[mname] = [sym,rdec,enc,dec] + + module_eval [ + "def #{mname}(*args)", + " sym,rdec,enc,dec = @SYM['#{mname}']", + " args = enc.call(args) if enc", + if( $DEBUG ) + " p \"[DL] call #{mname} with \#{args.inspect}\"" + else + "" + end, + " r,rs = sym.call(*args)", + if( $DEBUG ) + " p \"[DL] retval=\#{r.inspect} args=\#{rs.inspect}\"" + else + "" + end, + " r = rdec.call(r) if rdec", + " rs = dec.call(rs) if dec", + " @retval = r", + " @args = rs", + " return r", + "end", + "module_function :#{mname}", + ].join("\n") + + return sym + end + + def _args_ + return @args + end + + def _retval_ + return @retval + end + + def encode_argument_types(tys) + init_types() + encty = [] + enc = nil + dec = nil + tys.each_with_index{|ty,idx| + ty,c1,c2 = @types.encode_argument_type(ty) + if( !ty ) + raise(TypeError, "unsupported type: #{ty}") + end + encty.push(ty) + if( enc ) + if( c1 ) + conv1 = enc + enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v} + end + else + if( c1 ) + enc = proc{|v| v[idx] = c1.call(v[idx]); v} + end + end + if( dec ) + if( c2 ) + conv2 = dec + dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v} + end + else + if( c2 ) + dec = proc{|v| v[idx] = c2.call(v[idx]); v} + end + end + } + return [encty.join, enc, dec] + end + end # end of Internal + include Internal + end # end of Importable +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/struct.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/struct.rb new file mode 100644 index 00000000..33f303fe --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/struct.rb @@ -0,0 +1,149 @@ +# -*- ruby -*- + +require 'dl' +require 'dl/import' + +module DL + module Importable + module Internal + def define_struct(contents) + init_types() + Struct.new(@types, contents) + end + alias struct define_struct + + def define_union(contents) + init_types() + Union.new(@types, contents) + end + alias union define_union + + class Memory + def initialize(ptr, names, ty, len, enc, dec) + @ptr = ptr + @names = names + @ty = ty + @len = len + @enc = enc + @dec = dec + + # define methods + @names.each{|name| + instance_eval [ + "def #{name}", + " v = @ptr[\"#{name}\"]", + " if( @len[\"#{name}\"] )", + " v = v.collect{|x| @dec[\"#{name}\"] ? @dec[\"#{name}\"].call(x) : x }", + " else", + " v = @dec[\"#{name}\"].call(v) if @dec[\"#{name}\"]", + " end", + " return v", + "end", + "def #{name}=(v)", + " if( @len[\"#{name}\"] )", + " v = v.collect{|x| @enc[\"#{name}\"] ? @enc[\"#{name}\"].call(x) : x }", + " else", + " v = @enc[\"#{name}\"].call(v) if @enc[\"#{name}\"]", + " end", + " @ptr[\"#{name}\"] = v", + " return v", + "end", + ].join("\n") + } + end + + def to_ptr + return @ptr + end + + def size + return @ptr.size + end + end + + class Struct + def initialize(types, contents) + @names = [] + @ty = {} + @len = {} + @enc = {} + @dec = {} + @size = 0 + @tys = "" + @types = types + parse(contents) + end + + def size + return @size + end + + def members + return @names + end + + # ptr must be a PtrData object. + def new(ptr) + ptr.struct!(@tys, *@names) + mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) + return mem + end + + def malloc(size = nil) + if( !size ) + size = @size + end + ptr = DL::malloc(size) + return new(ptr) + end + + def parse(contents) + contents.each{|elem| + name,ty,num,enc,dec = parse_elem(elem) + @names.push(name) + @ty[name] = ty + @len[name] = num + @enc[name] = enc + @dec[name] = dec + if( num ) + @tys += "#{ty}#{num}" + else + @tys += ty + end + } + @size = DL.sizeof(@tys) + end + + def parse_elem(elem) + elem.strip! + case elem + when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)$/ + ty = ($1 + $2).strip + name = $3 + num = nil; + when /^([\w\d_\*]+)([\*\s]+)([\w\d_]+)\[(\d+)\]$/ + ty = ($1 + $2).strip + name = $3 + num = $4.to_i + else + raise(RuntimeError, "invalid element: #{elem}") + end + ty,enc,dec = @types.encode_struct_type(ty) + if( !ty ) + raise(TypeError, "unsupported type: #{ty}") + end + return [name,ty,num,enc,dec] + end + end # class Struct + + class Union < Struct + def new + ptr = DL::malloc(@size) + ptr.union!(@tys, *@names) + mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec) + return mem + end + end + end # module Internal + end # module Importable +end # module DL diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/types.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/types.rb new file mode 100644 index 00000000..1144917d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/types.rb @@ -0,0 +1,245 @@ +# -*- ruby -*- + +require 'dl' + +module DL + class Types + TYPES = [ + # FORMAT: + # ["alias name", + # "type name", encoding_method, decoding_method, for function prototypes + # "type name", encoding_method, decoding_method] for structures (not implemented) + + # for Windows + ["DWORD", "unsigned long", nil, nil, + "unsigned long", nil, nil], + ["PDWORD", "unsigned long *", nil, nil, + "unsigned long *", nil, nil], + ["WORD", "unsigned short", nil, nil, + "unsigned short", nil, nil], + ["PWORD", "unsigned int *", nil, nil, + "unsigned int *", nil, nil], + ["BYTE", "unsigned char", nil, nil, + "unsigned char", nil, nil], + ["PBYTE", "unsigned char *", nil, nil, + "unsigned char *", nil, nil], + ["BOOL", "ibool", nil, nil, + "ibool", nil, nil], + ["ATOM", "int", nil, nil, + "int", nil, nil], + ["BYTE", "unsigned char", nil, nil, + "unsigned char", nil, nil], + ["PBYTE", "unsigned char *", nil, nil, + "unsigned char *", nil, nil], + ["UINT", "unsigned int", nil, nil, + "unsigned int", nil, nil], + ["ULONG", "unsigned long", nil, nil, + "unsigned long", nil, nil], + ["UCHAR", "unsigned char", nil, nil, + "unsigned char", nil, nil], + ["HANDLE", "unsigned long", nil, nil, + "unsigned long", nil, nil], + ["PHANDLE","void*", nil, nil, + "void*", nil, nil], + ["PVOID", "void*", nil, nil, + "void*", nil, nil], + ["LPCSTR", "char*", nil, nil, + "char*", nil, nil], + ["HDC", "unsigned int", nil, nil, + "unsigned int", nil, nil], + ["HWND", "unsigned int", nil, nil, + "unsigned int", nil, nil], + + # Others + ["uint", "unsigned int", nil, nil, + "unsigned int", nil, nil], + ["u_int", "unsigned int", nil, nil, + "unsigned int", nil, nil], + ["ulong", "unsigned long", nil, nil, + "unsigned long", nil, nil], + ["u_long", "unsigned long", nil, nil, + "unsigned long", nil, nil], + + # DL::Importable primitive types + ["ibool", + "I", + proc{|v| v ? 1 : 0}, + proc{|v| (v != 0) ? true : false}, + "I", + proc{|v| v ? 1 : 0 }, + proc{|v| (v != 0) ? true : false} ], + ["cbool", + "C", + proc{|v| v ? 1 : 0}, + proc{|v| (v != 0) ? true : false}, + "C", + proc{|v,len| v ? 1 : 0}, + proc{|v,len| (v != 0) ? true : false}], + ["lbool", + "L", + proc{|v| v ? 1 : 0}, + proc{|v| (v != 0) ? true : false}, + "L", + proc{|v,len| v ? 1 : 0}, + proc{|v,len| (v != 0) ? true : false}], + ["unsigned char", + "C", + proc{|v| [v].pack("C").unpack("c")[0]}, + proc{|v| [v].pack("c").unpack("C")[0]}, + "C", + proc{|v| [v].pack("C").unpack("c")[0]}, + proc{|v| [v].pack("c").unpack("C")[0]}], + ["unsigned short", + "H", + proc{|v| [v].pack("S").unpack("s")[0]}, + proc{|v| [v].pack("s").unpack("S")[0]}, + "H", + proc{|v| [v].pack("S").unpack("s")[0]}, + proc{|v| [v].pack("s").unpack("S")[0]}], + ["unsigned int", + "I", + proc{|v| [v].pack("I").unpack("i")[0]}, + proc{|v| [v].pack("i").unpack("I")[0]}, + "I", + proc{|v| [v].pack("I").unpack("i")[0]}, + proc{|v| [v].pack("i").unpack("I")[0]}], + ["unsigned long", + "L", + proc{|v| [v].pack("L").unpack("l")[0]}, + proc{|v| [v].pack("l").unpack("L")[0]}, + "L", + proc{|v| [v].pack("L").unpack("l")[0]}, + proc{|v| [v].pack("l").unpack("L")[0]}], + ["unsigned char ref", + "c", + proc{|v| [v].pack("C").unpack("c")[0]}, + proc{|v| [v].pack("c").unpack("C")[0]}, + nil, nil, nil], + ["unsigned int ref", + "i", + proc{|v| [v].pack("I").unpack("i")[0]}, + proc{|v| [v].pack("i").unpack("I")[0]}, + nil, nil, nil], + ["unsigned long ref", + "l", + proc{|v| [v].pack("L").unpack("l")[0]}, + proc{|v| [v].pack("l").unpack("L")[0]}, + nil, nil, nil], + ["char ref", "c", nil, nil, + nil, nil, nil], + ["short ref", "h", nil, nil, + nil, nil, nil], + ["int ref", "i", nil, nil, + nil, nil, nil], + ["long ref", "l", nil, nil, + nil, nil, nil], + ["float ref", "f", nil, nil, + nil, nil, nil], + ["double ref","d", nil, nil, + nil, nil, nil], + ["char", "C", nil, nil, + "C", nil, nil], + ["short", "H", nil, nil, + "H", nil, nil], + ["int", "I", nil, nil, + "I", nil, nil], + ["long", "L", nil, nil, + "L", nil, nil], + ["float", "F", nil, nil, + "F", nil, nil], + ["double", "D", nil, nil, + "D", nil, nil], + [/^char\s*\*$/,"s",nil, nil, + "S",nil, nil], + [/^const char\s*\*$/,"S",nil, nil, + "S",nil, nil], + [/^.+\*$/, "P", nil, nil, + "P", nil, nil], + [/^.+\[\]$/, "a", nil, nil, + "a", nil, nil], + ["void", "0", nil, nil, + nil, nil, nil], + ] + + def initialize + init_types() + end + + def typealias(ty1, ty2, enc=nil, dec=nil, ty3=nil, senc=nil, sdec=nil) + @TYDEFS.unshift([ty1, ty2, enc, dec, ty3, senc, sdec]) + end + + def init_types + @TYDEFS = TYPES.dup + end + + def encode_argument_type(alias_type) + proc_encode = nil + proc_decode = nil + @TYDEFS.each{|aty,ty,enc,dec,_,_,_| + if( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) ) + alias_type = alias_type.gsub(aty,ty) if ty + alias_type.strip! if alias_type + if( proc_encode ) + if( enc ) + conv1 = proc_encode + proc_encode = proc{|v| enc.call(conv1.call(v))} + end + else + if( enc ) + proc_encode = enc + end + end + if( proc_decode ) + if( dec ) + conv2 = proc_decode + proc_decode = proc{|v| dec.call(conv2.call(v))} + end + else + if( dec ) + proc_decode = dec + end + end + end + } + return [alias_type, proc_encode, proc_decode] + end + + def encode_return_type(ty) + ty, enc, dec = encode_argument_type(ty) + return [ty, enc, dec] + end + + def encode_struct_type(alias_type) + proc_encode = nil + proc_decode = nil + @TYDEFS.each{|aty,_,_,_,ty,enc,dec| + if( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) ) + alias_type = alias_type.gsub(aty,ty) if ty + alias_type.strip! if alias_type + if( proc_encode ) + if( enc ) + conv1 = proc_encode + proc_encode = proc{|v| enc.call(conv1.call(v))} + end + else + if( enc ) + proc_encode = enc + end + end + if( proc_decode ) + if( dec ) + conv2 = proc_decode + proc_decode = proc{|v| dec.call(conv2.call(v))} + end + else + if( dec ) + proc_decode = dec + end + end + end + } + return [alias_type, proc_encode, proc_decode] + end + end # end of Types +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/win32.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/win32.rb new file mode 100644 index 00000000..0fed47c3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/dl/win32.rb @@ -0,0 +1,25 @@ +# -*- ruby -*- + +require 'dl' + +class Win32API + DLL = {} + + def initialize(dllname, func, import, export = "0") + prototype = (export + import.to_s).tr("VPpNnLlIi", "0SSI").sub(/^(.)0*$/, '\1') + handle = DLL[dllname] ||= DL::Handle.new(dllname) + @sym = handle.sym(func, prototype) + end + + def call(*args) + import = @sym.proto.split("", 2)[1] + args.each_with_index do |x, i| + args[i] = nil if x == 0 and import[i] == ?S + args[i], = [x].pack("I").unpack("i") if import[i] == ?I + end + ret, = @sym.call(*args) + return ret || 0 + end + + alias Call call +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb.rb new file mode 100644 index 00000000..93cc811e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb.rb @@ -0,0 +1,2 @@ +require 'drb/drb' + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/acl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/acl.rb new file mode 100644 index 00000000..861c8a51 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/acl.rb @@ -0,0 +1,146 @@ +# acl-2.0 - simple Access Control List +# +# Copyright (c) 2000,2002,2003 Masatoshi SEKI +# +# acl.rb is copyrighted free software by Masatoshi SEKI. +# You can redistribute it and/or modify it under the same terms as Ruby. + +require 'ipaddr' + +class ACL + VERSION=["2.0.0"] + class ACLEntry + def initialize(str) + if str == '*' or str == 'all' + @pat = [:all] + elsif str.include?('*') + @pat = [:name, dot_pat(str)] + else + begin + @pat = [:ip, IPAddr.new(str)] + rescue ArgumentError + @pat = [:name, dot_pat(str)] + end + end + end + + private + def dot_pat_str(str) + list = str.split('.').collect { |s| + (s == '*') ? '.+' : s + } + list.join("\\.") + end + + private + def dot_pat(str) + exp = "^" + dot_pat_str(str) + "$" + Regexp.new(exp) + end + + public + def match(addr) + case @pat[0] + when :all + true + when :ip + begin + ipaddr = IPAddr.new(addr[3]) + ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4? + rescue ArgumentError + return false + end + (@pat[1].include?(ipaddr)) ? true : false + when :name + (@pat[1] =~ addr[2]) ? true : false + else + false + end + end + end + + class ACLList + def initialize + @list = [] + end + + public + def match(addr) + @list.each do |e| + return true if e.match(addr) + end + false + end + + public + def add(str) + @list.push(ACLEntry.new(str)) + end + end + + DENY_ALLOW = 0 + ALLOW_DENY = 1 + + def initialize(list=nil, order = DENY_ALLOW) + @order = order + @deny = ACLList.new + @allow = ACLList.new + install_list(list) if list + end + + public + def allow_socket?(soc) + allow_addr?(soc.peeraddr) + end + + public + def allow_addr?(addr) + case @order + when DENY_ALLOW + return true if @allow.match(addr) + return false if @deny.match(addr) + return true + when ALLOW_DENY + return false if @deny.match(addr) + return true if @allow.match(addr) + return false + else + false + end + end + + public + def install_list(list) + i = 0 + while i < list.size + permission, domain = list.slice(i,2) + case permission.downcase + when 'allow' + @allow.add(domain) + when 'deny' + @deny.add(domain) + else + raise "Invalid ACL entry #{list.to_s}" + end + i += 2 + end + end +end + +if __FILE__ == $0 + # example + list = %w(deny all + allow 192.168.1.1 + allow ::ffff:192.168.1.2 + allow 192.168.1.3 + ) + + addr = ["AF_INET", 10, "lc630", "192.168.1.3"] + + acl = ACL.new + p acl.allow_addr?(addr) + + acl = ACL.new(list, ACL::DENY_ALLOW) + p acl.allow_addr?(addr) +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/drb.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/drb.rb new file mode 100644 index 00000000..25fbb3f7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/drb.rb @@ -0,0 +1,1763 @@ +# +# = drb/drb.rb +# +# Distributed Ruby: _dRuby_ version 2.0.4 +# +# Copyright (c) 1999-2003 Masatoshi SEKI. You can redistribute it and/or +# modify it under the same terms as Ruby. +# +# Author:: Masatoshi SEKI +# +# Documentation:: William Webber (william@williamwebber.com) +# +# == Overview +# +# dRuby is a distributed object system for Ruby. It allows an object in one +# Ruby process to invoke methods on an object in another Ruby process on the +# same or a different machine. +# +# The Ruby standard library contains the core classes of the dRuby package. +# However, the full package also includes access control lists and the +# Rinda tuple-space distributed task management system, as well as a +# large number of samples. The full dRuby package can be downloaded from +# the dRuby home page (see *References*). +# +# For an introduction and examples of usage see the documentation to the +# DRb module. +# +# == References +# +# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.html] +# The dRuby home page, in Japanese. Contains the full dRuby package +# and links to other Japanese-language sources. +# +# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.en.html] +# The English version of the dRuby home page. +# +# [http://www.chadfowler.com/ruby/drb.html] +# A quick tutorial introduction to using dRuby by Chad Fowler. +# +# [http://www.linux-mag.com/2002-09/ruby_05.html] +# A tutorial introduction to dRuby in Linux Magazine by Dave Thomas. +# Includes a discussion of Rinda. +# +# [http://www.eng.cse.dmu.ac.uk/~hgs/ruby/dRuby/] +# Links to English-language Ruby material collected by Hugh Sasse. +# +# [http://www.rubycentral.com/book/ospace.html] +# The chapter from *Programming* *Ruby* by Dave Thomas and Andy Hunt +# which discusses dRuby. +# +# [http://www.clio.ne.jp/home/web-i31s/Flotuard/Ruby/PRC2K_seki/dRuby.en.html] +# Translation of presentation on Ruby by Masatoshi Seki. + +require 'socket' +require 'thread' +require 'fcntl' +require 'drb/eq' + +# +# == Overview +# +# dRuby is a distributed object system for Ruby. It is written in +# pure Ruby and uses its own protocol. No add-in services are needed +# beyond those provided by the Ruby runtime, such as TCP sockets. It +# does not rely on or interoperate with other distributed object +# systems such as CORBA, RMI, or .NET. +# +# dRuby allows methods to be called in one Ruby process upon a Ruby +# object located in another Ruby process, even on another machine. +# References to objects can be passed between processes. Method +# arguments and return values are dumped and loaded in marshalled +# format. All of this is done transparently to both the caller of the +# remote method and the object that it is called upon. +# +# An object in a remote process is locally represented by a +# DRb::DRbObject instance. This acts as a sort of proxy for the +# remote object. Methods called upon this DRbObject instance are +# forwarded to its remote object. This is arranged dynamically at run +# time. There are no statically declared interfaces for remote +# objects, such as CORBA's IDL. +# +# dRuby calls made into a process are handled by a DRb::DRbServer +# instance within that process. This reconstitutes the method call, +# invokes it upon the specified local object, and returns the value to +# the remote caller. Any object can receive calls over dRuby. There +# is no need to implement a special interface, or mixin special +# functionality. Nor, in the general case, does an object need to +# explicitly register itself with a DRbServer in order to receive +# dRuby calls. +# +# One process wishing to make dRuby calls upon another process must +# somehow obtain an initial reference to an object in the remote +# process by some means other than as the return value of a remote +# method call, as there is initially no remote object reference it can +# invoke a method upon. This is done by attaching to the server by +# URI. Each DRbServer binds itself to a URI such as +# 'druby://example.com:8787'. A DRbServer can have an object attached +# to it that acts as the server's *front* *object*. A DRbObject can +# be explicitly created from the server's URI. This DRbObject's +# remote object will be the server's front object. This front object +# can then return references to other Ruby objects in the DRbServer's +# process. +# +# Method calls made over dRuby behave largely the same as normal Ruby +# method calls made within a process. Method calls with blocks are +# supported, as are raising exceptions. In addition to a method's +# standard errors, a dRuby call may also raise one of the +# dRuby-specific errors, all of which are subclasses of DRb::DRbError. +# +# Any type of object can be passed as an argument to a dRuby call or +# returned as its return value. By default, such objects are dumped +# or marshalled at the local end, then loaded or unmarshalled at the +# remote end. The remote end therefore receives a copy of the local +# object, not a distributed reference to it; methods invoked upon this +# copy are executed entirely in the remote process, not passed on to +# the local original. This has semantics similar to pass-by-value. +# +# However, if an object cannot be marshalled, a dRuby reference to it +# is passed or returned instead. This will turn up at the remote end +# as a DRbObject instance. All methods invoked upon this remote proxy +# are forwarded to the local object, as described in the discussion of +# DRbObjects. This has semantics similar to the normal Ruby +# pass-by-reference. +# +# The easiest way to signal that we want an otherwise marshallable +# object to be passed or returned as a DRbObject reference, rather +# than marshalled and sent as a copy, is to include the +# DRb::DRbUndumped mixin module. +# +# dRuby supports calling remote methods with blocks. As blocks (or +# rather the Proc objects that represent them) are not marshallable, +# the block executes in the local, not the remote, context. Each +# value yielded to the block is passed from the remote object to the +# local block, then the value returned by each block invocation is +# passed back to the remote execution context to be collected, before +# the collected values are finally returned to the local context as +# the return value of the method invocation. +# +# == Examples of usage +# +# For more dRuby samples, see the +samples+ directory in the full +# dRuby distribution. +# +# === dRuby in client/server mode +# +# This illustrates setting up a simple client-server drb +# system. Run the server and client code in different terminals, +# starting the server code first. +# +# ==== Server code +# +# require 'drb/drb' +# +# # The URI for the server to connect to +# URI="druby://localhost:8787" +# +# class TimeServer +# +# def get_current_time +# return Time.now +# end +# +# end +# +# # The object that handles requests on the server +# FRONT_OBJECT=TimeServer.new +# +# $SAFE = 1 # disable eval() and friends +# +# DRb.start_service(URI, FRONT_OBJECT) +# # Wait for the drb server thread to finish before exiting. +# DRb.thread.join +# +# ==== Client code +# +# require 'drb/drb' +# +# # The URI to connect to +# SERVER_URI="druby://localhost:8787" +# +# # Start a local DRbServer to handle callbacks. +# # +# # Not necessary for this small example, but will be required +# # as soon as we pass a non-marshallable object as an argument +# # to a dRuby call. +# DRb.start_service +# +# timeserver = DRbObject.new_with_uri(SERVER_URI) +# puts timeserver.get_current_time +# +# === Remote objects under dRuby +# +# This example illustrates returning a reference to an object +# from a dRuby call. The Logger instances live in the server +# process. References to them are returned to the client process, +# where methods can be invoked upon them. These methods are +# executed in the server process. +# +# ==== Server code +# +# require 'drb/drb' +# +# URI="druby://localhost:8787" +# +# class Logger +# +# # Make dRuby send Logger instances as dRuby references, +# # not copies. +# include DRb::DRbUndumped +# +# def initialize(n, fname) +# @name = n +# @filename = fname +# end +# +# def log(message) +# File.open(@filename, "a") do |f| +# f.puts("#{Time.now}: #{@name}: #{message}") +# end +# end +# +# end +# +# # We have a central object for creating and retrieving loggers. +# # This retains a local reference to all loggers created. This +# # is so an existing logger can be looked up by name, but also +# # to prevent loggers from being garbage collected. A dRuby +# # reference to an object is not sufficient to prevent it being +# # garbage collected! +# class LoggerFactory +# +# def initialize(bdir) +# @basedir = bdir +# @loggers = {} +# end +# +# def get_logger(name) +# if !@loggers.has_key? name +# # make the filename safe, then declare it to be so +# fname = name.gsub(/[.\/]/, "_").untaint +# @loggers[name] = Logger.new(name, @basedir + "/" + fname) +# end +# return @loggers[name] +# end +# +# end +# +# FRONT_OBJECT=LoggerFactory.new("/tmp/dlog") +# +# $SAFE = 1 # disable eval() and friends +# +# DRb.start_service(URI, FRONT_OBJECT) +# DRb.thread.join +# +# ==== Client code +# +# require 'drb/drb' +# +# SERVER_URI="druby://localhost:8787" +# +# DRb.start_service +# +# log_service=DRbObject.new_with_uri(SERVER_URI) +# +# ["loga", "logb", "logc"].each do |logname| +# +# logger=log_service.get_logger(logname) +# +# logger.log("Hello, world!") +# logger.log("Goodbye, world!") +# logger.log("=== EOT ===") +# +# end +# +# == Security +# +# As with all network services, security needs to be considered when +# using dRuby. By allowing external access to a Ruby object, you are +# not only allowing outside clients to call the methods you have +# defined for that object, but by default to execute arbitrary Ruby +# code on your server. Consider the following: +# +# # !!! UNSAFE CODE !!! +# ro = DRbObject::new_with_uri("druby://your.server.com:8989") +# class << ro +# undef :instance_eval # force call to be passed to remote object +# end +# ro.instance_eval("`rm -rf *`") +# +# The dangers posed by instance_eval and friends are such that a +# DRbServer should generally be run with $SAFE set to at least +# level 1. This will disable eval() and related calls on strings +# passed across the wire. The sample usage code given above follows +# this practice. +# +# A DRbServer can be configured with an access control list to +# selectively allow or deny access from specified IP addresses. The +# main druby distribution provides the ACL class for this purpose. In +# general, this mechanism should only be used alongside, rather than +# as a replacement for, a good firewall. +# +# == dRuby internals +# +# dRuby is implemented using three main components: a remote method +# call marshaller/unmarshaller; a transport protocol; and an +# ID-to-object mapper. The latter two can be directly, and the first +# indirectly, replaced, in order to provide different behaviour and +# capabilities. +# +# Marshalling and unmarshalling of remote method calls is performed by +# a DRb::DRbMessage instance. This uses the Marshal module to dump +# the method call before sending it over the transport layer, then +# reconstitute it at the other end. There is normally no need to +# replace this component, and no direct way is provided to do so. +# However, it is possible to implement an alternative marshalling +# scheme as part of an implementation of the transport layer. +# +# The transport layer is responsible for opening client and server +# network connections and forwarding dRuby request across them. +# Normally, it uses DRb::DRbMessage internally to manage marshalling +# and unmarshalling. The transport layer is managed by +# DRb::DRbProtocol. Multiple protocols can be installed in +# DRbProtocol at the one time; selection between them is determined by +# the scheme of a dRuby URI. The default transport protocol is +# selected by the scheme 'druby:', and implemented by +# DRb::DRbTCPSocket. This uses plain TCP/IP sockets for +# communication. An alternative protocol, using UNIX domain sockets, +# is implemented by DRb::DRbUNIXSocket in the file drb/unix.rb, and +# selected by the scheme 'drbunix:'. A sample implementation over +# HTTP can be found in the samples accompanying the main dRuby +# distribution. +# +# The ID-to-object mapping component maps dRuby object ids to the +# objects they refer to, and vice versa. The implementation to use +# can be specified as part of a DRb::DRbServer's configuration. The +# default implementation is provided by DRb::DRbIdConv. It uses an +# object's ObjectSpace id as its dRuby id. This means that the dRuby +# reference to that object only remains meaningful for the lifetime of +# the object's process and the lifetime of the object within that +# process. A modified implementation is provided by DRb::TimerIdConv +# in the file drb/timeridconv.rb. This implementation retains a local +# reference to all objects exported over dRuby for a configurable +# period of time (defaulting to ten minutes), to prevent them being +# garbage-collected within this time. Another sample implementation +# is provided in sample/name.rb in the main dRuby distribution. This +# allows objects to specify their own id or "name". A dRuby reference +# can be made persistent across processes by having each process +# register an object using the same dRuby name. +# +module DRb + + # Superclass of all errors raised in the DRb module. + class DRbError < RuntimeError; end + + # Error raised when an error occurs on the underlying communication + # protocol. + class DRbConnError < DRbError; end + + # Class responsible for converting between an object and its id. + # + # This, the default implementation, uses an object's local ObjectSpace + # __id__ as its id. This means that an object's identification over + # drb remains valid only while that object instance remains alive + # within the server runtime. + # + # For alternative mechanisms, see DRb::TimerIdConv in rdb/timeridconv.rb + # and DRbNameIdConv in sample/name.rb in the full drb distribution. + class DRbIdConv + + # Convert an object reference id to an object. + # + # This implementation looks up the reference id in the local object + # space and returns the object it refers to. + def to_obj(ref) + ObjectSpace._id2ref(ref) + end + + # Convert an object into a reference id. + # + # This implementation returns the object's __id__ in the local + # object space. + def to_id(obj) + obj.nil? ? nil : obj.__id__ + end + end + + # Mixin module making an object undumpable or unmarshallable. + # + # If an object which includes this module is returned by method + # called over drb, then the object remains in the server space + # and a reference to the object is returned, rather than the + # object being marshalled and moved into the client space. + module DRbUndumped + def _dump(dummy) # :nodoc: + raise TypeError, 'can\'t dump' + end + end + + # Error raised by the DRb module when an attempt is made to refer to + # the context's current drb server but the context does not have one. + # See #current_server. + class DRbServerNotFound < DRbError; end + + # Error raised by the DRbProtocol module when it cannot find any + # protocol implementation support the scheme specified in a URI. + class DRbBadURI < DRbError; end + + # Error raised by a dRuby protocol when it doesn't support the + # scheme specified in a URI. See DRb::DRbProtocol. + class DRbBadScheme < DRbError; end + + # An exception wrapping a DRb::DRbUnknown object + class DRbUnknownError < DRbError + + # Create a new DRbUnknownError for the DRb::DRbUnknown object +unknown+ + def initialize(unknown) + @unknown = unknown + super(unknown.name) + end + + # Get the wrapped DRb::DRbUnknown object. + attr_reader :unknown + + def self._load(s) # :nodoc: + Marshal::load(s) + end + + def _dump(lv) # :nodoc: + Marshal::dump(@unknown) + end + end + + # An exception wrapping an error object + class DRbRemoteError < DRbError + def initialize(error) + @reason = error.class.to_s + super("#{error.message} (#{error.class})") + set_backtrace(error.backtrace) + end + + # the class of the error, as a string. + attr_reader :reason + end + + # Class wrapping a marshalled object whose type is unknown locally. + # + # If an object is returned by a method invoked over drb, but the + # class of the object is unknown in the client namespace, or + # the object is a constant unknown in the client namespace, then + # the still-marshalled object is returned wrapped in a DRbUnknown instance. + # + # If this object is passed as an argument to a method invoked over + # drb, then the wrapped object is passed instead. + # + # The class or constant name of the object can be read from the + # +name+ attribute. The marshalled object is held in the +buf+ + # attribute. + class DRbUnknown + + # Create a new DRbUnknown object. + # + # +buf+ is a string containing a marshalled object that could not + # be unmarshalled. +err+ is the error message that was raised + # when the unmarshalling failed. It is used to determine the + # name of the unmarshalled object. + def initialize(err, buf) + case err.to_s + when /uninitialized constant (\S+)/ + @name = $1 + when /undefined class\/module (\S+)/ + @name = $1 + else + @name = nil + end + @buf = buf + end + + # The name of the unknown thing. + # + # Class name for unknown objects; variable name for unknown + # constants. + attr_reader :name + + # Buffer contained the marshalled, unknown object. + attr_reader :buf + + def self._load(s) # :nodoc: + begin + Marshal::load(s) + rescue NameError, ArgumentError + DRbUnknown.new($!, s) + end + end + + def _dump(lv) # :nodoc: + @buf + end + + # Attempt to load the wrapped marshalled object again. + # + # If the class of the object is now known locally, the object + # will be unmarshalled and returned. Otherwise, a new + # but identical DRbUnknown object will be returned. + def reload + self.class._load(@buf) + end + + # Create a DRbUnknownError exception containing this object. + def exception + DRbUnknownError.new(self) + end + end + + class DRbArray + def initialize(ary) + @ary = ary.collect { |obj| + if obj.kind_of? DRbUndumped + DRbObject.new(obj) + else + begin + Marshal.dump(obj) + obj + rescue + DRbObject.new(obj) + end + end + } + end + + def self._load(s) + Marshal::load(s) + end + + def _dump(lv) + Marshal.dump(@ary) + end + end + + # Handler for sending and receiving drb messages. + # + # This takes care of the low-level marshalling and unmarshalling + # of drb requests and responses sent over the wire between server + # and client. This relieves the implementor of a new drb + # protocol layer with having to deal with these details. + # + # The user does not have to directly deal with this object in + # normal use. + class DRbMessage + def initialize(config) # :nodoc: + @load_limit = config[:load_limit] + @argc_limit = config[:argc_limit] + end + + def dump(obj, error=false) # :nodoc: + obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped + begin + str = Marshal::dump(obj) + rescue + str = Marshal::dump(make_proxy(obj, error)) + end + [str.size].pack('N') + str + end + + def load(soc) # :nodoc: + begin + sz = soc.read(4) # sizeof (N) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + raise(DRbConnError, 'connection closed') if sz.nil? + raise(DRbConnError, 'premature header') if sz.size < 4 + sz = sz.unpack('N')[0] + raise(DRbConnError, "too large packet #{sz}") if @load_limit < sz + begin + str = soc.read(sz) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + raise(DRbConnError, 'connection closed') if str.nil? + raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz + Thread.exclusive do + begin + save = Thread.current[:drb_untaint] + Thread.current[:drb_untaint] = [] + Marshal::load(str) + rescue NameError, ArgumentError + DRbUnknown.new($!, str) + ensure + Thread.current[:drb_untaint].each do |x| + x.untaint + end + Thread.current[:drb_untaint] = save + end + end + end + + def send_request(stream, ref, msg_id, arg, b) # :nodoc: + ary = [] + ary.push(dump(ref.__drbref)) + ary.push(dump(msg_id.id2name)) + ary.push(dump(arg.length)) + arg.each do |e| + ary.push(dump(e)) + end + ary.push(dump(b)) + stream.write(ary.join('')) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + + def recv_request(stream) # :nodoc: + ref = load(stream) + ro = DRb.to_obj(ref) + msg = load(stream) + argc = load(stream) + raise ArgumentError, 'too many arguments' if @argc_limit < argc + argv = Array.new(argc, nil) + argc.times do |n| + argv[n] = load(stream) + end + block = load(stream) + return ro, msg, argv, block + end + + def send_reply(stream, succ, result) # :nodoc: + stream.write(dump(succ) + dump(result, !succ)) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + + def recv_reply(stream) # :nodoc: + succ = load(stream) + result = load(stream) + [succ, result] + end + + private + def make_proxy(obj, error=false) + if error + DRbRemoteError.new(obj) + else + DRbObject.new(obj) + end + end + end + + # Module managing the underlying network protocol(s) used by drb. + # + # By default, drb uses the DRbTCPSocket protocol. Other protocols + # can be defined. A protocol must define the following class methods: + # + # [open(uri, config)] Open a client connection to the server at +uri+, + # using configuration +config+. Return a protocol + # instance for this connection. + # [open_server(uri, config)] Open a server listening at +uri+, + # using configuration +config+. Return a + # protocol instance for this listener. + # [uri_option(uri, config)] Take a URI, possibly containing an option + # component (e.g. a trailing '?param=val'), + # and return a [uri, option] tuple. + # + # All of these methods should raise a DRbBadScheme error if the URI + # does not identify the protocol they support (e.g. "druby:" for + # the standard Ruby protocol). This is how the DRbProtocol module, + # given a URI, determines which protocol implementation serves that + # protocol. + # + # The protocol instance returned by #open_server must have the + # following methods: + # + # [accept] Accept a new connection to the server. Returns a protocol + # instance capable of communicating with the client. + # [close] Close the server connection. + # [uri] Get the URI for this server. + # + # The protocol instance returned by #open must have the following methods: + # + # [send_request (ref, msg_id, arg, b)] + # Send a request to +ref+ with the given message id and arguments. + # This is most easily implemented by calling DRbMessage.send_request, + # providing a stream that sits on top of the current protocol. + # [recv_reply] + # Receive a reply from the server and return it as a [success-boolean, + # reply-value] pair. This is most easily implemented by calling + # DRb.recv_reply, providing a stream that sits on top of the + # current protocol. + # [alive?] + # Is this connection still alive? + # [close] + # Close this connection. + # + # The protocol instance returned by #open_server().accept() must have + # the following methods: + # + # [recv_request] + # Receive a request from the client and return a [object, message, + # args, block] tuple. This is most easily implemented by calling + # DRbMessage.recv_request, providing a stream that sits on top of + # the current protocol. + # [send_reply(succ, result)] + # Send a reply to the client. This is most easily implemented + # by calling DRbMessage.send_reply, providing a stream that sits + # on top of the current protocol. + # [close] + # Close this connection. + # + # A new protocol is registered with the DRbProtocol module using + # the add_protocol method. + # + # For examples of other protocols, see DRbUNIXSocket in drb/unix.rb, + # and HTTP0 in sample/http0.rb and sample/http0serv.rb in the full + # drb distribution. + module DRbProtocol + + # Add a new protocol to the DRbProtocol module. + def add_protocol(prot) + @protocol.push(prot) + end + module_function :add_protocol + + # Open a client connection to +uri+ with the configuration +config+. + # + # The DRbProtocol module asks each registered protocol in turn to + # try to open the URI. Each protocol signals that it does not handle that + # URI by raising a DRbBadScheme error. If no protocol recognises the + # URI, then a DRbBadURI error is raised. If a protocol accepts the + # URI, but an error occurs in opening it, a DRbConnError is raised. + def open(uri, config, first=true) + @protocol.each do |prot| + begin + return prot.open(uri, config) + rescue DRbBadScheme + rescue DRbConnError + raise($!) + rescue + raise(DRbConnError, "#{uri} - #{$!.inspect}") + end + end + if first && (config[:auto_load] != false) + auto_load(uri, config) + return open(uri, config, false) + end + raise DRbBadURI, 'can\'t parse uri:' + uri + end + module_function :open + + # Open a server listening for connections at +uri+ with + # configuration +config+. + # + # The DRbProtocol module asks each registered protocol in turn to + # try to open a server at the URI. Each protocol signals that it does + # not handle that URI by raising a DRbBadScheme error. If no protocol + # recognises the URI, then a DRbBadURI error is raised. If a protocol + # accepts the URI, but an error occurs in opening it, the underlying + # error is passed on to the caller. + def open_server(uri, config, first=true) + @protocol.each do |prot| + begin + return prot.open_server(uri, config) + rescue DRbBadScheme + end + end + if first && (config[:auto_load] != false) + auto_load(uri, config) + return open_server(uri, config, false) + end + raise DRbBadURI, 'can\'t parse uri:' + uri + end + module_function :open_server + + # Parse +uri+ into a [uri, option] pair. + # + # The DRbProtocol module asks each registered protocol in turn to + # try to parse the URI. Each protocol signals that it does not handle that + # URI by raising a DRbBadScheme error. If no protocol recognises the + # URI, then a DRbBadURI error is raised. + def uri_option(uri, config, first=true) + @protocol.each do |prot| + begin + uri, opt = prot.uri_option(uri, config) + # opt = nil if opt == '' + return uri, opt + rescue DRbBadScheme + end + end + if first && (config[:auto_load] != false) + auto_load(uri, config) + return uri_option(uri, config, false) + end + raise DRbBadURI, 'can\'t parse uri:' + uri + end + module_function :uri_option + + def auto_load(uri, config) # :nodoc: + if uri =~ /^drb([a-z0-9]+):/ + require("drb/#{$1}") rescue nil + end + end + module_function :auto_load + end + + # The default drb protocol. + # + # Communicates over a TCP socket. + class DRbTCPSocket + private + def self.parse_uri(uri) + if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/ + host = $1 + port = $2.to_i + option = $4 + [host, port, option] + else + raise(DRbBadScheme, uri) unless uri =~ /^druby:/ + raise(DRbBadURI, 'can\'t parse uri:' + uri) + end + end + + public + + # Open a client connection to +uri+ using configuration +config+. + def self.open(uri, config) + host, port, option = parse_uri(uri) + host.untaint + port.untaint + soc = TCPSocket.open(host, port) + self.new(uri, soc, config) + end + + def self.getservername + host = Socket::gethostname + begin + Socket::gethostbyname(host)[0] + rescue + 'localhost' + end + end + + def self.open_server_inaddr_any(host, port) + infos = Socket::getaddrinfo(host, nil, + Socket::AF_UNSPEC, + Socket::SOCK_STREAM, + 0, + Socket::AI_PASSIVE) + family = infos.collect { |af, *_| af }.uniq + case family + when ['AF_INET'] + return TCPServer.open('0.0.0.0', port) + when ['AF_INET6'] + return TCPServer.open('::', port) + else + return TCPServer.open(port) + end + end + + # Open a server listening for connections at +uri+ using + # configuration +config+. + def self.open_server(uri, config) + uri = 'druby://:0' unless uri + host, port, opt = parse_uri(uri) + if host.size == 0 + host = getservername + soc = open_server_inaddr_any(host, port) + else + soc = TCPServer.open(host, port) + end + port = soc.addr[1] if port == 0 + uri = "druby://#{host}:#{port}" + self.new(uri, soc, config) + end + + # Parse +uri+ into a [uri, option] pair. + def self.uri_option(uri, config) + host, port, option = parse_uri(uri) + return "druby://#{host}:#{port}", option + end + + # Create a new DRbTCPSocket instance. + # + # +uri+ is the URI we are connected to. + # +soc+ is the tcp socket we are bound to. +config+ is our + # configuration. + def initialize(uri, soc, config={}) + @uri = uri + @socket = soc + @config = config + @acl = config[:tcp_acl] + @msg = DRbMessage.new(config) + set_sockopt(@socket) + end + + # Get the URI that we are connected to. + attr_reader :uri + + # Get the address of our TCP peer (the other end of the socket + # we are bound to. + def peeraddr + @socket.peeraddr + end + + # Get the socket. + def stream; @socket; end + + # On the client side, send a request to the server. + def send_request(ref, msg_id, arg, b) + @msg.send_request(stream, ref, msg_id, arg, b) + end + + # On the server side, receive a request from the client. + def recv_request + @msg.recv_request(stream) + end + + # On the server side, send a reply to the client. + def send_reply(succ, result) + @msg.send_reply(stream, succ, result) + end + + # On the client side, receive a reply from the server. + def recv_reply + @msg.recv_reply(stream) + end + + public + + # Close the connection. + # + # If this is an instance returned by #open_server, then this stops + # listening for new connections altogether. If this is an instance + # returned by #open or by #accept, then it closes this particular + # client-server session. + def close + if @socket + @socket.close + @socket = nil + end + end + + # On the server side, for an instance returned by #open_server, + # accept a client connection and return a new instance to handle + # the server's side of this client-server session. + def accept + while true + s = @socket.accept + break if (@acl ? @acl.allow_socket?(s) : true) + s.close + end + self.class.new(nil, s, @config) + end + + # Check to see if this connection is alive. + def alive? + return false unless @socket + if IO.select([@socket], nil, nil, 0) + close + return false + end + true + end + + def set_sockopt(soc) # :nodoc: + soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC + end + end + + module DRbProtocol + @protocol = [DRbTCPSocket] # default + end + + class DRbURIOption # :nodoc: I don't understand the purpose of this class... + def initialize(option) + @option = option.to_s + end + attr :option + def to_s; @option; end + + def ==(other) + return false unless DRbURIOption === other + @option == other.option + end + + def hash + @option.hash + end + + alias eql? == + end + + # Object wrapping a reference to a remote drb object. + # + # Method calls on this object are relayed to the remote + # object that this object is a stub for. + class DRbObject + + # Unmarshall a marshalled DRbObject. + # + # If the referenced object is located within the local server, then + # the object itself is returned. Otherwise, a new DRbObject is + # created to act as a stub for the remote referenced object. + def self._load(s) + uri, ref = Marshal.load(s) + + if DRb.here?(uri) + obj = DRb.to_obj(ref) + if ((! obj.tainted?) && Thread.current[:drb_untaint]) + Thread.current[:drb_untaint].push(obj) + end + return obj + end + + self.new_with(uri, ref) + end + + def self.new_with(uri, ref) + it = self.allocate + it.instance_variable_set('@uri', uri) + it.instance_variable_set('@ref', ref) + it + end + + # Create a new DRbObject from a URI alone. + def self.new_with_uri(uri) + self.new(nil, uri) + end + + # Marshall this object. + # + # The URI and ref of the object are marshalled. + def _dump(lv) + Marshal.dump([@uri, @ref]) + end + + # Create a new remote object stub. + # + # +obj+ is the (local) object we want to create a stub for. Normally + # this is +nil+. +uri+ is the URI of the remote object that this + # will be a stub for. + def initialize(obj, uri=nil) + @uri = nil + @ref = nil + if obj.nil? + return if uri.nil? + @uri, option = DRbProtocol.uri_option(uri, DRb.config) + @ref = DRbURIOption.new(option) unless option.nil? + else + @uri = uri ? uri : (DRb.uri rescue nil) + @ref = obj ? DRb.to_id(obj) : nil + end + end + + # Get the URI of the remote object. + def __drburi + @uri + end + + # Get the reference of the object, if local. + def __drbref + @ref + end + + undef :to_s + undef :to_a if respond_to?(:to_a) + + def respond_to?(msg_id, priv=false) + case msg_id + when :_dump + true + when :marshal_dump + false + else + method_missing(:respond_to?, msg_id, priv) + end + end + + # Routes method calls to the referenced object. + def method_missing(msg_id, *a, &b) + if DRb.here?(@uri) + obj = DRb.to_obj(@ref) + DRb.current_server.check_insecure_method(obj, msg_id) + return obj.__send__(msg_id, *a, &b) + end + + succ, result = self.class.with_friend(@uri) do + DRbConn.open(@uri) do |conn| + conn.send_message(self, msg_id, a, b) + end + end + + if succ + return result + elsif DRbUnknown === result + raise result + else + bt = self.class.prepare_backtrace(@uri, result) + result.set_backtrace(bt + caller) + raise result + end + end + + def self.with_friend(uri) + friend = DRb.fetch_server(uri) + return yield() unless friend + + save = Thread.current['DRb'] + Thread.current['DRb'] = { 'server' => friend } + return yield + ensure + Thread.current['DRb'] = save if friend + end + + def self.prepare_backtrace(uri, result) + prefix = "(#{uri}) " + bt = [] + result.backtrace.each do |x| + break if /`__send__'$/ =~ x + if /^\(druby:\/\// =~ x + bt.push(x) + else + bt.push(prefix + x) + end + end + bt + end + + def pretty_print(q) # :nodoc: + q.pp_object(self) + end + + def pretty_print_cycle(q) # :nodoc: + q.object_address_group(self) { + q.breakable + q.text '...' + } + end + end + + # Class handling the connection between a DRbObject and the + # server the real object lives on. + # + # This class maintains a pool of connections, to reduce the + # overhead of starting and closing down connections for each + # method call. + # + # This class is used internally by DRbObject. The user does + # not normally need to deal with it directly. + class DRbConn + POOL_SIZE = 16 # :nodoc: + @mutex = Mutex.new + @pool = [] + + def self.open(remote_uri) # :nodoc: + begin + conn = nil + + @mutex.synchronize do + #FIXME + new_pool = [] + @pool.each do |c| + if conn.nil? and c.uri == remote_uri + conn = c if c.alive? + else + new_pool.push c + end + end + @pool = new_pool + end + + conn = self.new(remote_uri) unless conn + succ, result = yield(conn) + return succ, result + + ensure + if conn + if succ + @mutex.synchronize do + @pool.unshift(conn) + @pool.pop.close while @pool.size > POOL_SIZE + end + else + conn.close + end + end + end + end + + def initialize(remote_uri) # :nodoc: + @uri = remote_uri + @protocol = DRbProtocol.open(remote_uri, DRb.config) + end + attr_reader :uri # :nodoc: + + def send_message(ref, msg_id, arg, block) # :nodoc: + @protocol.send_request(ref, msg_id, arg, block) + @protocol.recv_reply + end + + def close # :nodoc: + @protocol.close + @protocol = nil + end + + def alive? # :nodoc: + @protocol.alive? + end + end + + # Class representing a drb server instance. + # + # A DRbServer must be running in the local process before any incoming + # dRuby calls can be accepted, or any local objects can be passed as + # dRuby references to remote processes, even if those local objects are + # never actually called remotely. You do not need to start a DRbServer + # in the local process if you are only making outgoing dRuby calls + # passing marshalled parameters. + # + # Unless multiple servers are being used, the local DRbServer is normally + # started by calling DRb.start_service. + class DRbServer + @@acl = nil + @@idconv = DRbIdConv.new + @@secondary_server = nil + @@argc_limit = 256 + @@load_limit = 256 * 102400 + @@verbose = false + @@safe_level = 0 + + # Set the default value for the :argc_limit option. + # + # See #new(). The initial default value is 256. + def self.default_argc_limit(argc) + @@argc_limit = argc + end + + # Set the default value for the :load_limit option. + # + # See #new(). The initial default value is 25 MB. + def self.default_load_limit(sz) + @@load_limit = sz + end + + # Set the default value for the :acl option. + # + # See #new(). The initial default value is nil. + def self.default_acl(acl) + @@acl = acl + end + + # Set the default value for the :id_conv option. + # + # See #new(). The initial default value is a DRbIdConv instance. + def self.default_id_conv(idconv) + @@idconv = idconv + end + + def self.default_safe_level(level) + @@safe_level = level + end + + # Set the default value of the :verbose option. + # + # See #new(). The initial default value is false. + def self.verbose=(on) + @@verbose = on + end + + # Get the default value of the :verbose option. + def self.verbose + @@verbose + end + + def self.make_config(hash={}) # :nodoc: + default_config = { + :idconv => @@idconv, + :verbose => @@verbose, + :tcp_acl => @@acl, + :load_limit => @@load_limit, + :argc_limit => @@argc_limit, + :safe_level => @@safe_level + } + default_config.update(hash) + end + + # Create a new DRbServer instance. + # + # +uri+ is the URI to bind to. This is normally of the form + # 'druby://:' where is a hostname of + # the local machine. If nil, then the system's default hostname + # will be bound to, on a port selected by the system; these value + # can be retrieved from the +uri+ attribute. 'druby:' specifies + # the default dRuby transport protocol: another protocol, such + # as 'drbunix:', can be specified instead. + # + # +front+ is the front object for the server, that is, the object + # to which remote method calls on the server will be passed. If + # nil, then the server will not accept remote method calls. + # + # If +config_or_acl+ is a hash, it is the configuration to + # use for this server. The following options are recognised: + # + # :idconv :: an id-to-object conversion object. This defaults + # to an instance of the class DRb::DRbIdConv. + # :verbose :: if true, all unsuccessful remote calls on objects + # in the server will be logged to $stdout. false + # by default. + # :tcp_acl :: the access control list for this server. See + # the ACL class from the main dRuby distribution. + # :load_limit :: the maximum message size in bytes accepted by + # the server. Defaults to 25 MB (26214400). + # :argc_limit :: the maximum number of arguments to a remote + # method accepted by the server. Defaults to + # 256. + # + # The default values of these options can be modified on + # a class-wide basis by the class methods #default_argc_limit, + # #default_load_limit, #default_acl, #default_id_conv, + # and #verbose= + # + # If +config_or_acl+ is not a hash, but is not nil, it is + # assumed to be the access control list for this server. + # See the :tcp_acl option for more details. + # + # If no other server is currently set as the primary server, + # this will become the primary server. + # + # The server will immediately start running in its own thread. + def initialize(uri=nil, front=nil, config_or_acl=nil) + if Hash === config_or_acl + config = config_or_acl.dup + else + acl = config_or_acl || @@acl + config = { + :tcp_acl => acl + } + end + + @config = self.class.make_config(config) + + @protocol = DRbProtocol.open_server(uri, @config) + @uri = @protocol.uri + + @front = front + @idconv = @config[:idconv] + @safe_level = @config[:safe_level] + + @grp = ThreadGroup.new + @thread = run + + DRb.regist_server(self) + end + + # The URI of this DRbServer. + attr_reader :uri + + # The main thread of this DRbServer. + # + # This is the thread that listens for and accepts connections + # from clients, not that handles each client's request-response + # session. + attr_reader :thread + + # The front object of the DRbServer. + # + # This object receives remote method calls made on the server's + # URI alone, with an object id. + attr_reader :front + + # The configuration of this DRbServer + attr_reader :config + + attr_reader :safe_level + + # Set whether to operate in verbose mode. + # + # In verbose mode, failed calls are logged to stdout. + def verbose=(v); @config[:verbose]=v; end + + # Get whether the server is in verbose mode. + # + # In verbose mode, failed calls are logged to stdout. + def verbose; @config[:verbose]; end + + # Is this server alive? + def alive? + @thread.alive? + end + + # Stop this server. + def stop_service + DRb.remove_server(self) + if Thread.current['DRb'] && Thread.current['DRb']['server'] == self + Thread.current['DRb']['stop_service'] = true + else + @thread.kill + end + end + + # Convert a dRuby reference to the local object it refers to. + def to_obj(ref) + return front if ref.nil? + return front[ref.to_s] if DRbURIOption === ref + @idconv.to_obj(ref) + end + + # Convert a local object to a dRuby reference. + def to_id(obj) + return nil if obj.__id__ == front.__id__ + @idconv.to_id(obj) + end + + private + def kill_sub_thread + Thread.new do + grp = ThreadGroup.new + grp.add(Thread.current) + list = @grp.list + while list.size > 0 + list.each do |th| + th.kill if th.alive? + end + list = @grp.list + end + end + end + + def run + Thread.start do + begin + while true + main_loop + end + ensure + @protocol.close if @protocol + kill_sub_thread + end + end + end + + # List of insecure methods. + # + # These methods are not callable via dRuby. + INSECURE_METHOD = [ + :__send__ + ] + + # Has a method been included in the list of insecure methods? + def insecure_method?(msg_id) + INSECURE_METHOD.include?(msg_id) + end + + # Coerce an object to a string, providing our own representation if + # to_s is not defined for the object. + def any_to_s(obj) + obj.to_s + ":#{obj.class}" + rescue + sprintf("#<%s:0x%lx>", obj.class, obj.__id__) + end + + # Check that a method is callable via dRuby. + # + # +obj+ is the object we want to invoke the method on. +msg_id+ is the + # method name, as a Symbol. + # + # If the method is an insecure method (see #insecure_method?) a + # SecurityError is thrown. If the method is private or undefined, + # a NameError is thrown. + def check_insecure_method(obj, msg_id) + return true if Proc === obj && msg_id == :__drb_yield + raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class + raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id) + + if obj.private_methods.include?(msg_id.to_s) + desc = any_to_s(obj) + raise NoMethodError, "private method `#{msg_id}' called for #{desc}" + elsif obj.protected_methods.include?(msg_id.to_s) + desc = any_to_s(obj) + raise NoMethodError, "protected method `#{msg_id}' called for #{desc}" + else + true + end + end + public :check_insecure_method + + class InvokeMethod # :nodoc: + def initialize(drb_server, client) + @drb_server = drb_server + @safe_level = drb_server.safe_level + @client = client + end + + def perform + @result = nil + @succ = false + setup_message + + if $SAFE < @safe_level + info = Thread.current['DRb'] + if @block + @result = Thread.new { + Thread.current['DRb'] = info + $SAFE = @safe_level + perform_with_block + }.value + else + @result = Thread.new { + Thread.current['DRb'] = info + $SAFE = @safe_level + perform_without_block + }.value + end + else + if @block + @result = perform_with_block + else + @result = perform_without_block + end + end + @succ = true + if @msg_id == :to_ary && @result.class == Array + @result = DRbArray.new(@result) + end + return @succ, @result + rescue StandardError, ScriptError, Interrupt + @result = $! + return @succ, @result + end + + private + def init_with_client + obj, msg, argv, block = @client.recv_request + @obj = obj + @msg_id = msg.intern + @argv = argv + @block = block + end + + def check_insecure_method + @drb_server.check_insecure_method(@obj, @msg_id) + end + + def setup_message + init_with_client + check_insecure_method + end + + def perform_without_block + if Proc === @obj && @msg_id == :__drb_yield + if @argv.size == 1 + ary = @argv + else + ary = [@argv] + end + ary.collect(&@obj)[0] + else + @obj.__send__(@msg_id, *@argv) + end + end + + end + + if RUBY_VERSION >= '1.8' + require 'drb/invokemethod' + class InvokeMethod + include InvokeMethod18Mixin + end + else + require 'drb/invokemethod16' + class InvokeMethod + include InvokeMethod16Mixin + end + end + + # The main loop performed by a DRbServer's internal thread. + # + # Accepts a connection from a client, and starts up its own + # thread to handle it. This thread loops, receiving requests + # from the client, invoking them on a local object, and + # returning responses, until the client closes the connection + # or a local method call fails. + def main_loop + Thread.start(@protocol.accept) do |client| + @grp.add Thread.current + Thread.current['DRb'] = { 'client' => client , + 'server' => self } + loop do + begin + succ = false + invoke_method = InvokeMethod.new(self, client) + succ, result = invoke_method.perform + if !succ && verbose + p result + result.backtrace.each do |x| + puts x + end + end + client.send_reply(succ, result) rescue nil + ensure + client.close unless succ + if Thread.current['DRb']['stop_service'] + Thread.new { stop_service } + end + break unless succ + end + end + end + end + end + + @primary_server = nil + + # Start a dRuby server locally. + # + # The new dRuby server will become the primary server, even + # if another server is currently the primary server. + # + # +uri+ is the URI for the server to bind to. If nil, + # the server will bind to random port on the default local host + # name and use the default dRuby protocol. + # + # +front+ is the server's front object. This may be nil. + # + # +config+ is the configuration for the new server. This may + # be nil. + # + # See DRbServer::new. + def start_service(uri=nil, front=nil, config=nil) + @primary_server = DRbServer.new(uri, front, config) + end + module_function :start_service + + # The primary local dRuby server. + # + # This is the server created by the #start_service call. + attr_accessor :primary_server + module_function :primary_server=, :primary_server + + # Get the 'current' server. + # + # In the context of execution taking place within the main + # thread of a dRuby server (typically, as a result of a remote + # call on the server or one of its objects), the current + # server is that server. Otherwise, the current server is + # the primary server. + # + # If the above rule fails to find a server, a DRbServerNotFound + # error is raised. + def current_server + drb = Thread.current['DRb'] + server = (drb && drb['server']) ? drb['server'] : @primary_server + raise DRbServerNotFound unless server + return server + end + module_function :current_server + + # Stop the local dRuby server. + # + # This operates on the primary server. If there is no primary + # server currently running, it is a noop. + def stop_service + @primary_server.stop_service if @primary_server + @primary_server = nil + end + module_function :stop_service + + # Get the URI defining the local dRuby space. + # + # This is the URI of the current server. See #current_server. + def uri + current_server.uri + end + module_function :uri + + # Is +uri+ the URI for the current local server? + def here?(uri) + (current_server.uri rescue nil) == uri + end + module_function :here? + + # Get the configuration of the current server. + # + # If there is no current server, this returns the default configuration. + # See #current_server and DRbServer::make_config. + def config + current_server.config + rescue + DRbServer.make_config + end + module_function :config + + # Get the front object of the current server. + # + # This raises a DRbServerNotFound error if there is no current server. + # See #current_server. + def front + current_server.front + end + module_function :front + + # Convert a reference into an object using the current server. + # + # This raises a DRbServerNotFound error if there is no current server. + # See #current_server. + def to_obj(ref) + current_server.to_obj(ref) + end + + # Get a reference id for an object using the current server. + # + # This raises a DRbServerNotFound error if there is no current server. + # See #current_server. + def to_id(obj) + current_server.to_id(obj) + end + module_function :to_id + module_function :to_obj + + # Get the thread of the primary server. + # + # This returns nil if there is no primary server. See #primary_server. + def thread + @primary_server ? @primary_server.thread : nil + end + module_function :thread + + # Set the default id conv object. + # + # See DRbServer#default_id_conv. + def install_id_conv(idconv) + DRbServer.default_id_conv(idconv) + end + module_function :install_id_conv + + # Set the default acl. + # + # See DRb::DRbServer.default_acl. + def install_acl(acl) + DRbServer.default_acl(acl) + end + module_function :install_acl + + @server = {} + def regist_server(server) + @server[server.uri] = server + Thread.exclusive do + @primary_server = server unless @primary_server + end + end + module_function :regist_server + + def remove_server(server) + @server.delete(server.uri) + end + module_function :remove_server + + def fetch_server(uri) + @server[uri] + end + module_function :fetch_server +end + +DRbObject = DRb::DRbObject +DRbUndumped = DRb::DRbUndumped +DRbIdConv = DRb::DRbIdConv diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/eq.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/eq.rb new file mode 100644 index 00000000..e24512d6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/eq.rb @@ -0,0 +1,16 @@ +require 'drb/drb' + +module DRb + class DRbObject + def ==(other) + return false unless DRbObject === other + (@ref == other.__drbref) && (@uri == other.__drburi) + end + + def hash + [@uri, @ref].hash + end + + alias eql? == + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/extserv.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/extserv.rb new file mode 100644 index 00000000..7da8130c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/extserv.rb @@ -0,0 +1,64 @@ +=begin + external service + Copyright (c) 2000,2002 Masatoshi SEKI +=end + +require 'drb/drb' + +module DRb + class ExtServ + include DRbUndumped + + def initialize(there, name, server=nil) + @server = server || DRb::primary_server + @name = name + ro = DRbObject.new(nil, there) + @invoker = ro.regist(name, DRbObject.new(self, @server.uri)) + end + attr_reader :server + + def front + DRbObject.new(nil, @server.uri) + end + + def stop_service + @invoker.unregist(@name) + server = @server + @server = nil + server.stop_service + true + end + + def alive? + @server ? @server.alive? : false + end + end +end + +if __FILE__ == $0 + class Foo + include DRbUndumped + + def initialize(str) + @str = str + end + + def hello(it) + "#{it}: #{self}" + end + + def to_s + @str + end + end + + cmd = ARGV.shift + case cmd + when 'itest1', 'itest2' + front = Foo.new(cmd) + manager = DRb::DRbServer.new(nil, front) + es = DRb::ExtServ.new(ARGV.shift, ARGV.shift, manager) + es.server.thread.join + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/extservm.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/extservm.rb new file mode 100644 index 00000000..7066f84c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/extservm.rb @@ -0,0 +1,96 @@ +=begin + external service manager + Copyright (c) 2000 Masatoshi SEKI +=end + +require 'drb/drb' +require 'thread' + +module DRb + class ExtServManager + include DRbUndumped + + @@command = {} + + def self.command + @@command + end + + def self.command=(cmd) + @@command = cmd + end + + def initialize + @servers = {} + @waiting = [] + @queue = Queue.new + @thread = invoke_thread + @uri = nil + end + attr_accessor :uri + + def service(name) + while true + server = nil + Thread.exclusive do + server = @servers[name] if @servers[name] + end + return server if server && server.alive? + invoke_service(name) + end + end + + def regist(name, ro) + ary = nil + Thread.exclusive do + @servers[name] = ro + ary = @waiting + @waiting = [] + end + ary.each do |th| + begin + th.run + rescue ThreadError + end + end + self + end + + def unregist(name) + Thread.exclusive do + @servers.delete(name) + end + end + + private + def invoke_thread + Thread.new do + while true + name = @queue.pop + invoke_service_command(name, @@command[name]) + end + end + end + + def invoke_service(name) + Thread.critical = true + @waiting.push Thread.current + @queue.push name + Thread.stop + end + + def invoke_service_command(name, command) + raise "invalid command. name: #{name}" unless command + Thread.exclusive do + return if @servers.include?(name) + @servers[name] = false + end + uri = @uri || DRb.uri + if RUBY_PLATFORM =~ /mswin32/ && /NT/ =~ ENV["OS"] + system(%Q'cmd /c start "ruby" /b #{command} #{uri} #{name}') + else + system("#{command} #{uri} #{name} &") + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/gw.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/gw.rb new file mode 100644 index 00000000..b7a5f538 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/gw.rb @@ -0,0 +1,122 @@ +require 'drb/drb' +require 'monitor' + +module DRb + class GWIdConv < DRbIdConv + def to_obj(ref) + if Array === ref && ref[0] == :DRbObject + return DRbObject.new_with(ref[1], ref[2]) + end + super(ref) + end + end + + class GW + include MonitorMixin + def initialize + super() + @hash = {} + end + + def [](key) + synchronize do + @hash[key] + end + end + + def []=(key, v) + synchronize do + @hash[key] = v + end + end + end + + class DRbObject + def self._load(s) + uri, ref = Marshal.load(s) + if DRb.uri == uri + return ref ? DRb.to_obj(ref) : DRb.front + end + + self.new_with(DRb.uri, [:DRbObject, uri, ref]) + end + + def _dump(lv) + if DRb.uri == @uri + if Array === @ref && @ref[0] == :DRbObject + Marshal.dump([@ref[1], @ref[2]]) + else + Marshal.dump([@uri, @ref]) # ?? + end + else + Marshal.dump([DRb.uri, [:DRbObject, @uri, @ref]]) + end + end + end +end + +=begin +DRb.install_id_conv(DRb::GWIdConv.new) + +front = DRb::GW.new + +s1 = DRb::DRbServer.new('drbunix:/tmp/gw_b_a', front) +s2 = DRb::DRbServer.new('drbunix:/tmp/gw_b_c', front) + +s1.thread.join +s2.thread.join +=end + +=begin +# foo.rb + +require 'drb/drb' + +class Foo + include DRbUndumped + def initialize(name, peer=nil) + @name = name + @peer = peer + end + + def ping(obj) + puts "#{@name}: ping: #{obj.inspect}" + @peer.ping(self) if @peer + end +end +=end + +=begin +# gw_a.rb +require 'drb/unix' +require 'foo' + +obj = Foo.new('a') +DRb.start_service("drbunix:/tmp/gw_a", obj) + +robj = DRbObject.new_with_uri('drbunix:/tmp/gw_b_a') +robj[:a] = obj + +DRb.thread.join +=end + +=begin +# gw_c.rb +require 'drb/unix' +require 'foo' + +foo = Foo.new('c', nil) + +DRb.start_service("drbunix:/tmp/gw_c", nil) + +robj = DRbObject.new_with_uri("drbunix:/tmp/gw_b_c") + +puts "c->b" +a = robj[:a] +sleep 2 + +a.ping(foo) + +DRb.thread.join +=end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/invokemethod.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/invokemethod.rb new file mode 100644 index 00000000..412b2ab9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/invokemethod.rb @@ -0,0 +1,36 @@ +# for ruby-1.8.0 + +module DRb + class DRbServer + module InvokeMethod18Mixin + def block_yield(x) + if x.size == 1 && x[0].class == Array + x[0] = DRbArray.new(x[0]) + end + block_value = @block.call(*x) + end + + def perform_with_block + @obj.__send__(@msg_id, *@argv) do |*x| + jump_error = nil + begin + block_value = block_yield(x) + rescue LocalJumpError + jump_error = $! + end + if jump_error + case jump_error.reason + when :retry + retry + when :break + break(jump_error.exit_value) + else + raise jump_error + end + end + block_value + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/observer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/observer.rb new file mode 100644 index 00000000..e7f1668c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/observer.rb @@ -0,0 +1,22 @@ +require 'observer' + +module DRb + module DRbObservable + include Observable + + def notify_observers(*arg) + if defined? @observer_state and @observer_state + if defined? @observer_peers + for i in @observer_peers.dup + begin + i.update(*arg) + rescue + delete_observer(i) + end + end + end + @observer_state = false + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/ssl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/ssl.rb new file mode 100644 index 00000000..58d6b7d1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/ssl.rb @@ -0,0 +1,190 @@ +require 'socket' +require 'openssl' +require 'drb/drb' +require 'singleton' + +module DRb + + class DRbSSLSocket < DRbTCPSocket + + class SSLConfig + + DEFAULT = { + :SSLCertificate => nil, + :SSLPrivateKey => nil, + :SSLClientCA => nil, + :SSLCACertificatePath => nil, + :SSLCACertificateFile => nil, + :SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE, + :SSLVerifyDepth => nil, + :SSLVerifyCallback => nil, # custom verification + :SSLCertificateStore => nil, + # Must specify if you use auto generated certificate. + :SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]] + :SSLCertComment => "Generated by Ruby/OpenSSL" + } + + def initialize(config) + @config = config + @cert = config[:SSLCertificate] + @pkey = config[:SSLPrivateKey] + @ssl_ctx = nil + end + + def [](key); + @config[key] || DEFAULT[key] + end + + def connect(tcp) + ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx) + ssl.sync = true + ssl.connect + ssl + end + + def accept(tcp) + ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx) + ssl.sync = true + ssl.accept + ssl + end + + def setup_certificate + if @cert && @pkey + return + end + + rsa = OpenSSL::PKey::RSA.new(512){|p, n| + next unless self[:verbose] + case p + when 0; $stderr.putc "." # BN_generate_prime + when 1; $stderr.putc "+" # BN_generate_prime + when 2; $stderr.putc "*" # searching good prime, + # n = #of try, + # but also data from BN_generate_prime + when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q, + # but also data from BN_generate_prime + else; $stderr.putc "*" # BN_generate_prime + end + } + + cert = OpenSSL::X509::Certificate.new + cert.version = 3 + cert.serial = 0 + name = OpenSSL::X509::Name.new(self[:SSLCertName]) + cert.subject = name + cert.issuer = name + cert.not_before = Time.now + cert.not_after = Time.now + (365*24*60*60) + cert.public_key = rsa.public_key + + ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) + cert.extensions = [ + ef.create_extension("basicConstraints","CA:FALSE"), + ef.create_extension("subjectKeyIdentifier", "hash") ] + ef.issuer_certificate = cert + cert.add_extension(ef.create_extension("authorityKeyIdentifier", + "keyid:always,issuer:always")) + if comment = self[:SSLCertComment] + cert.add_extension(ef.create_extension("nsComment", comment)) + end + cert.sign(rsa, OpenSSL::Digest::SHA1.new) + + @cert = cert + @pkey = rsa + end + + def setup_ssl_context + ctx = ::OpenSSL::SSL::SSLContext.new + ctx.cert = @cert + ctx.key = @pkey + ctx.client_ca = self[:SSLClientCA] + ctx.ca_path = self[:SSLCACertificatePath] + ctx.ca_file = self[:SSLCACertificateFile] + ctx.verify_mode = self[:SSLVerifyMode] + ctx.verify_depth = self[:SSLVerifyDepth] + ctx.verify_callback = self[:SSLVerifyCallback] + ctx.cert_store = self[:SSLCertificateStore] + @ssl_ctx = ctx + end + end + + def self.parse_uri(uri) + if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/ + host = $1 + port = $2.to_i + option = $4 + [host, port, option] + else + raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/ + raise(DRbBadURI, 'can\'t parse uri:' + uri) + end + end + + def self.open(uri, config) + host, port, option = parse_uri(uri) + host.untaint + port.untaint + soc = TCPSocket.open(host, port) + ssl_conf = SSLConfig::new(config) + ssl_conf.setup_ssl_context + ssl = ssl_conf.connect(soc) + self.new(uri, ssl, ssl_conf, true) + end + + def self.open_server(uri, config) + uri = 'drbssl://:0' unless uri + host, port, opt = parse_uri(uri) + if host.size == 0 + host = getservername + soc = open_server_inaddr_any(host, port) + else + soc = TCPServer.open(host, port) + end + port = soc.addr[1] if port == 0 + @uri = "drbssl://#{host}:#{port}" + + ssl_conf = SSLConfig.new(config) + ssl_conf.setup_certificate + ssl_conf.setup_ssl_context + self.new(@uri, soc, ssl_conf, false) + end + + def self.uri_option(uri, config) + host, port, option = parse_uri(uri) + return "drbssl://#{host}:#{port}", option + end + + def initialize(uri, soc, config, is_established) + @ssl = is_established ? soc : nil + super(uri, soc.to_io, config) + end + + def stream; @ssl; end + + def close + if @ssl + @ssl.close + @ssl = nil + end + super + end + + def accept + begin + while true + soc = @socket.accept + break if (@acl ? @acl.allow_socket?(soc) : true) + soc.close + end + ssl = @config.accept(soc) + self.class.new(uri, ssl, @config, true) + rescue OpenSSL::SSL::SSLError + warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose] + retry + end + end + end + + DRbProtocol.add_protocol(DRbSSLSocket) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/timeridconv.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/timeridconv.rb new file mode 100644 index 00000000..bb2c48d5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/timeridconv.rb @@ -0,0 +1,91 @@ +require 'drb/drb' +require 'monitor' + +module DRb + class TimerIdConv < DRbIdConv + class TimerHolder2 + include MonitorMixin + + class InvalidIndexError < RuntimeError; end + + def initialize(timeout=600) + super() + @sentinel = Object.new + @gc = {} + @curr = {} + @renew = {} + @timeout = timeout + @keeper = keeper + end + + def add(obj) + synchronize do + key = obj.__id__ + @curr[key] = obj + return key + end + end + + def fetch(key, dv=@sentinel) + synchronize do + obj = peek(key) + if obj == @sentinel + return dv unless dv == @sentinel + raise InvalidIndexError + end + @renew[key] = obj # KeepIt + return obj + end + end + + def include?(key) + synchronize do + obj = peek(key) + return false if obj == @sentinel + true + end + end + + def peek(key) + synchronize do + return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel))) + end + end + + private + def alternate + synchronize do + @gc = @curr # GCed + @curr = @renew + @renew = {} + end + end + + def keeper + Thread.new do + loop do + size = alternate + sleep(@timeout) + end + end + end + end + + def initialize(timeout=600) + @holder = TimerHolder2.new(timeout) + end + + def to_obj(ref) + return super if ref.nil? + @holder.fetch(ref) + rescue TimerHolder2::InvalidIndexError + raise "invalid reference" + end + + def to_id(obj) + return @holder.add(obj) + end + end +end + +# DRb.install_id_conv(TimerIdConv.new) diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/unix.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/unix.rb new file mode 100644 index 00000000..57feed83 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/drb/unix.rb @@ -0,0 +1,108 @@ +require 'socket' +require 'drb/drb' +require 'tmpdir' + +raise(LoadError, "UNIXServer is required") unless defined?(UNIXServer) + +module DRb + + class DRbUNIXSocket < DRbTCPSocket + def self.parse_uri(uri) + if /^drbunix:(.*?)(\?(.*))?$/ =~ uri + filename = $1 + option = $3 + [filename, option] + else + raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/ + raise(DRbBadURI, 'can\'t parse uri:' + uri) + end + end + + def self.open(uri, config) + filename, option = parse_uri(uri) + filename.untaint + soc = UNIXSocket.open(filename) + self.new(uri, soc, config) + end + + def self.open_server(uri, config) + filename, option = parse_uri(uri) + if filename.size == 0 + soc = temp_server + filename = soc.path + uri = 'drbunix:' + soc.path + else + soc = UNIXServer.open(filename) + end + owner = config[:UNIXFileOwner] + group = config[:UNIXFileGroup] + if owner || group + require 'etc' + owner = Etc.getpwnam( owner ).uid if owner + group = Etc.getgrnam( group ).gid if group + File.chown owner, group, filename + end + mode = config[:UNIXFileMode] + File.chmod(mode, filename) if mode + + self.new(uri, soc, config, true) + end + + def self.uri_option(uri, config) + filename, option = parse_uri(uri) + return "drbunix:#{filename}", option + end + + def initialize(uri, soc, config={}, server_mode = false) + super(uri, soc, config) + set_sockopt(@socket) + @server_mode = server_mode + @acl = nil + end + + # import from tempfile.rb + Max_try = 10 + private + def self.temp_server + tmpdir = Dir::tmpdir + n = 0 + while true + begin + tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n) + lock = tmpname + '.lock' + unless File.exist?(tmpname) or File.exist?(lock) + Dir.mkdir(lock) + break + end + rescue + raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try + #sleep(1) + end + n += 1 + end + soc = UNIXServer.new(tmpname) + Dir.rmdir(lock) + soc + end + + public + def close + return unless @socket + path = @socket.path if @server_mode + @socket.close + File.unlink(path) if @server_mode + @socket = nil + end + + def accept + s = @socket.accept + self.class.new(nil, s, @config) + end + + def set_sockopt(soc) + soc.fcntl(Fcntl::F_SETFL, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC + end + end + + DRbProtocol.add_protocol(DRbUNIXSocket) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/e2mmap.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/e2mmap.rb new file mode 100644 index 00000000..3e2604af --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/e2mmap.rb @@ -0,0 +1,195 @@ +# +# e2mmap.rb - for ruby 1.1 +# $Release Version: 2.0$ +# $Revision: 1.10 $ +# $Date: 1999/02/17 12:33:17 $ +# by Keiju ISHITSUKA +# +# -- +# Usage: +# +# U1) +# class Foo +# extend Exception2MessageMapper +# def_e2message ExistingExceptionClass, "message..." +# def_exception :NewExceptionClass, "message..."[, superclass] +# ... +# end +# +# U2) +# module Error +# extend Exception2MessageMapper +# def_e2meggage ExistingExceptionClass, "message..." +# def_exception :NewExceptionClass, "message..."[, superclass] +# ... +# end +# class Foo +# include Error +# ... +# end +# +# foo = Foo.new +# foo.Fail .... +# +# U3) +# module Error +# extend Exception2MessageMapper +# def_e2message ExistingExceptionClass, "message..." +# def_exception :NewExceptionClass, "message..."[, superclass] +# ... +# end +# class Foo +# extend Exception2MessageMapper +# include Error +# ... +# end +# +# Foo.Fail NewExceptionClass, arg... +# Foo.Fail ExistingExceptionClass, arg... +# +# +fail "Use Ruby 1.1" if VERSION < "1.1" + +module Exception2MessageMapper + @RCS_ID='-$Id: e2mmap.rb,v 1.10 1999/02/17 12:33:17 keiju Exp keiju $-' + + E2MM = Exception2MessageMapper + + def E2MM.extend_object(cl) + super + cl.bind(self) unless cl == E2MM + end + + # backward compatibility + def E2MM.extend_to(b) + c = eval("self", b) + c.extend(self) + end + + def bind(cl) + self.module_eval %[ + def Raise(err = nil, *rest) + Exception2MessageMapper.Raise(self.class, err, *rest) + end + alias Fail Raise + + def self.included(mod) + mod.extend Exception2MessageMapper + end + ] + end + + # Fail(err, *rest) + # err: exception + # rest: message arguments + # + def Raise(err = nil, *rest) + E2MM.Raise(self, err, *rest) + end + alias Fail Raise + + # backward compatibility + alias fail! fail + def fail(err = nil, *rest) + begin + E2MM.Fail(self, err, *rest) + rescue E2MM::ErrNotRegisteredException + super + end + end + class << self + public :fail + end + + + # def_e2message(c, m) + # c: exception + # m: message_form + # define exception c with message m. + # + def def_e2message(c, m) + E2MM.def_e2message(self, c, m) + end + + # def_exception(n, m, s) + # n: exception_name + # m: message_form + # s: superclass(default: StandardError) + # define exception named ``c'' with message m. + # + def def_exception(n, m, s = StandardError) + E2MM.def_exception(self, n, m, s) + end + + # + # Private definitions. + # + # {[class, exp] => message, ...} + @MessageMap = {} + + # E2MM.def_exception(k, e, m) + # k: class to define exception under. + # e: exception + # m: message_form + # define exception c with message m. + # + def E2MM.def_e2message(k, c, m) + E2MM.instance_eval{@MessageMap[[k, c]] = m} + c + end + + # E2MM.def_exception(k, n, m, s) + # k: class to define exception under. + # n: exception_name + # m: message_form + # s: superclass(default: StandardError) + # define exception named ``c'' with message m. + # + def E2MM.def_exception(k, n, m, s = StandardError) + n = n.id2name if n.kind_of?(Fixnum) + e = Class.new(s) + E2MM.instance_eval{@MessageMap[[k, e]] = m} + k.const_set(n, e) + end + + # Fail(klass, err, *rest) + # klass: class to define exception under. + # err: exception + # rest: message arguments + # + def E2MM.Raise(klass = E2MM, err = nil, *rest) + if form = e2mm_message(klass, err) + $! = err.new(sprintf(form, *rest)) + $@ = caller(1) if $@.nil? + #p $@ + #p __FILE__ + $@.shift if $@[0] =~ /^#{Regexp.quote(__FILE__)}:/ + raise + else + E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect + end + end + class < +# EOF +# puts template.result(binding) +# +# Prints: The value of x is: 42 +# +# More complex examples are given below. +# +# +# == Recognized Tags +# +# ERB recognizes certain tags in the provided template and converts them based +# on the rules below: +# +# <% Ruby code -- inline with output %> +# <%= Ruby expression -- replace with result %> +# <%# comment -- ignored -- useful in testing %> +# % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new) +# %% replaced with % if first thing on a line and % processing is used +# <%% or %%> -- replace with <% or %> respectively +# +# All other text is passed through ERB filtering unchanged. +# +# +# == Options +# +# There are several settings you can change when you use ERB: +# * the nature of the tags that are recognized; +# * the value of $SAFE under which the template is run; +# * the binding used to resolve local variables in the template. +# +# See the ERB.new and ERB#result methods for more detail. +# +# +# == Examples +# +# === Plain Text +# +# ERB is useful for any generic templating situation. Note that in this example, we use the +# convenient "% at start of line" tag, and we quote the template literally with +# %q{...} to avoid trouble with the backslash. +# +# require "erb" +# +# # Create template. +# template = %q{ +# From: James Edward Gray II +# To: <%= to %> +# Subject: Addressing Needs +# +# <%= to[/\w+/] %>: +# +# Just wanted to send a quick note assuring that your needs are being +# addressed. +# +# I want you to know that my team will keep working on the issues, +# especially: +# +# <%# ignore numerous minor requests -- focus on priorities %> +# % priorities.each do |priority| +# * <%= priority %> +# % end +# +# Thanks for your patience. +# +# James Edward Gray II +# }.gsub(/^ /, '') +# +# message = ERB.new(template, 0, "%<>") +# +# # Set up template data. +# to = "Community Spokesman " +# priorities = [ "Run Ruby Quiz", +# "Document Modules", +# "Answer Questions on Ruby Talk" ] +# +# # Produce result. +# email = message.result +# puts email +# +# Generates: +# +# From: James Edward Gray II +# To: Community Spokesman +# Subject: Addressing Needs +# +# Community: +# +# Just wanted to send a quick note assuring that your needs are being addressed. +# +# I want you to know that my team will keep working on the issues, especially: +# +# * Run Ruby Quiz +# * Document Modules +# * Answer Questions on Ruby Talk +# +# Thanks for your patience. +# +# James Edward Gray II +# +# === Ruby in HTML +# +# ERB is often used in .rhtml files (HTML with embedded Ruby). Notice the need in +# this example to provide a special binding when the template is run, so that the instance +# variables in the Product object can be resolved. +# +# require "erb" +# +# # Build template data class. +# class Product +# def initialize( code, name, desc, cost ) +# @code = code +# @name = name +# @desc = desc +# @cost = cost +# +# @features = [ ] +# end +# +# def add_feature( feature ) +# @features << feature +# end +# +# # Support templating of member data. +# def get_binding +# binding +# end +# +# # ... +# end +# +# # Create template. +# template = %{ +# +# Ruby Toys -- <%= @name %> +# +# +#

<%= @name %> (<%= @code %>)

+#

<%= @desc %>

+# +#
    +# <% @features.each do |f| %> +#
  • <%= f %>
  • +# <% end %> +#
+# +#

+# <% if @cost < 10 %> +# Only <%= @cost %>!!! +# <% else %> +# Call for a price, today! +# <% end %> +#

+# +# +# +# }.gsub(/^ /, '') +# +# rhtml = ERB.new(template) +# +# # Set up template data. +# toy = Product.new( "TZ-1002", +# "Rubysapien", +# "Geek's Best Friend! Responds to Ruby commands...", +# 999.95 ) +# toy.add_feature("Listens for verbal commands in the Ruby language!") +# toy.add_feature("Ignores Perl, Java, and all C variants.") +# toy.add_feature("Karate-Chop Action!!!") +# toy.add_feature("Matz signature on left leg.") +# toy.add_feature("Gem studded eyes... Rubies, of course!") +# +# # Produce result. +# rhtml.run(toy.get_binding) +# +# Generates (some blank lines removed): +# +# +# Ruby Toys -- Rubysapien +# +# +#

Rubysapien (TZ-1002)

+#

Geek's Best Friend! Responds to Ruby commands...

+# +#
    +#
  • Listens for verbal commands in the Ruby language!
  • +#
  • Ignores Perl, Java, and all C variants.
  • +#
  • Karate-Chop Action!!!
  • +#
  • Matz signature on left leg.
  • +#
  • Gem studded eyes... Rubies, of course!
  • +#
+# +#

+# Call for a price, today! +#

+# +# +# +# +# +# == Notes +# +# There are a variety of templating solutions available in various Ruby projects: +# * ERB's big brother, eRuby, works the same but is written in C for speed; +# * Amrita (smart at producing HTML/XML); +# * cs/Template (written in C for speed); +# * RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere; +# * and others; search the RAA. +# +# Rails, the web application framework, uses ERB to create views. +# +class ERB + Revision = '$Date: 2008-06-24 16:16:52 +0900 (Tue, 24 Jun 2008) $' #' + + # Returns revision information for the erb.rb module. + def self.version + "erb.rb [2.0.4 #{ERB::Revision.split[1]}]" + end +end + +#-- +# ERB::Compiler +class ERB + class Compiler # :nodoc: + class PercentLine # :nodoc: + def initialize(str) + @value = str + end + attr_reader :value + alias :to_s :value + end + + class Scanner # :nodoc: + SplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>)|(\n)/ + + @scanner_map = {} + def self.regist_scanner(klass, trim_mode, percent) + @scanner_map[[trim_mode, percent]] = klass + end + + def self.default_scanner=(klass) + @default_scanner = klass + end + + def self.make_scanner(src, trim_mode, percent) + klass = @scanner_map.fetch([trim_mode, percent], @default_scanner) + klass.new(src, trim_mode, percent) + end + + def initialize(src, trim_mode, percent) + @src = src + @stag = nil + end + attr_accessor :stag + + def scan; end + end + + class TrimScanner < Scanner # :nodoc: + TrimSplitRegexp = /(<%%)|(%%>)|(<%=)|(<%#)|(<%)|(%>\n)|(%>)|(\n)/ + + def initialize(src, trim_mode, percent) + super + @trim_mode = trim_mode + @percent = percent + if @trim_mode == '>' + @scan_line = self.method(:trim_line1) + elsif @trim_mode == '<>' + @scan_line = self.method(:trim_line2) + elsif @trim_mode == '-' + @scan_line = self.method(:explicit_trim_line) + else + @scan_line = self.method(:scan_line) + end + end + attr_accessor :stag + + def scan(&block) + @stag = nil + if @percent + @src.each do |line| + percent_line(line, &block) + end + else + @src.each do |line| + @scan_line.call(line, &block) + end + end + nil + end + + def percent_line(line, &block) + if @stag || line[0] != ?% + return @scan_line.call(line, &block) + end + + line[0] = '' + if line[0] == ?% + @scan_line.call(line, &block) + else + yield(PercentLine.new(line.chomp)) + end + end + + def scan_line(line) + line.split(SplitRegexp).each do |token| + next if token.empty? + yield(token) + end + end + + def trim_line1(line) + line.split(TrimSplitRegexp).each do |token| + next if token.empty? + if token == "%>\n" + yield('%>') + yield(:cr) + break + end + yield(token) + end + end + + def trim_line2(line) + head = nil + line.split(TrimSplitRegexp).each do |token| + next if token.empty? + head = token unless head + if token == "%>\n" + yield('%>') + if is_erb_stag?(head) + yield(:cr) + else + yield("\n") + end + break + end + yield(token) + end + end + + def explicit_trim_line(line) + line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens| + tokens.each do |token| + next if token.empty? + if @stag.nil? && /[ \t]*<%-/ =~ token + yield('<%') + elsif @stag && token == "-%>\n" + yield('%>') + yield(:cr) + elsif @stag && token == '-%>' + yield('%>') + else + yield(token) + end + end + end + end + + ERB_STAG = %w(<%= <%# <%) + def is_erb_stag?(s) + ERB_STAG.member?(s) + end + end + + Scanner.default_scanner = TrimScanner + + class SimpleScanner < Scanner # :nodoc: + def scan + @src.each do |line| + line.split(SplitRegexp).each do |token| + next if token.empty? + yield(token) + end + end + end + end + + Scanner.regist_scanner(SimpleScanner, nil, false) + + begin + require 'strscan' + class SimpleScanner2 < Scanner # :nodoc: + def scan + stag_reg = /(.*?)(<%%|<%=|<%#|<%|\n|\z)/ + etag_reg = /(.*?)(%%>|%>|\n|\z)/ + scanner = StringScanner.new(@src) + while ! scanner.eos? + scanner.scan(@stag ? etag_reg : stag_reg) + text = scanner[1] + elem = scanner[2] + yield(text) unless text.empty? + yield(elem) unless elem.empty? + end + end + end + Scanner.regist_scanner(SimpleScanner2, nil, false) + + class PercentScanner < Scanner # :nodoc: + def scan + new_line = true + stag_reg = /(.*?)(<%%|<%=|<%#|<%|\n|\z)/ + etag_reg = /(.*?)(%%>|%>|\n|\z)/ + scanner = StringScanner.new(@src) + while ! scanner.eos? + if new_line && @stag.nil? + if scanner.scan(/%%/) + yield('%') + new_line = false + next + elsif scanner.scan(/%/) + yield(PercentLine.new(scanner.scan(/.*?(\n|\z)/).chomp)) + next + end + end + scanner.scan(@stag ? etag_reg : stag_reg) + text = scanner[1] + elem = scanner[2] + yield(text) unless text.empty? + yield(elem) unless elem.empty? + new_line = (elem == "\n") + end + end + end + Scanner.regist_scanner(PercentScanner, nil, true) + + class ExplicitScanner < Scanner # :nodoc: + def scan + new_line = true + stag_reg = /(.*?)(<%%|<%=|<%#|<%-|<%|\n|\z)/ + etag_reg = /(.*?)(%%>|-%>|%>|\n|\z)/ + scanner = StringScanner.new(@src) + while ! scanner.eos? + if new_line && @stag.nil? && scanner.scan(/[ \t]*<%-/) + yield('<%') + new_line = false + next + end + scanner.scan(@stag ? etag_reg : stag_reg) + text = scanner[1] + elem = scanner[2] + new_line = (elem == "\n") + yield(text) unless text.empty? + if elem == '-%>' + yield('%>') + if scanner.scan(/(\n|\z)/) + yield(:cr) + new_line = true + end + elsif elem == '<%-' + yield('<%') + else + yield(elem) unless elem.empty? + end + end + end + end + Scanner.regist_scanner(ExplicitScanner, '-', false) + + rescue LoadError + end + + class Buffer # :nodoc: + def initialize(compiler) + @compiler = compiler + @line = [] + @script = "" + @compiler.pre_cmd.each do |x| + push(x) + end + end + attr_reader :script + + def push(cmd) + @line << cmd + end + + def cr + @script << (@line.join('; ')) + @line = [] + @script << "\n" + end + + def close + return unless @line + @compiler.post_cmd.each do |x| + push(x) + end + @script << (@line.join('; ')) + @line = nil + end + end + + def compile(s) + out = Buffer.new(self) + + content = '' + scanner = make_scanner(s) + scanner.scan do |token| + if scanner.stag.nil? + case token + when PercentLine + out.push("#{@put_cmd} #{content.dump}") if content.size > 0 + content = '' + out.push(token.to_s) + out.cr + when :cr + out.cr + when '<%', '<%=', '<%#' + scanner.stag = token + out.push("#{@put_cmd} #{content.dump}") if content.size > 0 + content = '' + when "\n" + content << "\n" + out.push("#{@put_cmd} #{content.dump}") + out.cr + content = '' + when '<%%' + content << '<%' + else + content << token + end + else + case token + when '%>' + case scanner.stag + when '<%' + if content[-1] == ?\n + content.chop! + out.push(content) + out.cr + else + out.push(content) + end + when '<%=' + out.push("#{@insert_cmd}((#{content}).to_s)") + when '<%#' + # out.push("# #{content.dump}") + end + scanner.stag = nil + content = '' + when '%%>' + content << '%>' + else + content << token + end + end + end + out.push("#{@put_cmd} #{content.dump}") if content.size > 0 + out.close + out.script + end + + def prepare_trim_mode(mode) + case mode + when 1 + return [false, '>'] + when 2 + return [false, '<>'] + when 0 + return [false, nil] + when String + perc = mode.include?('%') + if mode.include?('-') + return [perc, '-'] + elsif mode.include?('<>') + return [perc, '<>'] + elsif mode.include?('>') + return [perc, '>'] + else + [perc, nil] + end + else + return [false, nil] + end + end + + def make_scanner(src) + Scanner.make_scanner(src, @trim_mode, @percent) + end + + def initialize(trim_mode) + @percent, @trim_mode = prepare_trim_mode(trim_mode) + @put_cmd = 'print' + @insert_cmd = @put_cmd + @pre_cmd = [] + @post_cmd = [] + end + attr_reader :percent, :trim_mode + attr_accessor :put_cmd, :insert_cmd, :pre_cmd, :post_cmd + end +end + +#-- +# ERB +class ERB + # + # Constructs a new ERB object with the template specified in _str_. + # + # An ERB object works by building a chunk of Ruby code that will output + # the completed template when run. If _safe_level_ is set to a non-nil value, + # ERB code will be run in a separate thread with $SAFE set to the + # provided level. + # + # If _trim_mode_ is passed a String containing one or more of the following + # modifiers, ERB will adjust its code generation as listed: + # + # % enables Ruby code processing for lines beginning with % + # <> omit newline for lines starting with <% and ending in %> + # > omit newline for lines ending in %> + # + # _eoutvar_ can be used to set the name of the variable ERB will build up + # its output in. This is useful when you need to run multiple ERB + # templates through the same binding and/or when you want to control where + # output ends up. Pass the name of the variable to be used inside a String. + # + # === Example + # + # require "erb" + # + # # build data class + # class Listings + # PRODUCT = { :name => "Chicken Fried Steak", + # :desc => "A well messages pattie, breaded and fried.", + # :cost => 9.95 } + # + # attr_reader :product, :price + # + # def initialize( product = "", price = "" ) + # @product = product + # @price = price + # end + # + # def build + # b = binding + # # create and run templates, filling member data variebles + # ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b + # <%= PRODUCT[:name] %> + # <%= PRODUCT[:desc] %> + # END_PRODUCT + # ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b + # <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %> + # <%= PRODUCT[:desc] %> + # END_PRICE + # end + # end + # + # # setup template data + # listings = Listings.new + # listings.build + # + # puts listings.product + "\n" + listings.price + # + # _Generates_ + # + # Chicken Fried Steak + # A well messages pattie, breaded and fried. + # + # Chicken Fried Steak -- 9.95 + # A well messages pattie, breaded and fried. + # + def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout') + @safe_level = safe_level + compiler = ERB::Compiler.new(trim_mode) + set_eoutvar(compiler, eoutvar) + @src = compiler.compile(str) + @filename = nil + end + + # The Ruby code generated by ERB + attr_reader :src + + # The optional _filename_ argument passed to Kernel#eval when the ERB code + # is run + attr_accessor :filename + + # + # Can be used to set _eoutvar_ as described in ERB#new. It's probably easier + # to just use the constructor though, since calling this method requires the + # setup of an ERB _compiler_ object. + # + def set_eoutvar(compiler, eoutvar = '_erbout') + compiler.put_cmd = "#{eoutvar}.concat" + compiler.insert_cmd = "#{eoutvar}.concat" + + cmd = [] + cmd.push "#{eoutvar} = ''" + + compiler.pre_cmd = cmd + + cmd = [] + cmd.push(eoutvar) + + compiler.post_cmd = cmd + end + + # Generate results and print them. (see ERB#result) + def run(b=TOPLEVEL_BINDING) + print self.result(b) + end + + # + # Executes the generated ERB code to produce a completed template, returning + # the results of that code. (See ERB#new for details on how this process can + # be affected by _safe_level_.) + # + # _b_ accepts a Binding or Proc object which is used to set the context of + # code evaluation. + # + def result(b=TOPLEVEL_BINDING) + if @safe_level + th = Thread.start { + $SAFE = @safe_level + eval(@src, b, (@filename || '(erb)'), 1) + } + return th.value + else + return eval(@src, b, (@filename || '(erb)'), 1) + end + end + + def def_method(mod, methodname, fname='(ERB)') # :nodoc: + mod.module_eval("def #{methodname}\n" + self.src + "\nend\n", fname, 0) + end + + def def_module(methodname='erb') # :nodoc: + mod = Module.new + def_method(mod, methodname) + mod + end + + def def_class(superklass=Object, methodname='result') # :nodoc: + cls = Class.new(superklass) + def_method(cls, methodname) + cls + end +end + +#-- +# ERB::Util +class ERB + # A utility module for conversion routines, often handy in HTML generation. + module Util + public + # + # A utility method for escaping HTML tag characters in _s_. + # + # require "erb" + # include ERB::Util + # + # puts html_escape("is a > 0 & a < 10?") + # + # _Generates_ + # + # is a > 0 & a < 10? + # + def html_escape(s) + s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/, options) +# chmod(mode, list, options) +# chmod_R(mode, list, options) +# chown(user, group, list, options) +# chown_R(user, group, list, options) +# touch(list, options) +# +# The options parameter is a hash of options, taken from the list +# :force, :noop, :preserve, and :verbose. +# :noop means that no changes are made. The other two are obvious. +# Each method documents the options that it honours. +# +# All methods that have the concept of a "source" file or directory can take +# either one file or a list of files in that argument. See the method +# documentation for examples. +# +# There are some `low level' methods, which do not accept any option: +# +# copy_entry(src, dest, preserve = false, dereference = false) +# copy_file(src, dest, preserve = false, dereference = true) +# copy_stream(srcstream, deststream) +# remove_entry(path, force = false) +# remove_entry_secure(path, force = false) +# remove_file(path, force = false) +# compare_file(path_a, path_b) +# compare_stream(stream_a, stream_b) +# uptodate?(file, cmp_list) +# +# == module FileUtils::Verbose +# +# This module has all methods of FileUtils module, but it outputs messages +# before acting. This equates to passing the :verbose flag to methods +# in FileUtils. +# +# == module FileUtils::NoWrite +# +# This module has all methods of FileUtils module, but never changes +# files/directories. This equates to passing the :noop flag to methods +# in FileUtils. +# +# == module FileUtils::DryRun +# +# This module has all methods of FileUtils module, but never changes +# files/directories. This equates to passing the :noop and +# :verbose flags to methods in FileUtils. +# + +module FileUtils + + def self.private_module_function(name) #:nodoc: + module_function name + private_class_method name + end + + # This hash table holds command options. + OPT_TABLE = {} #:nodoc: internal use only + + # + # Options: (none) + # + # Returns the name of the current directory. + # + def pwd + Dir.pwd + end + module_function :pwd + + alias getwd pwd + module_function :getwd + + # + # Options: verbose + # + # Changes the current directory to the directory +dir+. + # + # If this method is called with block, resumes to the old + # working directory after the block execution finished. + # + # FileUtils.cd('/', :verbose => true) # chdir and report it + # + def cd(dir, options = {}, &block) # :yield: dir + fu_check_options options, OPT_TABLE['cd'] + fu_output_message "cd #{dir}" if options[:verbose] + Dir.chdir(dir, &block) + fu_output_message 'cd -' if options[:verbose] and block + end + module_function :cd + + alias chdir cd + module_function :chdir + + OPT_TABLE['cd'] = + OPT_TABLE['chdir'] = [:verbose] + + # + # Options: (none) + # + # Returns true if +newer+ is newer than all +old_list+. + # Non-existent files are older than any file. + # + # FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \ + # system 'make hello.o' + # + def uptodate?(new, old_list, options = nil) + raise ArgumentError, 'uptodate? does not accept any option' if options + + return false unless File.exist?(new) + new_time = File.mtime(new) + old_list.each do |old| + if File.exist?(old) + return false unless new_time > File.mtime(old) + end + end + true + end + module_function :uptodate? + + # + # Options: mode noop verbose + # + # Creates one or more directories. + # + # FileUtils.mkdir 'test' + # FileUtils.mkdir %w( tmp data ) + # FileUtils.mkdir 'notexist', :noop => true # Does not really create. + # FileUtils.mkdir 'tmp', :mode => 0700 + # + def mkdir(list, options = {}) + fu_check_options options, OPT_TABLE['mkdir'] + list = fu_list(list) + fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose] + return if options[:noop] + + list.each do |dir| + fu_mkdir dir, options[:mode] + end + end + module_function :mkdir + + OPT_TABLE['mkdir'] = [:mode, :noop, :verbose] + + # + # Options: mode noop verbose + # + # Creates a directory and all its parent directories. + # For example, + # + # FileUtils.mkdir_p '/usr/local/lib/ruby' + # + # causes to make following directories, if it does not exist. + # * /usr + # * /usr/local + # * /usr/local/lib + # * /usr/local/lib/ruby + # + # You can pass several directories at a time in a list. + # + def mkdir_p(list, options = {}) + fu_check_options options, OPT_TABLE['mkdir_p'] + list = fu_list(list) + fu_output_message "mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose] + return *list if options[:noop] + + list.map {|path| path.sub(%r, '') }.each do |path| + # optimize for the most common case + begin + fu_mkdir path, options[:mode] + next + rescue SystemCallError + next if File.directory?(path) + end + + stack = [] + until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/" + stack.push path + path = File.dirname(path) + end + stack.reverse_each do |path| + begin + fu_mkdir path, options[:mode] + rescue SystemCallError => err + raise unless File.directory?(path) + end + end + end + + return *list + end + module_function :mkdir_p + + alias mkpath mkdir_p + alias makedirs mkdir_p + module_function :mkpath + module_function :makedirs + + OPT_TABLE['mkdir_p'] = + OPT_TABLE['mkpath'] = + OPT_TABLE['makedirs'] = [:mode, :noop, :verbose] + + def fu_mkdir(path, mode) #:nodoc: + path = path.sub(%r, '') + if mode + Dir.mkdir path, mode + File.chmod mode, path + else + Dir.mkdir path + end + end + private_module_function :fu_mkdir + + # + # Options: noop, verbose + # + # Removes one or more directories. + # + # FileUtils.rmdir 'somedir' + # FileUtils.rmdir %w(somedir anydir otherdir) + # # Does not really remove directory; outputs message. + # FileUtils.rmdir 'somedir', :verbose => true, :noop => true + # + def rmdir(list, options = {}) + fu_check_options options, OPT_TABLE['rmdir'] + list = fu_list(list) + fu_output_message "rmdir #{list.join ' '}" if options[:verbose] + return if options[:noop] + list.each do |dir| + Dir.rmdir dir.sub(%r, '') + end + end + module_function :rmdir + + OPT_TABLE['rmdir'] = [:noop, :verbose] + + # + # Options: force noop verbose + # + # ln(old, new, options = {}) + # + # Creates a hard link +new+ which points to +old+. + # If +new+ already exists and it is a directory, creates a link +new/old+. + # If +new+ already exists and it is not a directory, raises Errno::EEXIST. + # But if :force option is set, overwrite +new+. + # + # FileUtils.ln 'gcc', 'cc', :verbose => true + # FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs' + # + # ln(list, destdir, options = {}) + # + # Creates several hard links in a directory, with each one pointing to the + # item in +list+. If +destdir+ is not a directory, raises Errno::ENOTDIR. + # + # include FileUtils + # cd '/sbin' + # FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked. + # + def ln(src, dest, options = {}) + fu_check_options options, OPT_TABLE['ln'] + fu_output_message "ln#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose] + return if options[:noop] + fu_each_src_dest0(src, dest) do |s,d| + remove_file d, true if options[:force] + File.link s, d + end + end + module_function :ln + + alias link ln + module_function :link + + OPT_TABLE['ln'] = + OPT_TABLE['link'] = [:force, :noop, :verbose] + + # + # Options: force noop verbose + # + # ln_s(old, new, options = {}) + # + # Creates a symbolic link +new+ which points to +old+. If +new+ already + # exists and it is a directory, creates a symbolic link +new/old+. If +new+ + # already exists and it is not a directory, raises Errno::EEXIST. But if + # :force option is set, overwrite +new+. + # + # FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby' + # FileUtils.ln_s 'verylongsourcefilename.c', 'c', :force => true + # + # ln_s(list, destdir, options = {}) + # + # Creates several symbolic links in a directory, with each one pointing to the + # item in +list+. If +destdir+ is not a directory, raises Errno::ENOTDIR. + # + # If +destdir+ is not a directory, raises Errno::ENOTDIR. + # + # FileUtils.ln_s Dir.glob('bin/*.rb'), '/home/aamine/bin' + # + def ln_s(src, dest, options = {}) + fu_check_options options, OPT_TABLE['ln_s'] + fu_output_message "ln -s#{options[:force] ? 'f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose] + return if options[:noop] + fu_each_src_dest0(src, dest) do |s,d| + remove_file d, true if options[:force] + File.symlink s, d + end + end + module_function :ln_s + + alias symlink ln_s + module_function :symlink + + OPT_TABLE['ln_s'] = + OPT_TABLE['symlink'] = [:force, :noop, :verbose] + + # + # Options: noop verbose + # + # Same as + # #ln_s(src, dest, :force) + # + def ln_sf(src, dest, options = {}) + fu_check_options options, OPT_TABLE['ln_sf'] + options = options.dup + options[:force] = true + ln_s src, dest, options + end + module_function :ln_sf + + OPT_TABLE['ln_sf'] = [:noop, :verbose] + + # + # Options: preserve noop verbose + # + # Copies a file content +src+ to +dest+. If +dest+ is a directory, + # copies +src+ to +dest/src+. + # + # If +src+ is a list of files, then +dest+ must be a directory. + # + # FileUtils.cp 'eval.c', 'eval.c.org' + # FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6' + # FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true + # FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink + # + def cp(src, dest, options = {}) + fu_check_options options, OPT_TABLE['cp'] + fu_output_message "cp#{options[:preserve] ? ' -p' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose] + return if options[:noop] + fu_each_src_dest(src, dest) do |s, d| + copy_file s, d, options[:preserve] + end + end + module_function :cp + + alias copy cp + module_function :copy + + OPT_TABLE['cp'] = + OPT_TABLE['copy'] = [:preserve, :noop, :verbose] + + # + # Options: preserve noop verbose dereference_root remove_destination + # + # Copies +src+ to +dest+. If +src+ is a directory, this method copies + # all its contents recursively. If +dest+ is a directory, copies + # +src+ to +dest/src+. + # + # +src+ can be a list of files. + # + # # Installing ruby library "mylib" under the site_ruby + # FileUtils.rm_r site_ruby + '/mylib', :force + # FileUtils.cp_r 'lib/', site_ruby + '/mylib' + # + # # Examples of copying several files to target directory. + # FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail' + # FileUtils.cp_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true + # + # # If you want to copy all contents of a directory instead of the + # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y, + # # use following code. + # FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes src/dest, + # # but this doesn't. + # + def cp_r(src, dest, options = {}) + fu_check_options options, OPT_TABLE['cp_r'] + fu_output_message "cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose] + return if options[:noop] + options[:dereference_root] = true unless options.key?(:dereference_root) + fu_each_src_dest(src, dest) do |s, d| + copy_entry s, d, options[:preserve], options[:dereference_root], options[:remove_destination] + end + end + module_function :cp_r + + OPT_TABLE['cp_r'] = [:preserve, :noop, :verbose, + :dereference_root, :remove_destination] + + # + # Copies a file system entry +src+ to +dest+. + # If +src+ is a directory, this method copies its contents recursively. + # This method preserves file types, c.f. symlink, directory... + # (FIFO, device files and etc. are not supported yet) + # + # Both of +src+ and +dest+ must be a path name. + # +src+ must exist, +dest+ must not exist. + # + # If +preserve+ is true, this method preserves owner, group, permissions + # and modified time. + # + # If +dereference_root+ is true, this method dereference tree root. + # + # If +remove_destination+ is true, this method removes each destination file before copy. + # + def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false) + Entry_.new(src, nil, dereference_root).traverse do |ent| + destent = Entry_.new(dest, ent.rel, false) + File.unlink destent.path if remove_destination && File.file?(destent.path) + ent.copy destent.path + ent.copy_metadata destent.path if preserve + end + end + module_function :copy_entry + + # + # Copies file contents of +src+ to +dest+. + # Both of +src+ and +dest+ must be a path name. + # + def copy_file(src, dest, preserve = false, dereference = true) + ent = Entry_.new(src, nil, dereference) + ent.copy_file dest + ent.copy_metadata dest if preserve + end + module_function :copy_file + + # + # Copies stream +src+ to +dest+. + # +src+ must respond to #read(n) and + # +dest+ must respond to #write(str). + # + def copy_stream(src, dest) + fu_copy_stream0 src, dest, fu_stream_blksize(src, dest) + end + module_function :copy_stream + + # + # Options: force noop verbose + # + # Moves file(s) +src+ to +dest+. If +file+ and +dest+ exist on the different + # disk partition, the file is copied instead. + # + # FileUtils.mv 'badname.rb', 'goodname.rb' + # FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true # no error + # + # FileUtils.mv %w(junk.txt dust.txt), '/home/aamine/.trash/' + # FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true + # + def mv(src, dest, options = {}) + fu_check_options options, OPT_TABLE['mv'] + fu_output_message "mv#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose] + return if options[:noop] + fu_each_src_dest(src, dest) do |s, d| + destent = Entry_.new(d, nil, true) + begin + if destent.exist? + if destent.directory? + raise Errno::EEXIST, dest + else + destent.remove_file if rename_cannot_overwrite_file? + end + end + begin + File.rename s, d + rescue Errno::EXDEV + copy_entry s, d, true + if options[:secure] + remove_entry_secure s, options[:force] + else + remove_entry s, options[:force] + end + end + rescue SystemCallError + raise unless options[:force] + end + end + end + module_function :mv + + alias move mv + module_function :move + + OPT_TABLE['mv'] = + OPT_TABLE['move'] = [:force, :noop, :verbose, :secure] + + def rename_cannot_overwrite_file? #:nodoc: + /djgpp|cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM + end + private_module_function :rename_cannot_overwrite_file? + + # + # Options: force noop verbose + # + # Remove file(s) specified in +list+. This method cannot remove directories. + # All StandardErrors are ignored when the :force option is set. + # + # FileUtils.rm %w( junk.txt dust.txt ) + # FileUtils.rm Dir.glob('*.so') + # FileUtils.rm 'NotExistFile', :force => true # never raises exception + # + def rm(list, options = {}) + fu_check_options options, OPT_TABLE['rm'] + list = fu_list(list) + fu_output_message "rm#{options[:force] ? ' -f' : ''} #{list.join ' '}" if options[:verbose] + return if options[:noop] + + list.each do |path| + remove_file path, options[:force] + end + end + module_function :rm + + alias remove rm + module_function :remove + + OPT_TABLE['rm'] = + OPT_TABLE['remove'] = [:force, :noop, :verbose] + + # + # Options: noop verbose + # + # Equivalent to + # + # #rm(list, :force => true) + # + def rm_f(list, options = {}) + fu_check_options options, OPT_TABLE['rm_f'] + options = options.dup + options[:force] = true + rm list, options + end + module_function :rm_f + + alias safe_unlink rm_f + module_function :safe_unlink + + OPT_TABLE['rm_f'] = + OPT_TABLE['safe_unlink'] = [:noop, :verbose] + + # + # Options: force noop verbose secure + # + # remove files +list+[0] +list+[1]... If +list+[n] is a directory, + # removes its all contents recursively. This method ignores + # StandardError when :force option is set. + # + # FileUtils.rm_r Dir.glob('/tmp/*') + # FileUtils.rm_r '/', :force => true # :-) + # + # WARNING: This method causes local vulnerability + # if one of parent directories or removing directory tree are world + # writable (including /tmp, whose permission is 1777), and the current + # process has strong privilege such as Unix super user (root), and the + # system has symbolic link. For secure removing, read the documentation + # of #remove_entry_secure carefully, and set :secure option to true. + # Default is :secure=>false. + # + # NOTE: This method calls #remove_entry_secure if :secure option is set. + # See also #remove_entry_secure. + # + def rm_r(list, options = {}) + fu_check_options options, OPT_TABLE['rm_r'] + # options[:secure] = true unless options.key?(:secure) + list = fu_list(list) + fu_output_message "rm -r#{options[:force] ? 'f' : ''} #{list.join ' '}" if options[:verbose] + return if options[:noop] + list.each do |path| + if options[:secure] + remove_entry_secure path, options[:force] + else + remove_entry path, options[:force] + end + end + end + module_function :rm_r + + OPT_TABLE['rm_r'] = [:force, :noop, :verbose, :secure] + + # + # Options: noop verbose secure + # + # Equivalent to + # + # #rm_r(list, :force => true) + # + # WARNING: This method causes local vulnerability. + # Read the documentation of #rm_r first. + # + def rm_rf(list, options = {}) + fu_check_options options, OPT_TABLE['rm_rf'] + options = options.dup + options[:force] = true + rm_r list, options + end + module_function :rm_rf + + alias rmtree rm_rf + module_function :rmtree + + OPT_TABLE['rm_rf'] = + OPT_TABLE['rmtree'] = [:noop, :verbose, :secure] + + # + # This method removes a file system entry +path+. +path+ shall be a + # regular file, a directory, or something. If +path+ is a directory, + # remove it recursively. This method is required to avoid TOCTTOU + # (time-of-check-to-time-of-use) local security vulnerability of #rm_r. + # #rm_r causes security hole when: + # + # * Parent directory is world writable (including /tmp). + # * Removing directory tree includes world writable directory. + # * The system has symbolic link. + # + # To avoid this security hole, this method applies special preprocess. + # If +path+ is a directory, this method chown(2) and chmod(2) all + # removing directories. This requires the current process is the + # owner of the removing whole directory tree, or is the super user (root). + # + # WARNING: You must ensure that *ALL* parent directories are not + # world writable. Otherwise this method does not work. + # Only exception is temporary directory like /tmp and /var/tmp, + # whose permission is 1777. + # + # WARNING: Only the owner of the removing directory tree, or Unix super + # user (root) should invoke this method. Otherwise this method does not + # work. + # + # For details of this security vulnerability, see Perl's case: + # + # http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448 + # http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452 + # + # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100]. + # + def remove_entry_secure(path, force = false) + unless fu_have_symlink? + remove_entry path, force + return + end + fullpath = File.expand_path(path) + st = File.lstat(fullpath) + unless st.directory? + File.unlink fullpath + return + end + # is a directory. + parent_st = File.stat(File.dirname(fullpath)) + unless fu_world_writable?(parent_st) + remove_entry path, force + return + end + unless parent_st.sticky? + raise ArgumentError, "parent directory is world writable, FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})" + end + # freeze tree root + euid = Process.euid + File.open(fullpath + '/.') {|f| + unless fu_stat_identical_entry?(st, f.stat) + # symlink (TOC-to-TOU attack?) + File.unlink fullpath + return + end + f.chown euid, -1 + f.chmod 0700 + } + # ---- tree root is frozen ---- + root = Entry_.new(path) + root.preorder_traverse do |ent| + if ent.directory? + ent.chown euid, -1 + ent.chmod 0700 + end + end + root.postorder_traverse do |ent| + begin + ent.remove + rescue + raise unless force + end + end + rescue + raise unless force + end + module_function :remove_entry_secure + + def fu_world_writable?(st) + (st.mode & 0002) != 0 + end + private_module_function :fu_world_writable? + + def fu_have_symlink? #:nodoc + File.symlink nil, nil + rescue NotImplementedError + return false + rescue + return true + end + private_module_function :fu_have_symlink? + + def fu_stat_identical_entry?(a, b) #:nodoc: + a.dev == b.dev and a.ino == b.ino + end + private_module_function :fu_stat_identical_entry? + + # + # This method removes a file system entry +path+. + # +path+ might be a regular file, a directory, or something. + # If +path+ is a directory, remove it recursively. + # + # See also #remove_entry_secure. + # + def remove_entry(path, force = false) + Entry_.new(path).postorder_traverse do |ent| + begin + ent.remove + rescue + raise unless force + end + end + rescue + raise unless force + end + module_function :remove_entry + + # + # Removes a file +path+. + # This method ignores StandardError if +force+ is true. + # + def remove_file(path, force = false) + Entry_.new(path).remove_file + rescue + raise unless force + end + module_function :remove_file + + # + # Removes a directory +dir+ and its contents recursively. + # This method ignores StandardError if +force+ is true. + # + def remove_dir(path, force = false) + remove_entry path, force # FIXME?? check if it is a directory + end + module_function :remove_dir + + # + # Returns true if the contents of a file A and a file B are identical. + # + # FileUtils.compare_file('somefile', 'somefile') #=> true + # FileUtils.compare_file('/bin/cp', '/bin/mv') #=> maybe false + # + def compare_file(a, b) + return false unless File.size(a) == File.size(b) + File.open(a, 'rb') {|fa| + File.open(b, 'rb') {|fb| + return compare_stream(fa, fb) + } + } + end + module_function :compare_file + + alias identical? compare_file + alias cmp compare_file + module_function :identical? + module_function :cmp + + # + # Returns true if the contents of a stream +a+ and +b+ are identical. + # + def compare_stream(a, b) + bsize = fu_stream_blksize(a, b) + sa = sb = nil + while sa == sb + sa = a.read(bsize) + sb = b.read(bsize) + unless sa and sb + if sa.nil? and sb.nil? + return true + end + end + end + false + end + module_function :compare_stream + + # + # Options: mode preserve noop verbose + # + # If +src+ is not same as +dest+, copies it and changes the permission + # mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+. + # This method removes destination before copy. + # + # FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true + # FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true + # + def install(src, dest, options = {}) + fu_check_options options, OPT_TABLE['install'] + fu_output_message "install -c#{options[:preserve] && ' -p'}#{options[:mode] ? (' -m 0%o' % options[:mode]) : ''} #{[src,dest].flatten.join ' '}" if options[:verbose] + return if options[:noop] + fu_each_src_dest(src, dest) do |s, d| + unless File.exist?(d) and compare_file(s, d) + remove_file d, true + st = File.stat(s) if options[:preserve] + copy_file s, d + File.utime st.atime, st.mtime, d if options[:preserve] + File.chmod options[:mode], d if options[:mode] + end + end + end + module_function :install + + OPT_TABLE['install'] = [:mode, :preserve, :noop, :verbose] + + # + # Options: noop verbose + # + # Changes permission bits on the named files (in +list+) to the bit pattern + # represented by +mode+. + # + # FileUtils.chmod 0755, 'somecommand' + # FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb) + # FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true + # + def chmod(mode, list, options = {}) + fu_check_options options, OPT_TABLE['chmod'] + list = fu_list(list) + fu_output_message sprintf('chmod %o %s', mode, list.join(' ')) if options[:verbose] + return if options[:noop] + list.each do |path| + Entry_.new(path).chmod mode + end + end + module_function :chmod + + OPT_TABLE['chmod'] = [:noop, :verbose] + + # + # Options: noop verbose force + # + # Changes permission bits on the named files (in +list+) + # to the bit pattern represented by +mode+. + # + # FileUtils.chmod_R 0700, "/tmp/app.#{$$}" + # + def chmod_R(mode, list, options = {}) + fu_check_options options, OPT_TABLE['chmod_R'] + list = fu_list(list) + fu_output_message sprintf('chmod -R%s %o %s', + (options[:force] ? 'f' : ''), + mode, list.join(' ')) if options[:verbose] + return if options[:noop] + list.each do |root| + Entry_.new(root).traverse do |ent| + begin + ent.chmod mode + rescue + raise unless options[:force] + end + end + end + end + module_function :chmod_R + + OPT_TABLE['chmod_R'] = [:noop, :verbose, :force] + + # + # Options: noop verbose + # + # Changes owner and group on the named files (in +list+) + # to the user +user+ and the group +group+. +user+ and +group+ + # may be an ID (Integer/String) or a name (String). + # If +user+ or +group+ is nil, this method does not change + # the attribute. + # + # FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby' + # FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true + # + def chown(user, group, list, options = {}) + fu_check_options options, OPT_TABLE['chown'] + list = fu_list(list) + fu_output_message sprintf('chown %s%s', + [user,group].compact.join(':') + ' ', + list.join(' ')) if options[:verbose] + return if options[:noop] + uid = fu_get_uid(user) + gid = fu_get_gid(group) + list.each do |path| + Entry_.new(path).chown uid, gid + end + end + module_function :chown + + OPT_TABLE['chown'] = [:noop, :verbose] + + # + # Options: noop verbose force + # + # Changes owner and group on the named files (in +list+) + # to the user +user+ and the group +group+ recursively. + # +user+ and +group+ may be an ID (Integer/String) or + # a name (String). If +user+ or +group+ is nil, this + # method does not change the attribute. + # + # FileUtils.chown_R 'www', 'www', '/var/www/htdocs' + # FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true + # + def chown_R(user, group, list, options = {}) + fu_check_options options, OPT_TABLE['chown_R'] + list = fu_list(list) + fu_output_message sprintf('chown -R%s %s%s', + (options[:force] ? 'f' : ''), + [user,group].compact.join(':') + ' ', + list.join(' ')) if options[:verbose] + return if options[:noop] + uid = fu_get_uid(user) + gid = fu_get_gid(group) + return unless uid or gid + list.each do |root| + Entry_.new(root).traverse do |ent| + begin + ent.chown uid, gid + rescue + raise unless options[:force] + end + end + end + end + module_function :chown_R + + OPT_TABLE['chown_R'] = [:noop, :verbose, :force] + + begin + require 'etc' + + def fu_get_uid(user) #:nodoc: + return nil unless user + user = user.to_s + if /\A\d+\z/ =~ user + then user.to_i + else Etc.getpwnam(user).uid + end + end + private_module_function :fu_get_uid + + def fu_get_gid(group) #:nodoc: + return nil unless group + if /\A\d+\z/ =~ group + then group.to_i + else Etc.getgrnam(group).gid + end + end + private_module_function :fu_get_gid + + rescue LoadError + # need Win32 support??? + + def fu_get_uid(user) #:nodoc: + user # FIXME + end + private_module_function :fu_get_uid + + def fu_get_gid(group) #:nodoc: + group # FIXME + end + private_module_function :fu_get_gid + end + + # + # Options: noop verbose + # + # Updates modification time (mtime) and access time (atime) of file(s) in + # +list+. Files are created if they don't exist. + # + # FileUtils.touch 'timestamp' + # FileUtils.touch Dir.glob('*.c'); system 'make' + # + def touch(list, options = {}) + fu_check_options options, OPT_TABLE['touch'] + list = fu_list(list) + created = nocreate = options[:nocreate] + t = options[:mtime] + if options[:verbose] + fu_output_message "touch #{nocreate ? ' -c' : ''}#{t ? t.strftime(' -t %Y%m%d%H%M.%S') : ''}#{list.join ' '}" + end + return if options[:noop] + list.each do |path| + created = nocreate + begin + File.utime(t, t, path) + rescue Errno::ENOENT + raise if created + File.open(path, 'a') { + ; + } + created = true + retry if t + end + end + end + module_function :touch + + OPT_TABLE['touch'] = [:noop, :verbose, :mtime, :nocreate] + + private + + module StreamUtils_ + private + + def fu_windows? + /mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM + end + + def fu_copy_stream0(src, dest, blksize) #:nodoc: + # FIXME: readpartial? + while s = src.read(blksize) + dest.write s + end + end + + def fu_stream_blksize(*streams) + streams.each do |s| + next unless s.respond_to?(:stat) + size = fu_blksize(s.stat) + return size if size + end + fu_default_blksize() + end + + def fu_blksize(st) + s = st.blksize + return nil unless s + return nil if s == 0 + s + end + + def fu_default_blksize + 1024 + end + end + + include StreamUtils_ + extend StreamUtils_ + + class Entry_ #:nodoc: internal use only + include StreamUtils_ + + def initialize(a, b = nil, deref = false) + @prefix = @rel = @path = nil + if b + @prefix = a + @rel = b + else + @path = a + end + @deref = deref + @stat = nil + @lstat = nil + end + + def inspect + "\#<#{self.class} #{path()}>" + end + + def path + if @path + @path.to_str + else + join(@prefix, @rel) + end + end + + def prefix + @prefix || @path + end + + def rel + @rel + end + + def dereference? + @deref + end + + def exist? + lstat! ? true : false + end + + def file? + s = lstat! + s and s.file? + end + + def directory? + s = lstat! + s and s.directory? + end + + def symlink? + s = lstat! + s and s.symlink? + end + + def chardev? + s = lstat! + s and s.chardev? + end + + def blockdev? + s = lstat! + s and s.blockdev? + end + + def socket? + s = lstat! + s and s.socket? + end + + def pipe? + s = lstat! + s and s.pipe? + end + + S_IF_DOOR = 0xD000 + + def door? + s = lstat! + s and (s.mode & 0xF000 == S_IF_DOOR) + end + + def entries + Dir.entries(path())\ + .reject {|n| n == '.' or n == '..' }\ + .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) } + end + + def stat + return @stat if @stat + if lstat() and lstat().symlink? + @stat = File.stat(path()) + else + @stat = lstat() + end + @stat + end + + def stat! + return @stat if @stat + if lstat! and lstat!.symlink? + @stat = File.stat(path()) + else + @stat = lstat! + end + @stat + rescue SystemCallError + nil + end + + def lstat + if dereference? + @lstat ||= File.stat(path()) + else + @lstat ||= File.lstat(path()) + end + end + + def lstat! + lstat() + rescue SystemCallError + nil + end + + def chmod(mode) + if symlink? + File.lchmod mode, path() if have_lchmod? + else + File.chmod mode, path() + end + end + + def chown(uid, gid) + if symlink? + File.lchown uid, gid, path() if have_lchown? + else + File.chown uid, gid, path() + end + end + + def copy(dest) + case + when file? + copy_file dest + when directory? + begin + Dir.mkdir dest + rescue + raise unless File.directory?(dest) + end + when symlink? + File.symlink File.readlink(path()), dest + when chardev? + raise "cannot handle device file" unless File.respond_to?(:mknod) + mknod dest, ?c, 0666, lstat().rdev + when blockdev? + raise "cannot handle device file" unless File.respond_to?(:mknod) + mknod dest, ?b, 0666, lstat().rdev + when socket? + raise "cannot handle socket" unless File.respond_to?(:mknod) + mknod dest, nil, lstat().mode, 0 + when pipe? + raise "cannot handle FIFO" unless File.respond_to?(:mkfifo) + mkfifo dest, 0666 + when door? + raise "cannot handle door: #{path()}" + else + raise "unknown file type: #{path()}" + end + end + + def copy_file(dest) + st = stat() + File.open(path(), 'rb') {|r| + File.open(dest, 'wb', st.mode) {|w| + fu_copy_stream0 r, w, (fu_blksize(st) || fu_default_blksize()) + } + } + end + + def copy_metadata(path) + st = lstat() + File.utime st.atime, st.mtime, path + begin + File.chown st.uid, st.gid, path + rescue Errno::EPERM + # clear setuid/setgid + File.chmod st.mode & 01777, path + else + File.chmod st.mode, path + end + end + + def remove + if directory? + remove_dir1 + else + remove_file + end + end + + def remove_dir1 + platform_support { + Dir.rmdir path().sub(%r, '') + } + end + + def remove_file + platform_support { + File.unlink path + } + end + + def platform_support + return yield unless fu_windows? + first_time_p = true + begin + yield + rescue Errno::ENOENT + raise + rescue => err + if first_time_p + first_time_p = false + begin + File.chmod 0700, path() # Windows does not have symlink + retry + rescue SystemCallError + end + end + raise err + end + end + + def preorder_traverse + stack = [self] + while ent = stack.pop + yield ent + stack.concat ent.entries.reverse if ent.directory? + end + end + + alias traverse preorder_traverse + + def postorder_traverse + if directory? + entries().each do |ent| + ent.postorder_traverse do |e| + yield e + end + end + end + yield self + end + + private + + $fileutils_rb_have_lchmod = nil + + def have_lchmod? + # This is not MT-safe, but it does not matter. + if $fileutils_rb_have_lchmod == nil + $fileutils_rb_have_lchmod = check_have_lchmod? + end + $fileutils_rb_have_lchmod + end + + def check_have_lchmod? + return false unless File.respond_to?(:lchmod) + File.lchmod 0 + return true + rescue NotImplementedError + return false + end + + $fileutils_rb_have_lchown = nil + + def have_lchown? + # This is not MT-safe, but it does not matter. + if $fileutils_rb_have_lchown == nil + $fileutils_rb_have_lchown = check_have_lchown? + end + $fileutils_rb_have_lchown + end + + def check_have_lchown? + return false unless File.respond_to?(:lchown) + File.lchown nil, nil + return true + rescue NotImplementedError + return false + end + + def join(dir, base) + return dir.to_str if not base or base == '.' + return base.to_str if not dir or dir == '.' + File.join(dir, base) + end + end # class Entry_ + + def fu_list(arg) #:nodoc: + [arg].flatten.map {|path| path.to_str } + end + private_module_function :fu_list + + def fu_each_src_dest(src, dest) #:nodoc: + fu_each_src_dest0(src, dest) do |s, d| + raise ArgumentError, "same file: #{s} and #{d}" if fu_same?(s, d) + yield s, d + end + end + private_module_function :fu_each_src_dest + + def fu_each_src_dest0(src, dest) #:nodoc: + if src.is_a?(Array) + src.each do |s| + s = s.to_str + yield s, File.join(dest, File.basename(s)) + end + else + src = src.to_str + if File.directory?(dest) + yield src, File.join(dest, File.basename(src)) + else + yield src, dest.to_str + end + end + end + private_module_function :fu_each_src_dest0 + + def fu_same?(a, b) #:nodoc: + if fu_have_st_ino? + st1 = File.stat(a) + st2 = File.stat(b) + st1.dev == st2.dev and st1.ino == st2.ino + else + File.expand_path(a) == File.expand_path(b) + end + rescue Errno::ENOENT + return false + end + private_module_function :fu_same? + + def fu_have_st_ino? #:nodoc: + not fu_windows? + end + private_module_function :fu_have_st_ino? + + def fu_check_options(options, optdecl) #:nodoc: + h = options.dup + optdecl.each do |opt| + h.delete opt + end + raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty? + end + private_module_function :fu_check_options + + def fu_update_option(args, new) #:nodoc: + if args.last.is_a?(Hash) + args[-1] = args.last.dup.update(new) + else + args.push new + end + args + end + private_module_function :fu_update_option + + @fileutils_output = $stderr + @fileutils_label = '' + + def fu_output_message(msg) #:nodoc: + @fileutils_output ||= $stderr + @fileutils_label ||= '' + @fileutils_output.puts @fileutils_label + msg + end + private_module_function :fu_output_message + + # + # Returns an Array of method names which have any options. + # + # p FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...] + # + def FileUtils.commands + OPT_TABLE.keys + end + + # + # Returns an Array of option names. + # + # p FileUtils.options #=> ["noop", "force", "verbose", "preserve", "mode"] + # + def FileUtils.options + OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s } + end + + # + # Returns true if the method +mid+ have an option +opt+. + # + # p FileUtils.have_option?(:cp, :noop) #=> true + # p FileUtils.have_option?(:rm, :force) #=> true + # p FileUtils.have_option?(:rm, :perserve) #=> false + # + def FileUtils.have_option?(mid, opt) + li = OPT_TABLE[mid.to_s] or raise ArgumentError, "no such method: #{mid}" + li.include?(opt) + end + + # + # Returns an Array of option names of the method +mid+. + # + # p FileUtils.options(:rm) #=> ["noop", "verbose", "force"] + # + def FileUtils.options_of(mid) + OPT_TABLE[mid.to_s].map {|sym| sym.to_s } + end + + # + # Returns an Array of method names which have the option +opt+. + # + # p FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"] + # + def FileUtils.collect_method(opt) + OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) } + end + + METHODS = singleton_methods() - %w( private_module_function + commands options have_option? options_of collect_method ) + + # + # This module has all methods of FileUtils module, but it outputs messages + # before acting. This equates to passing the :verbose flag to + # methods in FileUtils. + # + module Verbose + include FileUtils + @fileutils_output = $stderr + @fileutils_label = '' + ::FileUtils.collect_method(:verbose).each do |name| + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args) + super(*fu_update_option(args, :verbose => true)) + end + private :#{name} + EOS + end + extend self + class << self + ::FileUtils::METHODS.each do |m| + public m + end + end + end + + # + # This module has all methods of FileUtils module, but never changes + # files/directories. This equates to passing the :noop flag + # to methods in FileUtils. + # + module NoWrite + include FileUtils + @fileutils_output = $stderr + @fileutils_label = '' + ::FileUtils.collect_method(:noop).each do |name| + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args) + super(*fu_update_option(args, :noop => true)) + end + private :#{name} + EOS + end + extend self + class << self + ::FileUtils::METHODS.each do |m| + public m + end + end + end + + # + # This module has all methods of FileUtils module, but never changes + # files/directories, with printing message before acting. + # This equates to passing the :noop and :verbose flag + # to methods in FileUtils. + # + module DryRun + include FileUtils + @fileutils_output = $stderr + @fileutils_label = '' + ::FileUtils.collect_method(:noop).each do |name| + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args) + super(*fu_update_option(args, :noop => true, :verbose => true)) + end + private :#{name} + EOS + end + extend self + class << self + ::FileUtils::METHODS.each do |m| + public m + end + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/finalize.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/finalize.rb new file mode 100644 index 00000000..9b6b302c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/finalize.rb @@ -0,0 +1,193 @@ +#-- +# finalizer.rb - +# $Release Version: 0.3$ +# $Revision: 1.4 $ +# $Date: 1998/02/27 05:34:33 $ +# by Keiju ISHITSUKA +#++ +# +# Usage: +# +# add dependency R_method(obj, dependant) +# add(obj, dependant, method = :finalize, *opt) +# add_dependency(obj, dependant, method = :finalize, *opt) +# +# delete dependency R_method(obj, dependant) +# delete(obj_or_id, dependant, method = :finalize) +# delete_dependency(obj_or_id, dependant, method = :finalize) +# +# delete dependency R_*(obj, dependant) +# delete_all_dependency(obj_or_id, dependant) +# +# delete dependency R_method(*, dependant) +# delete_by_dependant(dependant, method = :finalize) +# +# delete dependency R_*(*, dependant) +# delete_all_by_dependant(dependant) +# +# delete all dependency R_*(*, *) +# delete_all +# +# finalize the dependant connected by dependency R_method(obj, dependtant). +# finalize(obj_or_id, dependant, method = :finalize) +# finalize_dependency(obj_or_id, dependant, method = :finalize) +# +# finalize all dependants connected by dependency R_*(obj, dependtant). +# finalize_all_dependency(obj_or_id, dependant) +# +# finalize the dependant connected by dependency R_method(*, dependtant). +# finalize_by_dependant(dependant, method = :finalize) +# +# finalize all dependants connected by dependency R_*(*, dependant). +# finalize_all_by_dependant(dependant) +# +# finalize all dependency registered to the Finalizer. +# finalize_all +# +# stop invoking Finalizer on GC. +# safe{..} +# + +module Finalizer + RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-' + + class < [[dependant, method, *opt], ...], ...} + + # add dependency R_method(obj, dependant) + def add_dependency(obj, dependant, method = :finalize, *opt) + ObjectSpace.call_finalizer(obj) + method = method.intern unless method.kind_of?(Integer) + assoc = [dependant, method].concat(opt) + if dep = @dependency[obj.object_id] + dep.push assoc + else + @dependency[obj.object_id] = [assoc] + end + end + alias add add_dependency + + # delete dependency R_method(obj, dependant) + def delete_dependency(id, dependant, method = :finalize) + id = id.object_id unless id.kind_of?(Integer) + method = method.intern unless method.kind_of?(Integer) + for assoc in @dependency[id] + assoc.delete_if do + |d, m, *o| + d == dependant && m == method + end + @dependency.delete(id) if assoc.empty? + end + end + alias delete delete_dependency + + # delete dependency R_*(obj, dependant) + def delete_all_dependency(id, dependant) + id = id.object_id unless id.kind_of?(Integer) + method = method.intern unless method.kind_of?(Integer) + for assoc in @dependency[id] + assoc.delete_if do + |d, m, *o| + d == dependant + end + @dependency.delete(id) if assoc.empty? + end + end + + # delete dependency R_method(*, dependant) + def delete_by_dependant(dependant, method = :finalize) + method = method.intern unless method.kind_of?(Integer) + for id in @dependency.keys + delete(id, dependant, method) + end + end + + # delete dependency R_*(*, dependant) + def delete_all_by_dependant(dependant) + for id in @dependency.keys + delete_all_dependency(id, dependant) + end + end + + # finalize the depandant connected by dependency R_method(obj, dependtant) + def finalize_dependency(id, dependant, method = :finalize) + id = id.object_id unless id.kind_of?(Integer) + method = method.intern unless method.kind_of?(Integer) + for assocs in @dependency[id] + assocs.delete_if do + |d, m, *o| + d.send(m, id, *o) if ret = d == dependant && m == method + ret + end + @dependency.delete(id) if assoc.empty? + end + end + alias finalize finalize_dependency + + # finalize all dependants connected by dependency R_*(obj, dependtant) + def finalize_all_dependency(id, dependant) + id = id.object_id unless id.kind_of?(Integer) + method = method.intern unless method.kind_of?(Integer) + for assoc in @dependency[id] + assoc.delete_if do + |d, m, *o| + d.send(m, id, *o) if ret = d == dependant + end + @dependency.delete(id) if assoc.empty? + end + end + + # finalize the dependant connected by dependency R_method(*, dependtant) + def finalize_by_dependant(dependant, method = :finalize) + method = method.intern unless method.kind_of?(Integer) + for id in @dependency.keys + finalize(id, dependant, method) + end + end + + # finalize all dependants connected by dependency R_*(*, dependtant) + def finalize_all_by_dependant(dependant) + for id in @dependency.keys + finalize_all_dependency(id, dependant) + end + end + + # finalize all dependants registered to the Finalizer. + def finalize_all + for id, assocs in @dependency + for dependant, method, *opt in assocs + dependant.send(method, id, *opt) + end + assocs.clear + end + end + + # method to call finalize_* safely. + def safe + old_status = Thread.critical + Thread.critical = true + ObjectSpace.remove_finalizer(@proc) + begin + yield + ensure + ObjectSpace.add_finalizer(@proc) + Thread.critical = old_status + end + end + + private + + # registering function to ObjectSpace#add_finalizer + def final_of(id) + if assocs = @dependency.delete(id) + for dependant, method, *opt in assocs + dependant.send(method, id, *opt) + end + end + end + + end + @dependency = Hash.new + @proc = proc{|id| final_of(id)} + ObjectSpace.add_finalizer(@proc) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/find.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/find.rb new file mode 100644 index 00000000..0d22dd62 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/find.rb @@ -0,0 +1,79 @@ +# +# find.rb: the Find module for processing all files under a given directory. +# + +# +# The +Find+ module supports the top-down traversal of a set of file paths. +# +# For example, to total the size of all files under your home directory, +# ignoring anything in a "dot" directory (e.g. $HOME/.ssh): +# +# require 'find' +# +# total_size = 0 +# +# Find.find(ENV["HOME"]) do |path| +# if FileTest.directory?(path) +# if File.basename(path)[0] == ?. +# Find.prune # Don't look any further into this directory. +# else +# next +# end +# else +# total_size += FileTest.size(path) +# end +# end +# +module Find + + # + # Calls the associated block with the name of every file and directory listed + # as arguments, then recursively on their subdirectories, and so on. + # + # See the +Find+ module documentation for an example. + # + def find(*paths) # :yield: path + paths.collect!{|d| d.dup} + while file = paths.shift + catch(:prune) do + yield file.dup.taint + next unless File.exist? file + begin + if File.lstat(file).directory? then + d = Dir.open(file) + begin + for f in d + next if f == "." or f == ".." + if File::ALT_SEPARATOR and file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then + f = file + f + elsif file == "/" then + f = "/" + f + else + f = File.join(file, f) + end + paths.unshift f.untaint + end + ensure + d.close + end + end + rescue Errno::ENOENT, Errno::EACCES + end + end + end + end + + # + # Skips the current file or directory, restarting the loop with the next + # entry. If the current file is a directory, that directory will not be + # recursively entered. Meaningful only within the block associated with + # Find::find. + # + # See the +Find+ module documentation for an example. + # + def prune + throw :prune + end + + module_function :find, :prune +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/forwardable.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/forwardable.rb new file mode 100644 index 00000000..e2a2727d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/forwardable.rb @@ -0,0 +1,218 @@ +# = forwardable - Support for the Delegation Pattern +# +# $Release Version: 1.1$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# Documentation by James Edward Gray II and Gavin Sinclair +# +# == Introduction +# +# This library allows you delegate method calls to an object, on a method by +# method basis. You can use Forwardable to setup this delegation at the class +# level, or SingleForwardable to handle it at the object level. +# +# == Notes +# +# Be advised, RDoc will not detect delegated methods. +# +# forwardable.rb provides single-method delegation via the +# def_delegator() and def_delegators() methods. For full-class +# delegation via DelegateClass(), see delegate.rb. +# +# == Examples +# +# === Forwardable +# +# Forwardable makes building a new class based on existing work, with a proper +# interface, almost trivial. We want to rely on what has come before obviously, +# but with delegation we can take just the methods we need and even rename them +# as appropriate. In many cases this is preferable to inheritance, which gives +# us the entire old interface, even if much of it isn't needed. +# +# class Queue +# extend Forwardable +# +# def initialize +# @q = [ ] # prepare delegate object +# end +# +# # setup prefered interface, enq() and deq()... +# def_delegator :@q, :push, :enq +# def_delegator :@q, :shift, :deq +# +# # support some general Array methods that fit Queues well +# def_delegators :@q, :clear, :first, :push, :shift, :size +# end +# +# q = Queue.new +# q.enq 1, 2, 3, 4, 5 +# q.push 6 +# +# q.shift # => 1 +# while q.size > 0 +# puts q.deq +# end +# +# q.enq "Ruby", "Perl", "Python" +# puts q.first +# q.clear +# puts q.first +# +# Prints: +# +# 2 +# 3 +# 4 +# 5 +# 6 +# Ruby +# nil +# +# === SingleForwardable +# +# printer = String.new +# printer.extend SingleForwardable # prepare object for delegation +# printer.def_delegator "STDOUT", "puts" # add delegation for STDOUT.puts() +# printer.puts "Howdy!" +# +# Prints: +# +# Howdy! + +# +# The Forwardable module provides delegation of specified +# methods to a designated object, using the methods #def_delegator +# and #def_delegators. +# +# For example, say you have a class RecordCollection which +# contains an array @records. You could provide the lookup method +# #record_number(), which simply calls #[] on the @records +# array, like this: +# +# class RecordCollection +# extend Forwardable +# def_delegator :@records, :[], :record_number +# end +# +# Further, if you wish to provide the methods #size, #<<, and #map, +# all of which delegate to @records, this is how you can do it: +# +# class RecordCollection +# # extend Forwardable, but we did that above +# def_delegators :@records, :size, :<<, :map +# end +# +# Also see the example at forwardable.rb. +# +module Forwardable + + @debug = nil + class<to/from. + # + def syscopy(from, to) + to = catname(from, to) + + fmode = stat(from).mode + tpath = to + not_exist = !exist?(tpath) + + from = open(from, "rb") + to = open(to, "wb") + + begin + while true + to.syswrite from.sysread(BUFSIZE) + end + rescue EOFError + ret = true + rescue + ret = false + ensure + to.close + from.close + end + chmod(fmode, tpath) if not_exist + ret + end + + # + # Copies a file +from+ to +to+ using #syscopy. If +to+ is a directory, + # copies +from+ to to/from. If +verbose+ is true, from -> to + # is printed. + # + def copy(from, to, verbose = false) + $stderr.print from, " -> ", catname(from, to), "\n" if verbose + syscopy from, to + end + + alias cp copy + + # + # Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory, + # copies from +from+ to to/from. If +verbose+ is true, from -> + # to is printed. + # + def move(from, to, verbose = false) + to = catname(from, to) + $stderr.print from, " -> ", to, "\n" if verbose + + if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and file? to + unlink to + end + fstat = stat(from) + begin + rename from, to + rescue + begin + symlink readlink(from), to and unlink from + rescue + from_stat = stat(from) + syscopy from, to and unlink from + utime(from_stat.atime, from_stat.mtime, to) + begin + chown(fstat.uid, fstat.gid, to) + rescue + end + end + end + end + + alias mv move + + # + # Returns +true+ if and only if the contents of files +from+ and +to+ are + # identical. If +verbose+ is +true+, from <=> to is printed. + # + def compare(from, to, verbose = false) + $stderr.print from, " <=> ", to, "\n" if verbose + + return false if stat(from).size != stat(to).size + + from = open(from, "rb") + to = open(to, "rb") + + ret = false + fr = tr = '' + + begin + while fr == tr + fr = from.read(BUFSIZE) + if fr + tr = to.read(fr.size) + else + ret = to.read(BUFSIZE) + ret = !ret || ret.length == 0 + break + end + end + rescue + ret = false + ensure + to.close + from.close + end + ret + end + + alias cmp compare + + # + # Removes a list of files. Each parameter should be the name of the file to + # delete. If the last parameter isn't a String, verbose mode will be enabled. + # Returns the number of files deleted. + # + def safe_unlink(*files) + verbose = if files[-1].is_a? String then false else files.pop end + files.each do |file| + begin + unlink file + $stderr.print "removing ", file, "\n" if verbose + rescue Errno::EACCES # for Windows + continue if symlink? file + begin + mode = stat(file).mode + o_chmod mode | 0200, file + unlink file + $stderr.print "removing ", file, "\n" if verbose + rescue + o_chmod mode, file rescue nil + end + rescue + end + end + end + + alias rm_f safe_unlink + + # + # Creates a directory and all its parent directories. + # For example, + # + # File.makedirs '/usr/lib/ruby' + # + # causes the following directories to be made, if they do not exist. + # * /usr + # * /usr/lib + # * /usr/lib/ruby + # + # You can pass several directories, each as a parameter. If the last + # parameter isn't a String, verbose mode will be enabled. + # + def makedirs(*dirs) + verbose = if dirs[-1].is_a? String then false else dirs.pop end + mode = 0755 + for dir in dirs + parent = dirname(dir) + next if parent == dir or directory? dir + makedirs parent unless directory? parent + $stderr.print "mkdir ", dir, "\n" if verbose + if basename(dir) != "" + begin + Dir.mkdir dir, mode + rescue SystemCallError + raise unless directory? dir + end + end + end + end + + alias mkpath makedirs + + alias o_chmod chmod + + vsave, $VERBOSE = $VERBOSE, false + + # + # Changes permission bits on +files+ to the bit pattern represented + # by +mode+. If the last parameter isn't a String, verbose mode will + # be enabled. + # + # File.chmod 0755, 'somecommand' + # File.chmod 0644, 'my.rb', 'your.rb', true + # + def chmod(mode, *files) + verbose = if files[-1].is_a? String then false else files.pop end + $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose + o_chmod mode, *files + end + $VERBOSE = vsave + + # + # If +src+ is not the same as +dest+, copies it and changes the permission + # mode to +mode+. If +dest+ is a directory, destination is dest/src. + # If +mode+ is not set, default is used. If +verbose+ is set to true, the + # name of each file copied will be printed. + # + def install(from, to, mode = nil, verbose = false) + to = catname(from, to) + unless exist? to and cmp from, to + safe_unlink to if exist? to + cp from, to, verbose + chmod mode, to, verbose if mode + end + end + +end + +# vi:set sw=2: diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/generator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/generator.rb new file mode 100644 index 00000000..fcc2c64a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/generator.rb @@ -0,0 +1,380 @@ +#!/usr/bin/env ruby +#-- +# $Idaemons: /home/cvs/rb/generator.rb,v 1.8 2001/10/03 08:54:32 knu Exp $ +# $RoughId: generator.rb,v 1.10 2003/10/14 19:36:58 knu Exp $ +# $Id: generator.rb 11708 2007-02-12 23:01:19Z shyouhei $ +#++ +# +# = generator.rb: convert an internal iterator to an external one +# +# Copyright (c) 2001,2003 Akinori MUSHA +# +# All rights reserved. You can redistribute and/or modify it under +# the same terms as Ruby. +# +# == Overview +# +# This library provides the Generator class, which converts an +# internal iterator (i.e. an Enumerable object) to an external +# iterator. In that form, you can roll many iterators independently. +# +# The SyncEnumerator class, which is implemented using Generator, +# makes it easy to roll many Enumerable objects synchronously. +# +# See the respective classes for examples of usage. + + +# +# Generator converts an internal iterator (i.e. an Enumerable object) +# to an external iterator. +# +# Note that it is not very fast since it is implemented using +# continuations, which are currently slow. +# +# == Example +# +# require 'generator' +# +# # Generator from an Enumerable object +# g = Generator.new(['A', 'B', 'C', 'Z']) +# +# while g.next? +# puts g.next +# end +# +# # Generator from a block +# g = Generator.new { |g| +# for i in 'A'..'C' +# g.yield i +# end +# +# g.yield 'Z' +# } +# +# # The same result as above +# while g.next? +# puts g.next +# end +# +class Generator + include Enumerable + + # Creates a new generator either from an Enumerable object or from a + # block. + # + # In the former, block is ignored even if given. + # + # In the latter, the given block is called with the generator + # itself, and expected to call the +yield+ method for each element. + def initialize(enum = nil, &block) + if enum + @block = proc { |g| + enum.each { |x| g.yield x } + } + else + @block = block + end + + @index = 0 + @queue = [] + @cont_next = @cont_yield = @cont_endp = nil + + if @cont_next = callcc { |c| c } + @block.call(self) + + @cont_endp.call(nil) if @cont_endp + end + + self + end + + # Yields an element to the generator. + def yield(value) + if @cont_yield = callcc { |c| c } + @queue << value + @cont_next.call(nil) + end + + self + end + + # Returns true if the generator has reached the end. + def end?() + if @cont_endp = callcc { |c| c } + @cont_yield.nil? && @queue.empty? + else + @queue.empty? + end + end + + # Returns true if the generator has not reached the end yet. + def next?() + !end? + end + + # Returns the current index (position) counting from zero. + def index() + @index + end + + # Returns the current index (position) counting from zero. + def pos() + @index + end + + # Returns the element at the current position and moves forward. + def next() + if end? + raise EOFError, "no more elements available" + end + + if @cont_next = callcc { |c| c } + @cont_yield.call(nil) if @cont_yield + end + + @index += 1 + + @queue.shift + end + + # Returns the element at the current position. + def current() + if @queue.empty? + raise EOFError, "no more elements available" + end + + @queue.first + end + + # Rewinds the generator. + def rewind() + initialize(nil, &@block) if @index.nonzero? + + self + end + + # Rewinds the generator and enumerates the elements. + def each + rewind + + until end? + yield self.next + end + + self + end +end + +# +# SyncEnumerator creates an Enumerable object from multiple Enumerable +# objects and enumerates them synchronously. +# +# == Example +# +# require 'generator' +# +# s = SyncEnumerator.new([1,2,3], ['a', 'b', 'c']) +# +# # Yields [1, 'a'], [2, 'b'], and [3,'c'] +# s.each { |row| puts row.join(', ') } +# +class SyncEnumerator + include Enumerable + + # Creates a new SyncEnumerator which enumerates rows of given + # Enumerable objects. + def initialize(*enums) + @gens = enums.map { |e| Generator.new(e) } + end + + # Returns the number of enumerated Enumerable objects, i.e. the size + # of each row. + def size + @gens.size + end + + # Returns the number of enumerated Enumerable objects, i.e. the size + # of each row. + def length + @gens.length + end + + # Returns true if the given nth Enumerable object has reached the + # end. If no argument is given, returns true if any of the + # Enumerable objects has reached the end. + def end?(i = nil) + if i.nil? + @gens.detect { |g| g.end? } ? true : false + else + @gens[i].end? + end + end + + # Enumerates rows of the Enumerable objects. + def each + @gens.each { |g| g.rewind } + + loop do + count = 0 + + ret = @gens.map { |g| + if g.end? + count += 1 + nil + else + g.next + end + } + + if count == @gens.size + break + end + + yield ret + end + + self + end +end + +if $0 == __FILE__ + eval DATA.read, nil, $0, __LINE__+4 +end + +__END__ + +require 'test/unit' + +class TC_Generator < Test::Unit::TestCase + def test_block1 + g = Generator.new { |g| + # no yield's + } + + assert_equal(0, g.pos) + assert_raises(EOFError) { g.current } + end + + def test_block2 + g = Generator.new { |g| + for i in 'A'..'C' + g.yield i + end + + g.yield 'Z' + } + + assert_equal(0, g.pos) + assert_equal('A', g.current) + + assert_equal(true, g.next?) + assert_equal(0, g.pos) + assert_equal('A', g.current) + assert_equal(0, g.pos) + assert_equal('A', g.next) + + assert_equal(1, g.pos) + assert_equal(true, g.next?) + assert_equal(1, g.pos) + assert_equal('B', g.current) + assert_equal(1, g.pos) + assert_equal('B', g.next) + + assert_equal(g, g.rewind) + + assert_equal(0, g.pos) + assert_equal('A', g.current) + + assert_equal(true, g.next?) + assert_equal(0, g.pos) + assert_equal('A', g.current) + assert_equal(0, g.pos) + assert_equal('A', g.next) + + assert_equal(1, g.pos) + assert_equal(true, g.next?) + assert_equal(1, g.pos) + assert_equal('B', g.current) + assert_equal(1, g.pos) + assert_equal('B', g.next) + + assert_equal(2, g.pos) + assert_equal(true, g.next?) + assert_equal(2, g.pos) + assert_equal('C', g.current) + assert_equal(2, g.pos) + assert_equal('C', g.next) + + assert_equal(3, g.pos) + assert_equal(true, g.next?) + assert_equal(3, g.pos) + assert_equal('Z', g.current) + assert_equal(3, g.pos) + assert_equal('Z', g.next) + + assert_equal(4, g.pos) + assert_equal(false, g.next?) + assert_raises(EOFError) { g.next } + end + + def test_each + a = [5, 6, 7, 8, 9] + + g = Generator.new(a) + + i = 0 + + g.each { |x| + assert_equal(a[i], x) + + i += 1 + + break if i == 3 + } + + assert_equal(3, i) + + i = 0 + + g.each { |x| + assert_equal(a[i], x) + + i += 1 + } + + assert_equal(5, i) + end +end + +class TC_SyncEnumerator < Test::Unit::TestCase + def test_each + r = ['a'..'f', 1..10, 10..20] + ra = r.map { |x| x.to_a } + + a = (0...(ra.map {|x| x.size}.max)).map { |i| ra.map { |x| x[i] } } + + s = SyncEnumerator.new(*r) + + i = 0 + + s.each { |x| + assert_equal(a[i], x) + + i += 1 + + break if i == 3 + } + + assert_equal(3, i) + + i = 0 + + s.each { |x| + assert_equal(a[i], x) + + i += 1 + } + + assert_equal(a.size, i) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/getoptlong.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/getoptlong.rb new file mode 100644 index 00000000..4d004419 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/getoptlong.rb @@ -0,0 +1,621 @@ +# +# GetoptLong for Ruby +# +# Copyright (C) 1998, 1999, 2000 Motoyuki Kasahara. +# +# You may redistribute and/or modify this library under the same license +# terms as Ruby. +# +# See GetoptLong for documentation. +# +# Additional documents and the latest version of `getoptlong.rb' can be +# found at http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/ + +# The GetoptLong class allows you to parse command line options similarly to +# the GNU getopt_long() C library call. Note, however, that GetoptLong is a +# pure Ruby implementation. +# +# GetoptLong allows for POSIX-style options like --file as well +# as single letter options like -f +# +# The empty option -- (two minus symbols) is used to end option +# processing. This can be particularly important if options have optional +# arguments. +# +# Here is a simple example of usage: +# +# # == Synopsis +# # +# # hello: greets user, demonstrates command line parsing +# # +# # == Usage +# # +# # hello [OPTION] ... DIR +# # +# # -h, --help: +# # show help +# # +# # --repeat x, -n x: +# # repeat x times +# # +# # --name [name]: +# # greet user by name, if name not supplied default is John +# # +# # DIR: The directory in which to issue the greeting. +# +# require 'getoptlong' +# require 'rdoc/usage' +# +# opts = GetoptLong.new( +# [ '--help', '-h', GetoptLong::NO_ARGUMENT ], +# [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ], +# [ '--name', GetoptLong::OPTIONAL_ARGUMENT ] +# ) +# +# dir = nil +# name = nil +# repetitions = 1 +# opts.each do |opt, arg| +# case opt +# when '--help' +# RDoc::usage +# when '--repeat' +# repetitions = arg.to_i +# when '--name' +# if arg == '' +# name = 'John' +# else +# name = arg +# end +# end +# end +# +# if ARGV.length != 1 +# puts "Missing dir argument (try --help)" +# exit 0 +# end +# +# dir = ARGV.shift +# +# Dir.chdir(dir) +# for i in (1..repetitions) +# print "Hello" +# if name +# print ", #{name}" +# end +# puts +# end +# +# Example command line: +# +# hello -n 6 --name -- /tmp +# +class GetoptLong + # + # Orderings. + # + ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2] + + # + # Argument flags. + # + ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1, + OPTIONAL_ARGUMENT = 2] + + # + # Status codes. + # + STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2 + + # + # Error types. + # + class Error < StandardError; end + class AmbigousOption < Error; end + class NeedlessArgument < Error; end + class MissingArgument < Error; end + class InvalidOption < Error; end + + # + # Set up option processing. + # + # The options to support are passed to new() as an array of arrays. + # Each sub-array contains any number of String option names which carry + # the same meaning, and one of the following flags: + # + # GetoptLong::NO_ARGUMENT :: Option does not take an argument. + # + # GetoptLong::REQUIRED_ARGUMENT :: Option always takes an argument. + # + # GetoptLong::OPTIONAL_ARGUMENT :: Option may or may not take an argument. + # + # The first option name is considered to be the preferred (canonical) name. + # Other than that, the elements of each sub-array can be in any order. + # + def initialize(*arguments) + # + # Current ordering. + # + if ENV.include?('POSIXLY_CORRECT') + @ordering = REQUIRE_ORDER + else + @ordering = PERMUTE + end + + # + # Hash table of option names. + # Keys of the table are option names, and their values are canonical + # names of the options. + # + @canonical_names = Hash.new + + # + # Hash table of argument flags. + # Keys of the table are option names, and their values are argument + # flags of the options. + # + @argument_flags = Hash.new + + # + # Whether error messages are output to $deferr. + # + @quiet = FALSE + + # + # Status code. + # + @status = STATUS_YET + + # + # Error code. + # + @error = nil + + # + # Error message. + # + @error_message = nil + + # + # Rest of catenated short options. + # + @rest_singles = '' + + # + # List of non-option-arguments. + # Append them to ARGV when option processing is terminated. + # + @non_option_arguments = Array.new + + if 0 < arguments.length + set_options(*arguments) + end + end + + # + # Set the handling of the ordering of options and arguments. + # A RuntimeError is raised if option processing has already started. + # + # The supplied value must be a member of GetoptLong::ORDERINGS. It alters + # the processing of options as follows: + # + # REQUIRE_ORDER : + # + # Options are required to occur before non-options. + # + # Processing of options ends as soon as a word is encountered that has not + # been preceded by an appropriate option flag. + # + # For example, if -a and -b are options which do not take arguments, + # parsing command line arguments of '-a one -b two' would result in + # 'one', '-b', 'two' being left in ARGV, and only ('-a', '') being + # processed as an option/arg pair. + # + # This is the default ordering, if the environment variable + # POSIXLY_CORRECT is set. (This is for compatibility with GNU getopt_long.) + # + # PERMUTE : + # + # Options can occur anywhere in the command line parsed. This is the + # default behavior. + # + # Every sequence of words which can be interpreted as an option (with or + # without argument) is treated as an option; non-option words are skipped. + # + # For example, if -a does not require an argument and -b optionally takes + # an argument, parsing '-a one -b two three' would result in ('-a','') and + # ('-b', 'two') being processed as option/arg pairs, and 'one','three' + # being left in ARGV. + # + # If the ordering is set to PERMUTE but the environment variable + # POSIXLY_CORRECT is set, REQUIRE_ORDER is used instead. This is for + # compatibility with GNU getopt_long. + # + # RETURN_IN_ORDER : + # + # All words on the command line are processed as options. Words not + # preceded by a short or long option flag are passed as arguments + # with an option of '' (empty string). + # + # For example, if -a requires an argument but -b does not, a command line + # of '-a one -b two three' would result in option/arg pairs of ('-a', 'one') + # ('-b', ''), ('', 'two'), ('', 'three') being processed. + # + def ordering=(ordering) + # + # The method is failed if option processing has already started. + # + if @status != STATUS_YET + set_error(ArgumentError, "argument error") + raise RuntimeError, + "invoke ordering=, but option processing has already started" + end + + # + # Check ordering. + # + if !ORDERINGS.include?(ordering) + raise ArgumentError, "invalid ordering `#{ordering}'" + end + if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT') + @ordering = REQUIRE_ORDER + else + @ordering = ordering + end + end + + # + # Return ordering. + # + attr_reader :ordering + + # + # Set options. Takes the same argument as GetoptLong.new. + # + # Raises a RuntimeError if option processing has already started. + # + def set_options(*arguments) + # + # The method is failed if option processing has already started. + # + if @status != STATUS_YET + raise RuntimeError, + "invoke set_options, but option processing has already started" + end + + # + # Clear tables of option names and argument flags. + # + @canonical_names.clear + @argument_flags.clear + + arguments.each do |arg| + # + # Each argument must be an Array. + # + if !arg.is_a?(Array) + raise ArgumentError, "the option list contains non-Array argument" + end + + # + # Find an argument flag and it set to `argument_flag'. + # + argument_flag = nil + arg.each do |i| + if ARGUMENT_FLAGS.include?(i) + if argument_flag != nil + raise ArgumentError, "too many argument-flags" + end + argument_flag = i + end + end + raise ArgumentError, "no argument-flag" if argument_flag == nil + + canonical_name = nil + arg.each do |i| + # + # Check an option name. + # + next if i == argument_flag + begin + if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/ + raise ArgumentError, "an invalid option `#{i}'" + end + if (@canonical_names.include?(i)) + raise ArgumentError, "option redefined `#{i}'" + end + rescue + @canonical_names.clear + @argument_flags.clear + raise + end + + # + # Register the option (`i') to the `@canonical_names' and + # `@canonical_names' Hashes. + # + if canonical_name == nil + canonical_name = i + end + @canonical_names[i] = canonical_name + @argument_flags[i] = argument_flag + end + raise ArgumentError, "no option name" if canonical_name == nil + end + return self + end + + # + # Set/Unset `quiet' mode. + # + attr_writer :quiet + + # + # Return the flag of `quiet' mode. + # + attr_reader :quiet + + # + # `quiet?' is an alias of `quiet'. + # + alias quiet? quiet + + # + # Explicitly terminate option processing. + # + def terminate + return nil if @status == STATUS_TERMINATED + raise RuntimeError, "an error has occured" if @error != nil + + @status = STATUS_TERMINATED + @non_option_arguments.reverse_each do |argument| + ARGV.unshift(argument) + end + + @canonical_names = nil + @argument_flags = nil + @rest_singles = nil + @non_option_arguments = nil + + return self + end + + # + # Returns true if option processing has terminated, false otherwise. + # + def terminated? + return @status == STATUS_TERMINATED + end + + # + # Set an error (protected). + # + def set_error(type, message) + $deferr.print("#{$0}: #{message}\n") if !@quiet + + @error = type + @error_message = message + @canonical_names = nil + @argument_flags = nil + @rest_singles = nil + @non_option_arguments = nil + + raise type, message + end + protected :set_error + + # + # Examine whether an option processing is failed. + # + attr_reader :error + + # + # `error?' is an alias of `error'. + # + alias error? error + + # Return the appropriate error message in POSIX-defined format. + # If no error has occurred, returns nil. + # + def error_message + return @error_message + end + + # + # Get next option name and its argument, as an Array of two elements. + # + # The option name is always converted to the first (preferred) + # name given in the original options to GetoptLong.new. + # + # Example: ['--option', 'value'] + # + # Returns nil if the processing is complete (as determined by + # STATUS_TERMINATED). + # + def get + option_name, option_argument = nil, '' + + # + # Check status. + # + return nil if @error != nil + case @status + when STATUS_YET + @status = STATUS_STARTED + when STATUS_TERMINATED + return nil + end + + # + # Get next option argument. + # + if 0 < @rest_singles.length + argument = '-' + @rest_singles + elsif (ARGV.length == 0) + terminate + return nil + elsif @ordering == PERMUTE + while 0 < ARGV.length && ARGV[0] !~ /^-./ + @non_option_arguments.push(ARGV.shift) + end + if ARGV.length == 0 + terminate + return nil + end + argument = ARGV.shift + elsif @ordering == REQUIRE_ORDER + if (ARGV[0] !~ /^-./) + terminate + return nil + end + argument = ARGV.shift + else + argument = ARGV.shift + end + + # + # Check the special argument `--'. + # `--' indicates the end of the option list. + # + if argument == '--' && @rest_singles.length == 0 + terminate + return nil + end + + # + # Check for long and short options. + # + if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0 + # + # This is a long style option, which start with `--'. + # + pattern = $1 + if @canonical_names.include?(pattern) + option_name = pattern + else + # + # The option `option_name' is not registered in `@canonical_names'. + # It may be an abbreviated. + # + match_count = 0 + @canonical_names.each_key do |key| + if key.index(pattern) == 0 + option_name = key + match_count += 1 + end + end + if 2 <= match_count + set_error(AmbigousOption, "option `#{argument}' is ambiguous") + elsif match_count == 0 + set_error(InvalidOption, "unrecognized option `#{argument}'") + end + end + + # + # Check an argument to the option. + # + if @argument_flags[option_name] == REQUIRED_ARGUMENT + if argument =~ /=(.*)$/ + option_argument = $1 + elsif 0 < ARGV.length + option_argument = ARGV.shift + else + set_error(MissingArgument, + "option `#{argument}' requires an argument") + end + elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT + if argument =~ /=(.*)$/ + option_argument = $1 + elsif 0 < ARGV.length && ARGV[0] !~ /^-./ + option_argument = ARGV.shift + else + option_argument = '' + end + elsif argument =~ /=(.*)$/ + set_error(NeedlessArgument, + "option `#{option_name}' doesn't allow an argument") + end + + elsif argument =~ /^(-(.))(.*)/ + # + # This is a short style option, which start with `-' (not `--'). + # Short options may be catenated (e.g. `-l -g' is equivalent to + # `-lg'). + # + option_name, ch, @rest_singles = $1, $2, $3 + + if @canonical_names.include?(option_name) + # + # The option `option_name' is found in `@canonical_names'. + # Check its argument. + # + if @argument_flags[option_name] == REQUIRED_ARGUMENT + if 0 < @rest_singles.length + option_argument = @rest_singles + @rest_singles = '' + elsif 0 < ARGV.length + option_argument = ARGV.shift + else + # 1003.2 specifies the format of this message. + set_error(MissingArgument, "option requires an argument -- #{ch}") + end + elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT + if 0 < @rest_singles.length + option_argument = @rest_singles + @rest_singles = '' + elsif 0 < ARGV.length && ARGV[0] !~ /^-./ + option_argument = ARGV.shift + else + option_argument = '' + end + end + else + # + # This is an invalid option. + # 1003.2 specifies the format of this message. + # + if ENV.include?('POSIXLY_CORRECT') + set_error(InvalidOption, "illegal option -- #{ch}") + else + set_error(InvalidOption, "invalid option -- #{ch}") + end + end + else + # + # This is a non-option argument. + # Only RETURN_IN_ORDER falled into here. + # + return '', argument + end + + return @canonical_names[option_name], option_argument + end + + # + # `get_option' is an alias of `get'. + # + alias get_option get + + # Iterator version of `get'. + # + # The block is called repeatedly with two arguments: + # The first is the option name. + # The second is the argument which followed it (if any). + # Example: ('--opt', 'value') + # + # The option name is always converted to the first (preferred) + # name given in the original options to GetoptLong.new. + # + def each + loop do + option_name, option_argument = get_option + break if option_name == nil + yield option_name, option_argument + end + end + + # + # `each_option' is an alias of `each'. + # + alias each_option each +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/getopts.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/getopts.rb new file mode 100644 index 00000000..a857a42d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/getopts.rb @@ -0,0 +1,127 @@ +# +# getopts.rb - +# $Release Version: $ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Yasuo OHBA(SHL Japan Inc. Technology Dept.) +# +# -- +# this is obsolete; use getoptlong +# +# 2000-03-21 +# modified by Minero Aoki +# +# 2002-03-05 +# rewritten by Akinori MUSHA +# + +warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: getopts is deprecated after Ruby 1.8.1; use optparse instead" if caller[0] and $VERBOSE + +$RCS_ID=%q$Header$ + +# getopts is obsolete. Use GetoptLong. + +def getopts(single_options, *options) + boolopts = {} + valopts = {} + + # + # set defaults + # + single_options.scan(/.:?/) do |opt| + if opt.size == 1 + boolopts[opt] = false + else + valopts[opt[0, 1]] = nil + end + end if single_options + + options.each do |arg| + opt, val = arg.split(':', 2) + + if val + valopts[opt] = val.empty? ? nil : val + else + boolopts[opt] = false + end + end + + # + # scan + # + c = 0 + argv = ARGV + + while arg = argv.shift + case arg + when /\A--(.*)/ + if $1.empty? # xinit -- -bpp 24 + break + end + + opt, val = $1.split('=', 2) + + if opt.size == 1 + argv.unshift arg + return nil + elsif valopts.key? opt # imclean --src +trash + valopts[opt] = val || argv.shift or return nil + elsif boolopts.key? opt # ruby --verbose + boolopts[opt] = true + else + argv.unshift arg + return nil + end + + c += 1 + when /\A-(.+)/ + opts = $1 + + until opts.empty? + opt = opts.slice!(0, 1) + + if valopts.key? opt + val = opts + + if val.empty? # ruby -e 'p $:' + valopts[opt] = argv.shift or return nil + else # cc -ohello ... + valopts[opt] = val + end + + c += 1 + break + elsif boolopts.key? opt + boolopts[opt] = true # ruby -h + c += 1 + else + argv.unshift arg + return nil + end + end + else + argv.unshift arg + break + end + end + + # + # set + # + $OPT = {} + + boolopts.each do |opt, val| + $OPT[opt] = val + + sopt = opt.gsub(/[^A-Za-z0-9_]/, '_') + eval "$OPT_#{sopt} = val" + end + valopts.each do |opt, val| + $OPT[opt] = val + + sopt = opt.gsub(/[^A-Za-z0-9_]/, '_') + eval "$OPT_#{sopt} = val" + end + + c +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/gserver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/gserver.rb new file mode 100644 index 00000000..eb5f31b7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/gserver.rb @@ -0,0 +1,253 @@ +# +# Copyright (C) 2001 John W. Small All Rights Reserved +# +# Author:: John W. Small +# Documentation:: Gavin Sinclair +# Licence:: Freeware. +# +# See the class GServer for documentation. +# + +require "socket" +require "thread" + +# +# GServer implements a generic server, featuring thread pool management, +# simple logging, and multi-server management. See HttpServer in +# xmlrpc/httpserver.rb in the Ruby standard library for an example of +# GServer in action. +# +# Any kind of application-level server can be implemented using this class. +# It accepts multiple simultaneous connections from clients, up to an optional +# maximum number. Several _services_ (i.e. one service per TCP port) can be +# run simultaneously, and stopped at any time through the class method +# GServer.stop(port). All the threading issues are handled, saving +# you the effort. All events are optionally logged, but you can provide your +# own event handlers if you wish. +# +# === Example +# +# Using GServer is simple. Below we implement a simple time server, run it, +# query it, and shut it down. Try this code in +irb+: +# +# require 'gserver' +# +# # +# # A server that returns the time in seconds since 1970. +# # +# class TimeServer < GServer +# def initialize(port=10001, *args) +# super(port, *args) +# end +# def serve(io) +# io.puts(Time.now.to_i) +# end +# end +# +# # Run the server with logging enabled (it's a separate thread). +# server = TimeServer.new +# server.audit = true # Turn logging on. +# server.start +# +# # *** Now point your browser to http://localhost:10001 to see it working *** +# +# # See if it's still running. +# GServer.in_service?(10001) # -> true +# server.stopped? # -> false +# +# # Shut the server down gracefully. +# server.shutdown +# +# # Alternatively, stop it immediately. +# GServer.stop(10001) +# # or, of course, "server.stop". +# +# All the business of accepting connections and exception handling is taken +# care of. All we have to do is implement the method that actually serves the +# client. +# +# === Advanced +# +# As the example above shows, the way to use GServer is to subclass it to +# create a specific server, overriding the +serve+ method. You can override +# other methods as well if you wish, perhaps to collect statistics, or emit +# more detailed logging. +# +# connecting +# disconnecting +# starting +# stopping +# +# The above methods are only called if auditing is enabled. +# +# You can also override +log+ and +error+ if, for example, you wish to use a +# more sophisticated logging system. +# +class GServer + + DEFAULT_HOST = "127.0.0.1" + + def serve(io) + end + + @@services = {} # Hash of opened ports, i.e. services + @@servicesMutex = Mutex.new + + def GServer.stop(port, host = DEFAULT_HOST) + @@servicesMutex.synchronize { + @@services[host][port].stop + } + end + + def GServer.in_service?(port, host = DEFAULT_HOST) + @@services.has_key?(host) and + @@services[host].has_key?(port) + end + + def stop + @connectionsMutex.synchronize { + if @tcpServerThread + @tcpServerThread.raise "stop" + end + } + end + + def stopped? + @tcpServerThread == nil + end + + def shutdown + @shutdown = true + end + + def connections + @connections.size + end + + def join + @tcpServerThread.join if @tcpServerThread + end + + attr_reader :port, :host, :maxConnections + attr_accessor :stdlog, :audit, :debug + + def connecting(client) + addr = client.peeraddr + log("#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} " + + "#{addr[2]}<#{addr[3]}> connect") + true + end + + def disconnecting(clientPort) + log("#{self.class.to_s} #{@host}:#{@port} " + + "client:#{clientPort} disconnect") + end + + protected :connecting, :disconnecting + + def starting() + log("#{self.class.to_s} #{@host}:#{@port} start") + end + + def stopping() + log("#{self.class.to_s} #{@host}:#{@port} stop") + end + + protected :starting, :stopping + + def error(detail) + log(detail.backtrace.join("\n")) + end + + def log(msg) + if @stdlog + @stdlog.puts("[#{Time.new.ctime}] %s" % msg) + @stdlog.flush + end + end + + protected :error, :log + + def initialize(port, host = DEFAULT_HOST, maxConnections = 4, + stdlog = $stderr, audit = false, debug = false) + @tcpServerThread = nil + @port = port + @host = host + @maxConnections = maxConnections + @connections = [] + @connectionsMutex = Mutex.new + @connectionsCV = ConditionVariable.new + @stdlog = stdlog + @audit = audit + @debug = debug + end + + def start(maxConnections = -1) + raise "running" if !stopped? + @shutdown = false + @maxConnections = maxConnections if maxConnections > 0 + @@servicesMutex.synchronize { + if GServer.in_service?(@port,@host) + raise "Port already in use: #{host}:#{@port}!" + end + @tcpServer = TCPServer.new(@host,@port) + @port = @tcpServer.addr[1] + @@services[@host] = {} unless @@services.has_key?(@host) + @@services[@host][@port] = self; + } + @tcpServerThread = Thread.new { + begin + starting if @audit + while !@shutdown + @connectionsMutex.synchronize { + while @connections.size >= @maxConnections + @connectionsCV.wait(@connectionsMutex) + end + } + client = @tcpServer.accept + @connections << Thread.new(client) { |myClient| + begin + myPort = myClient.peeraddr[1] + serve(myClient) if !@audit or connecting(myClient) + rescue => detail + error(detail) if @debug + ensure + begin + myClient.close + rescue + end + @connectionsMutex.synchronize { + @connections.delete(Thread.current) + @connectionsCV.signal + } + disconnecting(myPort) if @audit + end + } + end + rescue => detail + error(detail) if @debug + ensure + begin + @tcpServer.close + rescue + end + if @shutdown + @connectionsMutex.synchronize { + while @connections.size > 0 + @connectionsCV.wait(@connectionsMutex) + end + } + else + @connections.each { |c| c.raise "stop" } + end + @tcpServerThread = nil + @@servicesMutex.synchronize { + @@services[@host].delete(@port) + } + stopping if @audit + end + } + self + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/importenv.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/importenv.rb new file mode 100644 index 00000000..8e1ba33b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/importenv.rb @@ -0,0 +1,33 @@ +# importenv.rb -- imports environment variables as global variables, Perlish ;( +# +# Usage: +# +# require 'importenv' +# p $USER +# $USER = "matz" +# p ENV["USER"] + +warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: importenv is deprecated after Ruby 1.8.1 (no replacement)" + +for k,v in ENV + next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k + eval <. +# All rights reserved. +# +# You can redistribute and/or modify it under the same terms as Ruby. +# +# $Id: ipaddr.rb 18047 2008-07-12 15:07:29Z shyouhei $ +# +# TODO: +# - scope_id support +require 'socket' + +unless Socket.const_defined? "AF_INET6" + class Socket + AF_INET6 = Object.new + end + + class << IPSocket + def valid_v4?(addr) + if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr + return $~.captures.all? {|i| i.to_i < 256} + end + return false + end + + def valid_v6?(addr) + # IPv6 (normal) + return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr + return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr + return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr + # IPv6 (IPv4 compat) + return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr && valid_v4?($') + return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($') + return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($') + + false + end + + def valid?(addr) + valid_v4?(addr) || valid_v6?(addr) + end + + alias getaddress_orig getaddress + def getaddress(s) + if valid?(s) + s + elsif /\A[-A-Za-z\d.]+\Z/ =~ s + getaddress_orig(s) + else + raise ArgumentError, "invalid address" + end + end + end +end + +# IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and +# IPv6 are supported. +# +# == Example +# +# require 'ipaddr' +# +# ipaddr1 = IPAddr.new "3ffe:505:2::1" +# +# p ipaddr1 #=> # +# +# p ipaddr1.to_s #=> "3ffe:505:2::1" +# +# ipaddr2 = ipaddr1.mask(48) #=> # +# +# p ipaddr2.to_s #=> "3ffe:505:2::" +# +# ipaddr3 = IPAddr.new "192.168.2.0/24" +# +# p ipaddr3 #=> # + +class IPAddr + + IN4MASK = 0xffffffff + IN6MASK = 0xffffffffffffffffffffffffffffffff + IN6FORMAT = (["%.4x"] * 8).join(':') + + # Returns the address family of this IP address. + attr :family + + # Creates a new ipaddr containing the given network byte ordered + # string form of an IP address. + def IPAddr::new_ntoh(addr) + return IPAddr.new(IPAddr::ntop(addr)) + end + + # Convert a network byte ordered string form of an IP address into + # human readable form. + def IPAddr::ntop(addr) + case addr.size + when 4 + s = addr.unpack('C4').join('.') + when 16 + s = IN6FORMAT % addr.unpack('n8') + else + raise ArgumentError, "unsupported address family" + end + return s + end + + # Returns a new ipaddr built by bitwise AND. + def &(other) + return self.clone.set(@addr & other.to_i) + end + + # Returns a new ipaddr built by bitwise OR. + def |(other) + return self.clone.set(@addr | other.to_i) + end + + # Returns a new ipaddr built by bitwise right-shift. + def >>(num) + return self.clone.set(@addr >> num) + end + + # Returns a new ipaddr built by bitwise left shift. + def <<(num) + return self.clone.set(addr_mask(@addr << num)) + end + + # Returns a new ipaddr built by bitwise negation. + def ~ + return self.clone.set(addr_mask(~@addr)) + end + + # Returns true if two ipaddr are equal. + def ==(other) + if other.kind_of?(IPAddr) && @family != other.family + return false + end + return (@addr == other.to_i) + end + + # Returns a new ipaddr built by masking IP address with the given + # prefixlen/netmask. (e.g. 8, 64, "255.255.255.0", etc.) + def mask(prefixlen) + return self.clone.mask!(prefixlen) + end + + # Returns true if the given ipaddr is in the range. + # + # e.g.: + # require 'ipaddr' + # net1 = IPAddr.new("192.168.2.0/24") + # p net1.include?(IPAddr.new("192.168.2.0")) #=> true + # p net1.include?(IPAddr.new("192.168.2.255")) #=> true + # p net1.include?(IPAddr.new("192.168.3.0")) #=> false + def include?(other) + if ipv4_mapped? + if (@mask_addr >> 32) != 0xffffffffffffffffffffffff + return false + end + mask_addr = (@mask_addr & IN4MASK) + addr = (@addr & IN4MASK) + family = Socket::AF_INET + else + mask_addr = @mask_addr + addr = @addr + family = @family + end + if other.kind_of?(IPAddr) + if other.ipv4_mapped? + other_addr = (other.to_i & IN4MASK) + other_family = Socket::AF_INET + else + other_addr = other.to_i + other_family = other.family + end + else # Not IPAddr - assume integer in same family as us + other_addr = other.to_i + other_family = family + end + + if family != other_family + return false + end + return ((addr & mask_addr) == (other_addr & mask_addr)) + end + alias === include? + + # Returns the integer representation of the ipaddr. + def to_i + return @addr + end + + # Returns a string containing the IP address representation. + def to_s + str = to_string + return str if ipv4? + + str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1') + loop do + break if str.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::') + break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':') + break if str.sub!(/\b0:0:0:0:0:0\b/, ':') + break if str.sub!(/\b0:0:0:0:0\b/, ':') + break if str.sub!(/\b0:0:0:0\b/, ':') + break if str.sub!(/\b0:0:0\b/, ':') + break if str.sub!(/\b0:0\b/, ':') + break + end + str.sub!(/:{3,}/, '::') + + if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\Z/i =~ str + str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256) + end + + str + end + + # Returns a string containing the IP address representation in + # canonical form. + def to_string + return _to_string(@addr) + end + + # Returns a network byte ordered string form of the IP address. + def hton + case @family + when Socket::AF_INET + return [@addr].pack('N') + when Socket::AF_INET6 + return (0..7).map { |i| + (@addr >> (112 - 16 * i)) & 0xffff + }.pack('n8') + else + raise "unsupported address family" + end + end + + # Returns true if the ipaddr is an IPv4 address. + def ipv4? + return @family == Socket::AF_INET + end + + # Returns true if the ipaddr is an IPv6 address. + def ipv6? + return @family == Socket::AF_INET6 + end + + # Returns true if the ipaddr is an IPv4-mapped IPv6 address. + def ipv4_mapped? + return ipv6? && (@addr >> 32) == 0xffff + end + + # Returns true if the ipaddr is an IPv4-compatible IPv6 address. + def ipv4_compat? + if !ipv6? || (@addr >> 32) != 0 + return false + end + a = (@addr & IN4MASK) + return a != 0 && a != 1 + end + + # Returns a new ipaddr built by converting the native IPv4 address + # into an IPv4-mapped IPv6 address. + def ipv4_mapped + if !ipv4? + raise ArgumentError, "not an IPv4 address" + end + return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6) + end + + # Returns a new ipaddr built by converting the native IPv4 address + # into an IPv4-compatible IPv6 address. + def ipv4_compat + if !ipv4? + raise ArgumentError, "not an IPv4 address" + end + return self.clone.set(@addr, Socket::AF_INET6) + end + + # Returns a new ipaddr built by converting the IPv6 address into a + # native IPv4 address. If the IP address is not an IPv4-mapped or + # IPv4-compatible IPv6 address, returns self. + def native + if !ipv4_mapped? && !ipv4_compat? + return self + end + return self.clone.set(@addr & IN4MASK, Socket::AF_INET) + end + + # Returns a string for DNS reverse lookup. It returns a string in + # RFC3172 form for an IPv6 address. + def reverse + case @family + when Socket::AF_INET + return _reverse + ".in-addr.arpa" + when Socket::AF_INET6 + return ip6_arpa + else + raise "unsupported address family" + end + end + + # Returns a string for DNS reverse lookup compatible with RFC3172. + def ip6_arpa + if !ipv6? + raise ArgumentError, "not an IPv6 address" + end + return _reverse + ".ip6.arpa" + end + + # Returns a string for DNS reverse lookup compatible with RFC1886. + def ip6_int + if !ipv6? + raise ArgumentError, "not an IPv6 address" + end + return _reverse + ".ip6.int" + end + + # Returns a string containing a human-readable representation of the + # ipaddr. ("#") + def inspect + case @family + when Socket::AF_INET + af = "IPv4" + when Socket::AF_INET6 + af = "IPv6" + else + raise "unsupported address family" + end + return sprintf("#<%s: %s:%s/%s>", self.class.name, + af, _to_string(@addr), _to_string(@mask_addr)) + end + + protected + + def set(addr, *family) + case family[0] ? family[0] : @family + when Socket::AF_INET + if addr < 0 || addr > IN4MASK + raise ArgumentError, "invalid address" + end + when Socket::AF_INET6 + if addr < 0 || addr > IN6MASK + raise ArgumentError, "invalid address" + end + else + raise ArgumentError, "unsupported address family" + end + @addr = addr + if family[0] + @family = family[0] + end + return self + end + + def mask!(mask) + if mask.kind_of?(String) + if mask =~ /^\d+$/ + prefixlen = mask.to_i + else + m = IPAddr.new(mask) + if m.family != @family + raise ArgumentError, "address family is not same" + end + @mask_addr = m.to_i + @addr &= @mask_addr + return self + end + else + prefixlen = mask + end + case @family + when Socket::AF_INET + if prefixlen < 0 || prefixlen > 32 + raise ArgumentError, "invalid length" + end + masklen = 32 - prefixlen + @mask_addr = ((IN4MASK >> masklen) << masklen) + when Socket::AF_INET6 + if prefixlen < 0 || prefixlen > 128 + raise ArgumentError, "invalid length" + end + masklen = 128 - prefixlen + @mask_addr = ((IN6MASK >> masklen) << masklen) + else + raise "unsupported address family" + end + @addr = ((@addr >> masklen) << masklen) + return self + end + + private + + # Creates a new ipaddr containing the given human readable form of + # an IP address. It also accepts `address/prefixlen' and + # `address/mask'. When prefixlen or mask is specified, it returns a + # masked ipaddr. IPv6 address may beenclosed with `[' and `]'. + # + # Although an address family is determined automatically from a + # specified address, you can specify an address family explicitly by + # the optional second argument. + def initialize(addr = '::', family = Socket::AF_UNSPEC) + if !addr.kind_of?(String) + if family != Socket::AF_INET6 && family != Socket::AF_INET + raise ArgumentError, "unsupported address family" + end + set(addr, family) + @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK + return + end + prefix, prefixlen = addr.split('/') + if prefix =~ /^\[(.*)\]$/i + prefix = $1 + family = Socket::AF_INET6 + end + # It seems AI_NUMERICHOST doesn't do the job. + #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil, + # Socket::AI_NUMERICHOST) + begin + IPSocket.getaddress(prefix) # test if address is vaild + rescue + raise ArgumentError, "invalid address" + end + @addr = @family = nil + if family == Socket::AF_UNSPEC || family == Socket::AF_INET + @addr = in_addr(prefix) + if @addr + @family = Socket::AF_INET + end + end + if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6) + @addr = in6_addr(prefix) + @family = Socket::AF_INET6 + end + if family != Socket::AF_UNSPEC && @family != family + raise ArgumentError, "address family unmatch" + end + if prefixlen + mask!(prefixlen) + else + @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK + end + end + + def in_addr(addr) + if addr =~ /^\d+\.\d+\.\d+\.\d+$/ + n = 0 + addr.split('.').each { |i| + n <<= 8 + n += i.to_i + } + return n + end + return nil + end + + def in6_addr(left) + case left + when /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i + return in_addr($1) + 0xffff00000000 + when /^::(\d+\.\d+\.\d+\.\d+)$/i + return in_addr($1) + when /[^0-9a-f:]/i + raise ArgumentError, "invalid address" + when /^(.*)::(.*)$/ + left, right = $1, $2 + else + right = '' + end + l = left.split(':') + r = right.split(':') + rest = 8 - l.size - r.size + if rest < 0 + return nil + end + a = [l, Array.new(rest, '0'), r].flatten! + n = 0 + a.each { |i| + n <<= 16 + n += i.hex + } + return n + end + + def addr_mask(addr) + case @family + when Socket::AF_INET + addr &= IN4MASK + when Socket::AF_INET6 + addr &= IN6MASK + else + raise "unsupported address family" + end + return addr + end + + def _reverse + case @family + when Socket::AF_INET + return (0..3).map { |i| + (@addr >> (8 * i)) & 0xff + }.join('.') + when Socket::AF_INET6 + return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.') + else + raise "unsupported address family" + end + end + + def _to_string(addr) + case @family + when Socket::AF_INET + return (0..3).map { |i| + (addr >> (24 - 8 * i)) & 0xff + }.join('.') + when Socket::AF_INET6 + return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:')) + else + raise "unsupported address family" + end + end + +end + +if $0 == __FILE__ + eval DATA.read, nil, $0, __LINE__+4 +end + +__END__ + +require 'test/unit' +require 'test/unit/ui/console/testrunner' + +class TC_IPAddr < Test::Unit::TestCase + def test_s_new + assert_nothing_raised { + IPAddr.new("3FFE:505:ffff::/48") + IPAddr.new("0:0:0:1::") + IPAddr.new("2001:200:300::/48") + } + + a = IPAddr.new + assert_equal("::", a.to_s) + assert_equal("0000:0000:0000:0000:0000:0000:0000:0000", a.to_string) + assert_equal(Socket::AF_INET6, a.family) + + a = IPAddr.new("0123:4567:89ab:cdef:0ABC:DEF0:1234:5678") + assert_equal("123:4567:89ab:cdef:abc:def0:1234:5678", a.to_s) + assert_equal("0123:4567:89ab:cdef:0abc:def0:1234:5678", a.to_string) + assert_equal(Socket::AF_INET6, a.family) + + a = IPAddr.new("3ffe:505:2::/48") + assert_equal("3ffe:505:2::", a.to_s) + assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string) + assert_equal(Socket::AF_INET6, a.family) + assert_equal(false, a.ipv4?) + assert_equal(true, a.ipv6?) + assert_equal("#", a.inspect) + + a = IPAddr.new("3ffe:505:2::/ffff:ffff:ffff::") + assert_equal("3ffe:505:2::", a.to_s) + assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string) + assert_equal(Socket::AF_INET6, a.family) + + a = IPAddr.new("0.0.0.0") + assert_equal("0.0.0.0", a.to_s) + assert_equal("0.0.0.0", a.to_string) + assert_equal(Socket::AF_INET, a.family) + + a = IPAddr.new("192.168.1.2") + assert_equal("192.168.1.2", a.to_s) + assert_equal("192.168.1.2", a.to_string) + assert_equal(Socket::AF_INET, a.family) + assert_equal(true, a.ipv4?) + assert_equal(false, a.ipv6?) + + a = IPAddr.new("192.168.1.2/24") + assert_equal("192.168.1.0", a.to_s) + assert_equal("192.168.1.0", a.to_string) + assert_equal(Socket::AF_INET, a.family) + assert_equal("#", a.inspect) + + a = IPAddr.new("192.168.1.2/255.255.255.0") + assert_equal("192.168.1.0", a.to_s) + assert_equal("192.168.1.0", a.to_string) + assert_equal(Socket::AF_INET, a.family) + + assert_equal("0:0:0:1::", IPAddr.new("0:0:0:1::").to_s) + assert_equal("2001:200:300::", IPAddr.new("2001:200:300::/48").to_s) + + assert_equal("2001:200:300::", IPAddr.new("[2001:200:300::]/48").to_s) + + [ + ["fe80::1%fxp0"], + ["::1/255.255.255.0"], + ["::1:192.168.1.2/120"], + [IPAddr.new("::1").to_i], + ["::ffff:192.168.1.2/120", Socket::AF_INET], + ["[192.168.1.2]/120"], + ].each { |args| + assert_raises(ArgumentError) { + IPAddr.new(*args) + } + } + end + + def test_s_new_ntoh + addr = '' + IPAddr.new("1234:5678:9abc:def0:1234:5678:9abc:def0").hton.each_byte { |c| + addr += sprintf("%02x", c) + } + assert_equal("123456789abcdef0123456789abcdef0", addr) + addr = '' + IPAddr.new("123.45.67.89").hton.each_byte { |c| + addr += sprintf("%02x", c) + } + assert_equal(sprintf("%02x%02x%02x%02x", 123, 45, 67, 89), addr) + a = IPAddr.new("3ffe:505:2::") + assert_equal("3ffe:505:2::", IPAddr.new_ntoh(a.hton).to_s) + a = IPAddr.new("192.168.2.1") + assert_equal("192.168.2.1", IPAddr.new_ntoh(a.hton).to_s) + end + + def test_ipv4_compat + a = IPAddr.new("::192.168.1.2") + assert_equal("::192.168.1.2", a.to_s) + assert_equal("0000:0000:0000:0000:0000:0000:c0a8:0102", a.to_string) + assert_equal(Socket::AF_INET6, a.family) + assert_equal(true, a.ipv4_compat?) + b = a.native + assert_equal("192.168.1.2", b.to_s) + assert_equal(Socket::AF_INET, b.family) + assert_equal(false, b.ipv4_compat?) + + a = IPAddr.new("192.168.1.2") + b = a.ipv4_compat + assert_equal("::192.168.1.2", b.to_s) + assert_equal(Socket::AF_INET6, b.family) + end + + def test_ipv4_mapped + a = IPAddr.new("::ffff:192.168.1.2") + assert_equal("::ffff:192.168.1.2", a.to_s) + assert_equal("0000:0000:0000:0000:0000:ffff:c0a8:0102", a.to_string) + assert_equal(Socket::AF_INET6, a.family) + assert_equal(true, a.ipv4_mapped?) + b = a.native + assert_equal("192.168.1.2", b.to_s) + assert_equal(Socket::AF_INET, b.family) + assert_equal(false, b.ipv4_mapped?) + + a = IPAddr.new("192.168.1.2") + b = a.ipv4_mapped + assert_equal("::ffff:192.168.1.2", b.to_s) + assert_equal(Socket::AF_INET6, b.family) + end + + def test_reverse + assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").reverse) + assert_equal("1.2.168.192.in-addr.arpa", IPAddr.new("192.168.2.1").reverse) + end + + def test_ip6_arpa + assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").ip6_arpa) + assert_raises(ArgumentError) { + IPAddr.new("192.168.2.1").ip6_arpa + } + end + + def test_ip6_int + assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int", IPAddr.new("3ffe:505:2::f").ip6_int) + assert_raises(ArgumentError) { + IPAddr.new("192.168.2.1").ip6_int + } + end + + def test_to_s + assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0001", IPAddr.new("3ffe:505:2::1").to_string) + assert_equal("3ffe:505:2::1", IPAddr.new("3ffe:505:2::1").to_s) + end +end + +class TC_Operator < Test::Unit::TestCase + + IN6MASK32 = "ffff:ffff::" + IN6MASK128 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + + def setup + @in6_addr_any = IPAddr.new() + @a = IPAddr.new("3ffe:505:2::/48") + @b = IPAddr.new("0:0:0:1::") + @c = IPAddr.new(IN6MASK32) + end + alias set_up setup + + def test_or + assert_equal("3ffe:505:2:1::", (@a | @b).to_s) + a = @a + a |= @b + assert_equal("3ffe:505:2:1::", a.to_s) + assert_equal("3ffe:505:2::", @a.to_s) + assert_equal("3ffe:505:2:1::", + (@a | 0x00000000000000010000000000000000).to_s) + end + + def test_and + assert_equal("3ffe:505::", (@a & @c).to_s) + a = @a + a &= @c + assert_equal("3ffe:505::", a.to_s) + assert_equal("3ffe:505:2::", @a.to_s) + assert_equal("3ffe:505::", (@a & 0xffffffff000000000000000000000000).to_s) + end + + def test_shift_right + assert_equal("0:3ffe:505:2::", (@a >> 16).to_s) + a = @a + a >>= 16 + assert_equal("0:3ffe:505:2::", a.to_s) + assert_equal("3ffe:505:2::", @a.to_s) + end + + def test_shift_left + assert_equal("505:2::", (@a << 16).to_s) + a = @a + a <<= 16 + assert_equal("505:2::", a.to_s) + assert_equal("3ffe:505:2::", @a.to_s) + end + + def test_carrot + a = ~@in6_addr_any + assert_equal(IN6MASK128, a.to_s) + assert_equal("::", @in6_addr_any.to_s) + end + + def test_equal + assert_equal(true, @a == IPAddr.new("3ffe:505:2::")) + assert_equal(false, @a == IPAddr.new("3ffe:505:3::")) + assert_equal(true, @a != IPAddr.new("3ffe:505:3::")) + assert_equal(false, @a != IPAddr.new("3ffe:505:2::")) + end + + def test_mask + a = @a.mask(32) + assert_equal("3ffe:505::", a.to_s) + assert_equal("3ffe:505:2::", @a.to_s) + end + + def test_include? + assert_equal(true, @a.include?(IPAddr.new("3ffe:505:2::"))) + assert_equal(true, @a.include?(IPAddr.new("3ffe:505:2::1"))) + assert_equal(false, @a.include?(IPAddr.new("3ffe:505:3::"))) + net1 = IPAddr.new("192.168.2.0/24") + assert_equal(true, net1.include?(IPAddr.new("192.168.2.0"))) + assert_equal(true, net1.include?(IPAddr.new("192.168.2.255"))) + assert_equal(false, net1.include?(IPAddr.new("192.168.3.0"))) + # test with integer parameter + int = (192 << 24) + (168 << 16) + (2 << 8) + 13 + + assert_equal(true, net1.include?(int)) + assert_equal(false, net1.include?(int+255)) + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb.rb new file mode 100644 index 00000000..9ca23135 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb.rb @@ -0,0 +1,346 @@ +# +# irb.rb - irb main module +# $Release Version: 0.9.5 $ +# $Revision: 17127 $ +# $Date: 2008-06-13 12:02:17 +0900 (Fri, 13 Jun 2008) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +require "e2mmap" + +require "irb/init" +require "irb/context" +require "irb/extend-command" +#require "irb/workspace" + +require "irb/ruby-lex" +require "irb/input-method" +require "irb/locale" + +STDOUT.sync = true + +module IRB + @RCS_ID='-$Id: irb.rb 17127 2008-06-13 03:02:17Z shyouhei $-' + + class Abort < Exception;end + + # + @CONF = {} + + def IRB.conf + @CONF + end + + # IRB version method + def IRB.version + if v = @CONF[:VERSION] then return v end + + require "irb/version" + rv = @RELEASE_VERSION.sub(/\.0/, "") + @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE) + end + + def IRB.CurrentContext + IRB.conf[:MAIN_CONTEXT] + end + + # initialize IRB and start TOP_LEVEL irb + def IRB.start(ap_path = nil) + $0 = File::basename(ap_path, ".rb") if ap_path + + IRB.setup(ap_path) + + if @CONF[:SCRIPT] + irb = Irb.new(nil, @CONF[:SCRIPT]) + else + irb = Irb.new + end + + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @CONF[:MAIN_CONTEXT] = irb.context + + trap("SIGINT") do + irb.signal_handle + end + + catch(:IRB_EXIT) do + irb.eval_input + end +# print "\n" + end + + def IRB.irb_exit(irb, ret) + throw :IRB_EXIT, ret + end + + def IRB.irb_abort(irb, exception = Abort) + if defined? Thread + irb.context.thread.raise exception, "abort then interrupt!!" + else + raise exception, "abort then interrupt!!" + end + end + + # + # irb interpriter main routine + # + class Irb + def initialize(workspace = nil, input_method = nil, output_method = nil) + @context = Context.new(self, workspace, input_method, output_method) + @context.main.extend ExtendCommandBundle + @signal_status = :IN_IRB + + @scanner = RubyLex.new + @scanner.exception_on_syntax_error = false + end + attr_reader :context + attr_accessor :scanner + + def eval_input + @scanner.set_prompt do + |ltype, indent, continue, line_no| + if ltype + f = @context.prompt_s + elsif continue + f = @context.prompt_c + elsif indent > 0 + f = @context.prompt_n + else @context.prompt_i + f = @context.prompt_i + end + f = "" unless f + if @context.prompting? + @context.io.prompt = p = prompt(f, ltype, indent, line_no) + else + @context.io.prompt = p = "" + end + if @context.auto_indent_mode + unless ltype + ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size + + indent * 2 - p.size + ind += 2 if continue + @context.io.prompt = p + " " * ind if ind > 0 + end + end + end + + @scanner.set_input(@context.io) do + signal_status(:IN_INPUT) do + if l = @context.io.gets + print l if @context.verbose? + else + if @context.ignore_eof? and @context.io.readable_atfer_eof? + l = "\n" + if @context.verbose? + printf "Use \"exit\" to leave %s\n", @context.ap_name + end + end + end + l + end + end + + @scanner.each_top_level_statement do |line, line_no| + signal_status(:IN_EVAL) do + begin + line.untaint + @context.evaluate(line, line_no) + output_value if @context.echo? + exc = nil + rescue Interrupt => exc + rescue SystemExit, SignalException + raise + rescue Exception => exc + end + if exc + print exc.class, ": ", exc, "\n" + if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ + irb_bug = true + else + irb_bug = false + end + + messages = [] + lasts = [] + levels = 0 + for m in exc.backtrace + m = @context.workspace.filter_backtrace(m) unless irb_bug + if m + if messages.size < @context.back_trace_limit + messages.push "\tfrom "+m + else + lasts.push "\tfrom "+m + if lasts.size > @context.back_trace_limit + lasts.shift + levels += 1 + end + end + end + end + print messages.join("\n"), "\n" + unless lasts.empty? + printf "... %d levels...\n", levels if levels > 0 + print lasts.join("\n") + end + print "Maybe IRB bug!!\n" if irb_bug + end + if $SAFE > 2 + abort "Error: irb does not work for $SAFE level higher than 2" + end + end + end + end + + def suspend_name(path = nil, name = nil) + @context.irb_path, back_path = path, @context.irb_path if path + @context.irb_name, back_name = name, @context.irb_name if name + begin + yield back_path, back_name + ensure + @context.irb_path = back_path if path + @context.irb_name = back_name if name + end + end + + def suspend_workspace(workspace) + @context.workspace, back_workspace = workspace, @context.workspace + begin + yield back_workspace + ensure + @context.workspace = back_workspace + end + end + + def suspend_input_method(input_method) + back_io = @context.io + @context.instance_eval{@io = input_method} + begin + yield back_io + ensure + @context.instance_eval{@io = back_io} + end + end + + def suspend_context(context) + @context, back_context = context, @context + begin + yield back_context + ensure + @context = back_context + end + end + + def signal_handle + unless @context.ignore_sigint? + print "\nabort!!\n" if @context.verbose? + exit + end + + case @signal_status + when :IN_INPUT + print "^C\n" + raise RubyLex::TerminateLineInput + when :IN_EVAL + IRB.irb_abort(self) + when :IN_LOAD + IRB.irb_abort(self, LoadAbort) + when :IN_IRB + # ignore + else + # ignore other cases as well + end + end + + def signal_status(status) + return yield if @signal_status == :IN_LOAD + + signal_status_back = @signal_status + @signal_status = status + begin + yield + ensure + @signal_status = signal_status_back + end + end + + def prompt(prompt, ltype, indent, line_no) + p = prompt.dup + p.gsub!(/%([0-9]+)?([a-zA-Z])/) do + case $2 + when "N" + @context.irb_name + when "m" + @context.main.to_s + when "M" + @context.main.inspect + when "l" + ltype + when "i" + if $1 + format("%" + $1 + "d", indent) + else + indent.to_s + end + when "n" + if $1 + format("%" + $1 + "d", line_no) + else + line_no.to_s + end + when "%" + "%" + end + end + p + end + + def output_value + if @context.inspect? + printf @context.return_format, @context.last_value.inspect + else + printf @context.return_format, @context.last_value + end + end + + def inspect + ary = [] + for iv in instance_variables + case iv + when "@signal_status" + ary.push format("%s=:%s", iv, @signal_status.id2name) + when "@context" + ary.push format("%s=%s", iv, eval(iv).__to_s__) + else + ary.push format("%s=%s", iv, eval(iv)) + end + end + format("#<%s: %s>", self.class, ary.join(", ")) + end + end + + # Singleton method + def @CONF.inspect + IRB.version unless self[:VERSION] + + array = [] + for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name} + case k + when :MAIN_CONTEXT, :__TMP__EHV__ + array.push format("CONF[:%s]=...myself...", k.id2name) + when :PROMPT + s = v.collect{ + |kk, vv| + ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"} + format(":%s=>{%s}", kk.id2name, ss.join(", ")) + } + array.push format("CONF[:%s]={%s}", k.id2name, s.join(", ")) + else + array.push format("CONF[:%s]=%s", k.id2name, v.inspect) + end + end + array.join("\n") + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/cmd/chws.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/cmd/chws.rb new file mode 100644 index 00000000..772d4da4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/cmd/chws.rb @@ -0,0 +1,33 @@ +# +# change-ws.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + +require "irb/cmd/nop.rb" +require "irb/ext/change-ws.rb" + +module IRB + module ExtendCommand + + class CurrentWorkingWorkspace", "==", "===", "=~", ">", ">=", ">>", + "[]", "[]=", "^",] + + def self.select_message(receiver, message, candidates) + candidates.grep(/^#{message}/).collect do |e| + case e + when /^[a-zA-Z_]/ + receiver + "." + e + when /^[0-9]/ + when *Operators + #receiver + " " + e + end + end + end + end +end + +if Readline.respond_to?("basic_word_break_characters=") + Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{(" +end +Readline.completion_append_character = nil +Readline.completion_proc = IRB::InputCompletor::CompletionProc diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/context.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/context.rb new file mode 100644 index 00000000..de70945f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/context.rb @@ -0,0 +1,255 @@ +# +# irb/context.rb - irb context +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +require "irb/workspace" + +module IRB + class Context + # + # Arguments: + # input_method: nil -- stdin or readline + # String -- File + # other -- using this as InputMethod + # + def initialize(irb, workspace = nil, input_method = nil, output_method = nil) + @irb = irb + if workspace + @workspace = workspace + else + @workspace = WorkSpace.new + end + @thread = Thread.current if defined? Thread +# @irb_level = 0 + + # copy of default configuration + @ap_name = IRB.conf[:AP_NAME] + @rc = IRB.conf[:RC] + @load_modules = IRB.conf[:LOAD_MODULES] + + @use_readline = IRB.conf[:USE_READLINE] + @inspect_mode = IRB.conf[:INSPECT_MODE] + + self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE] + self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER] + self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER] + self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY] + + @ignore_sigint = IRB.conf[:IGNORE_SIGINT] + @ignore_eof = IRB.conf[:IGNORE_EOF] + + @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT] + + self.prompt_mode = IRB.conf[:PROMPT_MODE] + + if IRB.conf[:SINGLE_IRB] or !defined?(JobManager) + @irb_name = IRB.conf[:IRB_NAME] + else + @irb_name = "irb#"+IRB.JobManager.n_jobs.to_s + end + @irb_path = "(" + @irb_name + ")" + + case input_method + when nil + case use_readline? + when nil + if (defined?(ReadlineInputMethod) && STDIN.tty? && + IRB.conf[:PROMPT_MODE] != :INF_RUBY) + @io = ReadlineInputMethod.new + else + @io = StdioInputMethod.new + end + when false + @io = StdioInputMethod.new + when true + if defined?(ReadlineInputMethod) + @io = ReadlineInputMethod.new + else + @io = StdioInputMethod.new + end + end + + when String + @io = FileInputMethod.new(input_method) + @irb_name = File.basename(input_method) + @irb_path = input_method + else + @io = input_method + end + self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY] + + if output_method + @output_method = output_method + else + @output_method = StdioOutputMethod.new + end + + @verbose = IRB.conf[:VERBOSE] + @echo = IRB.conf[:ECHO] + if @echo.nil? + @echo = true + end + @debug_level = IRB.conf[:DEBUG_LEVEL] + end + + def main + @workspace.main + end + + attr_reader :workspace_home + attr_accessor :workspace + attr_reader :thread + attr_accessor :io + + attr_accessor :irb + attr_accessor :ap_name + attr_accessor :rc + attr_accessor :load_modules + attr_accessor :irb_name + attr_accessor :irb_path + + attr_reader :use_readline + attr_reader :inspect_mode + + attr_reader :prompt_mode + attr_accessor :prompt_i + attr_accessor :prompt_s + attr_accessor :prompt_c + attr_accessor :prompt_n + attr_accessor :auto_indent_mode + attr_accessor :return_format + + attr_accessor :ignore_sigint + attr_accessor :ignore_eof + attr_accessor :echo + attr_accessor :verbose + attr_reader :debug_level + + attr_accessor :back_trace_limit + + alias use_readline? use_readline + alias rc? rc + alias ignore_sigint? ignore_sigint + alias ignore_eof? ignore_eof + alias echo? echo + + def verbose? + if @verbose.nil? + if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) + false + elsif !STDIN.tty? or @io.kind_of?(FileInputMethod) + true + else + false + end + end + end + + def prompting? + verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) || + (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod))) + end + + attr_reader :last_value + + def set_last_value(value) + @last_value = value + @workspace.evaluate self, "_ = IRB.CurrentContext.last_value" + end + + attr_reader :irb_name + + def prompt_mode=(mode) + @prompt_mode = mode + pconf = IRB.conf[:PROMPT][mode] + @prompt_i = pconf[:PROMPT_I] + @prompt_s = pconf[:PROMPT_S] + @prompt_c = pconf[:PROMPT_C] + @prompt_n = pconf[:PROMPT_N] + @return_format = pconf[:RETURN] + if ai = pconf.include?(:AUTO_INDENT) + @auto_indent_mode = ai + else + @auto_indent_mode = IRB.conf[:AUTO_INDENT] + end + end + + def inspect? + @inspect_mode.nil? or @inspect_mode + end + + def file_input? + @io.class == FileInputMethod + end + + def inspect_mode=(opt) + if opt + @inspect_mode = opt + else + @inspect_mode = !@inspect_mode + end + print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose? + @inspect_mode + end + + def use_readline=(opt) + @use_readline = opt + print "use readline module\n" if @use_readline + end + + def debug_level=(value) + @debug_level = value + RubyLex.debug_level = value + SLex.debug_level = value + end + + def debug? + @debug_level > 0 + end + + def evaluate(line, line_no) + @line_no = line_no + set_last_value(@workspace.evaluate(self, line, irb_path, line_no)) +# @workspace.evaluate("_ = IRB.conf[:MAIN_CONTEXT]._") +# @_ = @workspace.evaluate(line, irb_path, line_no) + end + + alias __exit__ exit + def exit(ret = 0) + IRB.irb_exit(@irb, ret) + end + + NOPRINTING_IVARS = ["@last_value"] + NO_INSPECTING_IVARS = ["@irb", "@io"] + IDNAME_IVARS = ["@prompt_mode"] + + alias __inspect__ inspect + def inspect + array = [] + for ivar in instance_variables.sort{|e1, e2| e1 <=> e2} + name = ivar.sub(/^@(.*)$/){$1} + val = instance_eval(ivar) + case ivar + when *NOPRINTING_IVARS + array.push format("conf.%s=%s", name, "...") + when *NO_INSPECTING_IVARS + array.push format("conf.%s=%s", name, val.to_s) + when *IDNAME_IVARS + array.push format("conf.%s=:%s", name, val.id2name) + else + array.push format("conf.%s=%s", name, val.inspect) + end + end + array.join("\n") + end + alias __to_s__ to_s + alias to_s inspect + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/change-ws.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/change-ws.rb new file mode 100644 index 00000000..0fbdd813 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/change-ws.rb @@ -0,0 +1,62 @@ +# +# irb/ext/cb.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + +module IRB + class Context + + def home_workspace + if defined? @home_workspace + @home_workspace + else + @home_workspace = @workspace + end + end + + def change_workspace(*_main) + if _main.empty? + @workspace = home_workspace + return main + end + + @workspace = WorkSpace.new(_main[0]) + + if !(class<= 0 + @contents.find{|no, val| no == idx}[1] + else + @contents[idx][1] + end + rescue NameError + nil + end + end + + def push(no, val) + @contents.push [no, val] + @contents.shift if @size != 0 && @contents.size > @size + end + + alias real_inspect inspect + + def inspect + if @contents.empty? + return real_inspect + end + + unless (last = @contents.pop)[1].equal?(self) + @contents.push last + last = nil + end + str = @contents.collect{|no, val| + if val.equal?(self) + "#{no} ...self-history..." + else + "#{no} #{val.inspect}" + end + }.join("\n") + if str == "" + str = "Empty." + end + @contents.push last if last + str + end + end +end + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/loader.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/loader.rb new file mode 100644 index 00000000..465a793d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/loader.rb @@ -0,0 +1,120 @@ +# +# loader.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + + +module IRB + class LoadAbort < Exception;end + + module IrbLoader + @RCS_ID='-$Id: loader.rb 11708 2007-02-12 23:01:19Z shyouhei $-' + + alias ruby_load load + alias ruby_require require + + def irb_load(fn, priv = nil) + path = search_file_from_ruby_path(fn) + raise LoadError, "No such file to load -- #{fn}" unless path + + load_file(path, priv) + end + + def search_file_from_ruby_path(fn) + if /^#{Regexp.quote(File::Separator)}/ =~ fn + return fn if File.exist?(fn) + return nil + end + + for path in $: + if File.exist?(f = File.join(path, fn)) + return f + end + end + return nil + end + + def source_file(path) + irb.suspend_name(path, File.basename(path)) do + irb.suspend_input_method(FileInputMethod.new(path)) do + |back_io| + irb.signal_status(:IN_LOAD) do + if back_io.kind_of?(FileInputMethod) + irb.eval_input + else + begin + irb.eval_input + rescue LoadAbort + print "load abort!!\n" + end + end + end + end + end + end + + def load_file(path, priv = nil) + irb.suspend_name(path, File.basename(path)) do + + if priv + ws = WorkSpace.new(Module.new) + else + ws = WorkSpace.new + end + irb.suspend_workspace(ws) do + irb.suspend_input_method(FileInputMethod.new(path)) do + |back_io| + irb.signal_status(:IN_LOAD) do +# p irb.conf + if back_io.kind_of?(FileInputMethod) + irb.eval_input + else + begin + irb.eval_input + rescue LoadAbort + print "load abort!!\n" + end + end + end + end + end + end + end + + def old + back_io = @io + back_path = @irb_path + back_name = @irb_name + back_scanner = @irb.scanner + begin + @io = FileInputMethod.new(path) + @irb_name = File.basename(path) + @irb_path = path + @irb.signal_status(:IN_LOAD) do + if back_io.kind_of?(FileInputMethod) + @irb.eval_input + else + begin + @irb.eval_input + rescue LoadAbort + print "load abort!!\n" + end + end + end + ensure + @io = back_io + @irb_name = back_name + @irb_path = back_path + @irb.scanner = back_scanner + end + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/math-mode.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/math-mode.rb new file mode 100644 index 00000000..ccef2a12 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/math-mode.rb @@ -0,0 +1,37 @@ +# +# math-mode.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +require "mathn" + +module IRB + class Context + attr_reader :math_mode + alias math? math_mode + + def math_mode=(opt) + if @math_mode == true && opt == false + IRB.fail CantReturnToNormalMode + return + end + + @math_mode = opt + if math_mode + main.extend Math + print "start math mode\n" if verbose? + end + end + + def inspect? + @inspect_mode.nil? && !@math_mode or @inspect_mode + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/multi-irb.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/multi-irb.rb new file mode 100644 index 00000000..b0d0ed8d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/multi-irb.rb @@ -0,0 +1,241 @@ +# +# irb/multi-irb.rb - multiple irb module +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +IRB.fail CantShiftToMultiIrbMode unless defined?(Thread) +require "thread" + +module IRB + # job management class + class JobManager + @RCS_ID='-$Id: multi-irb.rb 11708 2007-02-12 23:01:19Z shyouhei $-' + + def initialize + # @jobs = [[thread, irb],...] + @jobs = [] + @current_job = nil + end + + attr_accessor :current_job + + def n_jobs + @jobs.size + end + + def thread(key) + th, irb = search(key) + th + end + + def irb(key) + th, irb = search(key) + irb + end + + def main_thread + @jobs[0][0] + end + + def main_irb + @jobs[0][1] + end + + def insert(irb) + @jobs.push [Thread.current, irb] + end + + def switch(key) + th, irb = search(key) + IRB.fail IrbAlreadyDead unless th.alive? + IRB.fail IrbSwitchedToCurrentThread if th == Thread.current + @current_job = irb + th.run + Thread.stop + @current_job = irb(Thread.current) + end + + def kill(*keys) + for key in keys + th, irb = search(key) + IRB.fail IrbAlreadyDead unless th.alive? + th.exit + end + end + + def search(key) + case key + when Integer + @jobs[key] + when Irb + @jobs.find{|k, v| v.equal?(key)} + when Thread + @jobs.assoc(key) + else + assoc = @jobs.find{|k, v| v.context.main.equal?(key)} + IRB.fail NoSuchJob, key if assoc.nil? + assoc + end + end + + def delete(key) + case key + when Integer + IRB.fail NoSuchJob, key unless @jobs[key] + @jobs[key] = nil + else + catch(:EXISTS) do + @jobs.each_index do + |i| + if @jobs[i] and (@jobs[i][0] == key || + @jobs[i][1] == key || + @jobs[i][1].context.main.equal?(key)) + @jobs[i] = nil + throw :EXISTS + end + end + IRB.fail NoSuchJob, key + end + end + until assoc = @jobs.pop; end unless @jobs.empty? + @jobs.push assoc + end + + def inspect + ary = [] + @jobs.each_index do + |i| + th, irb = @jobs[i] + next if th.nil? + + if th.alive? + if th.stop? + t_status = "stop" + else + t_status = "running" + end + else + t_status = "exited" + end + ary.push format("#%d->%s on %s (%s: %s)", + i, + irb.context.irb_name, + irb.context.main, + th, + t_status) + end + ary.join("\n") + end + end + + @JobManager = JobManager.new + + def IRB.JobManager + @JobManager + end + + def IRB.CurrentContext + IRB.JobManager.irb(Thread.current).context + end + + # invoke multi-irb + def IRB.irb(file = nil, *main) + workspace = WorkSpace.new(*main) + parent_thread = Thread.current + Thread.start do + begin + irb = Irb.new(workspace, file) + rescue + print "Subirb can't start with context(self): ", workspace.main.inspect, "\n" + print "return to main irb\n" + Thread.pass + Thread.main.wakeup + Thread.exit + end + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @JobManager.insert(irb) + @JobManager.current_job = irb + begin + system_exit = false + catch(:IRB_EXIT) do + irb.eval_input + end + rescue SystemExit + system_exit = true + raise + #fail + ensure + unless system_exit + @JobManager.delete(irb) + if parent_thread.alive? + @JobManager.current_job = @JobManager.irb(parent_thread) + parent_thread.run + else + @JobManager.current_job = @JobManager.main_irb + @JobManager.main_thread.run + end + end + end + end + Thread.stop + @JobManager.current_job = @JobManager.irb(Thread.current) + end + +# class Context +# def set_last_value(value) +# @last_value = value +# @workspace.evaluate "_ = IRB.JobManager.irb(Thread.current).context.last_value" +# if @eval_history #and !@__.equal?(@last_value) +# @eval_history_values.push @line_no, @last_value +# @workspace.evaluate "__ = IRB.JobManager.irb(Thread.current).context.instance_eval{@eval_history_values}" +# end +# @last_value +# end +# end + +# module ExtendCommand +# def irb_context +# IRB.JobManager.irb(Thread.current).context +# end +# # alias conf irb_context +# end + + @CONF[:SINGLE_IRB_MODE] = false + @JobManager.insert(@CONF[:MAIN_CONTEXT].irb) + @JobManager.current_job = @CONF[:MAIN_CONTEXT].irb + + class Irb + def signal_handle + unless @context.ignore_sigint? + print "\nabort!!\n" if @context.verbose? + exit + end + + case @signal_status + when :IN_INPUT + print "^C\n" + IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput + when :IN_EVAL + IRB.irb_abort(self) + when :IN_LOAD + IRB.irb_abort(self, LoadAbort) + when :IN_IRB + # ignore + else + # ignore other cases as well + end + end + end + + trap("SIGINT") do + @JobManager.current_job.signal_handle + Thread.stop + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/save-history.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/save-history.rb new file mode 100644 index 00000000..f615ea24 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/save-history.rb @@ -0,0 +1,85 @@ +#!/usr/local/bin/ruby +# +# save-history.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKAkeiju@ruby-lang.org) +# +# -- +# +# +# + +require "readline" + +module IRB + module HistorySavingAbility + @RCS_ID='-$Id: save-history.rb 11708 2007-02-12 23:01:19Z shyouhei $-' + end + + class Context + def init_save_history + unless (class<<@io;self;end).include?(HistorySavingAbility) + @io.extend(HistorySavingAbility) + end + end + + def save_history + IRB.conf[:SAVE_HISTORY] + end + + def save_history=(val) + IRB.conf[:SAVE_HISTORY] = val + if val + main_context = IRB.conf[:MAIN_CONTEXT] + main_context = self unless main_context + main_context.init_save_history + end + end + + def history_file + IRB.conf[:HISTORY_FILE] + end + + def history_file=(hist) + IRB.conf[:HISTORY_FILE] = hist + end + end + + module HistorySavingAbility + include Readline + + def HistorySavingAbility.create_finalizer + proc do + if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0 + if hf = IRB.conf[:HISTORY_FILE] + file = File.expand_path(hf) + end + file = IRB.rc_file("_history") unless file + open(file, 'w' ) do |f| + hist = HISTORY.to_a + f.puts(hist[-num..-1] || hist) + end + end + end + end + + def HistorySavingAbility.extended(obj) + ObjectSpace.define_finalizer(obj, HistorySavingAbility.create_finalizer) + obj.load_history + obj + end + + def load_history + hist = IRB.conf[:HISTORY_FILE] + hist = IRB.rc_file("_history") unless hist + if File.exist?(hist) + open(hist) do |f| + f.each {|l| HISTORY << l.chomp} + end + end + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/tracer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/tracer.rb new file mode 100644 index 00000000..a860ffd9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/tracer.rb @@ -0,0 +1,61 @@ +# +# irb/lib/tracer.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +require "tracer" + +module IRB + + # initialize tracing function + def IRB.initialize_tracer + Tracer.verbose = false + Tracer.add_filter { + |event, file, line, id, binding, *rests| + /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and + File::basename(file) != "irb.rb" + } + end + + class Context + attr_reader :use_tracer + alias use_tracer? use_tracer + + def use_tracer=(opt) + if opt + Tracer.set_get_line_procs(@irb_path) { + |line_no, *rests| + @io.line(line_no) + } + elsif !opt && @use_tracer + Tracer.off + end + @use_tracer=opt + end + end + + class WorkSpace + alias __evaluate__ evaluate + def evaluate(context, statements, file = nil, line = nil) + if context.use_tracer? && file != nil && line != nil + Tracer.on + begin + __evaluate__(context, statements, file, line) + ensure + Tracer.off + end + else + __evaluate__(context, statements, file || __FILE__, line || __LINE__) + end + end + end + + IRB.initialize_tracer +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/use-loader.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/use-loader.rb new file mode 100644 index 00000000..a7098199 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/use-loader.rb @@ -0,0 +1,65 @@ +# +# use-loader.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + +require "irb/cmd/load" +require "irb/ext/loader" + +class Object + alias __original__load__IRB_use_loader__ load + alias __original__require__IRB_use_loader__ require +end + +module IRB + module ExtendCommandBundle + def irb_load(*opts, &b) + ExtendCommand::Load.execute(irb_context, *opts, &b) + end + def irb_require(*opts, &b) + ExtendCommand::Require.execute(irb_context, *opts, &b) + end + end + + class Context + + IRB.conf[:USE_LOADER] = false + + def use_loader + IRB.conf[:USE_LOADER] + end + + alias use_loader? use_loader + + def use_loader=(opt) + + if IRB.conf[:USE_LOADER] != opt + IRB.conf[:USE_LOADER] = opt + if opt + if !$".include?("irb/cmd/load") + end + (class<<@workspace.main;self;end).instance_eval { + alias_method :load, :irb_load + alias_method :require, :irb_require + } + else + (class<<@workspace.main;self;end).instance_eval { + alias_method :load, :__original__load__IRB_use_loader__ + alias_method :require, :__original__require__IRB_use_loader__ + } + end + end + print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose? + opt + end + end +end + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/workspaces.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/workspaces.rb new file mode 100644 index 00000000..7bb6411a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ext/workspaces.rb @@ -0,0 +1,56 @@ +# +# push-ws.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + +module IRB + class Context + + def irb_level + workspace_stack.size + end + + def workspaces + if defined? @workspaces + @workspaces + else + @workspaces = [] + end + end + + def push_workspace(*_main) + if _main.empty? + if workspaces.empty? + print "No other workspace\n" + return nil + end + ws = workspaces.pop + workspaces.push @workspace + @workspace = ws + return workspaces + end + + workspaces.push @workspace + @workspace = WorkSpace.new(@workspace.binding, _main[0]) + if !(class< + def new_alias_name(name, prefix = "__alias_of__", postfix = "__") + base_name = "#{prefix}#{name}#{postfix}" + all_methods = instance_methods(true) + private_instance_methods(true) + same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/) + return base_name if same_methods.empty? + no = same_methods.size + while !same_methods.include?(alias_name = base_name + no) + no += 1 + end + alias_name + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/frame.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/frame.rb new file mode 100644 index 00000000..34bf103b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/frame.rb @@ -0,0 +1,67 @@ +# +# frame.rb - +# $Release Version: 0.9$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) +# +# -- +# +# +# + +require "e2mmap" + +module IRB + class Frame + extend Exception2MessageMapper + def_exception :FrameOverflow, "frame overflow" + def_exception :FrameUnderflow, "frame underflow" + + INIT_STACK_TIMES = 3 + CALL_STACK_OFFSET = 3 + + def initialize + @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES + end + + def trace_func(event, file, line, id, binding) + case event + when 'call', 'class' + @frames.push binding + when 'return', 'end' + @frames.pop + end + end + + def top(n = 0) + bind = @frames[-(n + CALL_STACK_OFFSET)] + Fail FrameUnderflow unless bind + bind + end + + def bottom(n = 0) + bind = @frames[n] + Fail FrameOverflow unless bind + bind + end + + # singleton functions + def Frame.bottom(n = 0) + @backtrace.bottom(n) + end + + def Frame.top(n = 0) + @backtrace.top(n) + end + + def Frame.sender + eval "self", @backtrace.top + end + + @backtrace = Frame.new + set_trace_func proc{|event, file, line, id, binding, klass| + @backtrace.trace_func(event, file, line, id, binding) + } + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/help.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/help.rb new file mode 100644 index 00000000..9a32fd85 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/help.rb @@ -0,0 +1,33 @@ +# +# irb/help.rb - print usase module +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +module IRB + def IRB.print_usage + lc = IRB.conf[:LC_MESSAGES] + path = lc.find("irb/help-message") + space_line = false + File.foreach(path) do + |l| + if /^\s*$/ =~ l + lc.puts l unless space_line + space_line = true + next + end + space_line = false + + l.sub!(/#.*$/, "") + next if /^\s*$/ =~ l + lc.puts l + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/init.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/init.rb new file mode 100644 index 00000000..60974cff --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/init.rb @@ -0,0 +1,259 @@ +# +# irb/init.rb - irb initialize module +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + +module IRB + + # initialize config + def IRB.setup(ap_path) + IRB.init_config(ap_path) + IRB.init_error + IRB.parse_opts + IRB.run_config + IRB.load_modules + + unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]] + IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE]) + end + end + + # @CONF default setting + def IRB.init_config(ap_path) + # class instance variables + @TRACER_INITIALIZED = false + + # default configurations + unless ap_path and @CONF[:AP_NAME] + ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb") + end + @CONF[:AP_NAME] = File::basename(ap_path, ".rb") + + @CONF[:IRB_NAME] = "irb" + @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__) + + @CONF[:RC] = true + @CONF[:LOAD_MODULES] = [] + @CONF[:IRB_RC] = nil + + @CONF[:MATH_MODE] = false + @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod) + @CONF[:INSPECT_MODE] = nil + @CONF[:USE_TRACER] = false + @CONF[:USE_LOADER] = false + @CONF[:IGNORE_SIGINT] = true + @CONF[:IGNORE_EOF] = false + @CONF[:ECHO] = nil + @CONF[:VERBOSE] = nil + + @CONF[:EVAL_HISTORY] = nil + @CONF[:SAVE_HISTORY] = nil + + @CONF[:BACK_TRACE_LIMIT] = 16 + + @CONF[:PROMPT] = { + :NULL => { + :PROMPT_I => nil, + :PROMPT_N => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n" + }, + :DEFAULT => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_N => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "=> %s\n" + }, + :CLASSIC => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_N => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "%s\n" + }, + :SIMPLE => { + :PROMPT_I => ">> ", + :PROMPT_N => ">> ", + :PROMPT_S => nil, + :PROMPT_C => "?> ", + :RETURN => "=> %s\n" + }, + :INF_RUBY => { + :PROMPT_I => "%N(%m):%03n:%i> ", +# :PROMPT_N => "%N(%m):%03n:%i> ", + :PROMPT_N => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n", + :AUTO_INDENT => true + }, + :XMP => { + :PROMPT_I => nil, + :PROMPT_N => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => " ==>%s\n" + } + } + + @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL) + @CONF[:AUTO_INDENT] = false + + @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING + @CONF[:SINGLE_IRB] = false + +# @CONF[:LC_MESSAGES] = "en" + @CONF[:LC_MESSAGES] = Locale.new + + @CONF[:DEBUG_LEVEL] = 1 + end + + def IRB.init_error + @CONF[:LC_MESSAGES].load("irb/error.rb") + end + + FEATURE_IOPT_CHANGE_VERSION = "1.9.0" + + # option analyzing + def IRB.parse_opts + load_path = [] + while opt = ARGV.shift + case opt + when "-f" + @CONF[:RC] = false + when "-m" + @CONF[:MATH_MODE] = true + when "-d" + $DEBUG = true + when /^-r(.+)?/ + opt = $1 || ARGV.shift + @CONF[:LOAD_MODULES].push opt if opt + when /^-I(.+)?/ + opt = $1 || ARGV.shift + load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt + when /^-K(.)/ + $KCODE = $1 + when "--inspect" + @CONF[:INSPECT_MODE] = true + when "--noinspect" + @CONF[:INSPECT_MODE] = false + when "--readline" + @CONF[:USE_READLINE] = true + when "--noreadline" + @CONF[:USE_READLINE] = false + when "--echo" + @CONF[:ECHO] = true + when "--noecho" + @CONF[:ECHO] = false + when "--verbose" + @CONF[:VERBOSE] = true + when "--noverbose" + @CONF[:VERBOSE] = false + when "--prompt-mode", "--prompt" + prompt_mode = ARGV.shift.upcase.tr("-", "_").intern + @CONF[:PROMPT_MODE] = prompt_mode + when "--noprompt" + @CONF[:PROMPT_MODE] = :NULL + when "--inf-ruby-mode" + @CONF[:PROMPT_MODE] = :INF_RUBY + when "--sample-book-mode", "--simple-prompt" + @CONF[:PROMPT_MODE] = :SIMPLE + when "--tracer" + @CONF[:USE_TRACER] = true + when "--back-trace-limit" + @CONF[:BACK_TRACE_LIMIT] = ARGV.shift.to_i + when "--context-mode" + @CONF[:CONTEXT_MODE] = ARGV.shift.to_i + when "--single-irb" + @CONF[:SINGLE_IRB] = true + when "--irb_debug" + @CONF[:DEBUG_LEVEL] = ARGV.shift.to_i + when "-v", "--version" + print IRB.version, "\n" + exit 0 + when "-h", "--help" + require "irb/help" + IRB.print_usage + exit 0 + when /^-/ + IRB.fail UnrecognizedSwitch, opt + else + @CONF[:SCRIPT] = opt + $0 = opt + break + end + end + if RUBY_VERSION >= FEATURE_IOPT_CHANGE_VERSION + load_path.collect! do |path| + /\A\.\// =~ path ? path : File.expand_path(path) + end + end + $LOAD_PATH.unshift(*load_path) + end + + # running config + def IRB.run_config + if @CONF[:RC] + begin + load rc_file + rescue LoadError, Errno::ENOENT + rescue + print "load error: #{rc_file}\n" + print $!.class, ": ", $!, "\n" + for err in $@[0, $@.size - 2] + print "\t", err, "\n" + end + end + end + end + + IRBRC_EXT = "rc" + def IRB.rc_file(ext = IRBRC_EXT) + if !@CONF[:RC_NAME_GENERATOR] + rc_file_generators do |rcgen| + @CONF[:RC_NAME_GENERATOR] ||= rcgen + if File.exist?(rcgen.call(IRBRC_EXT)) + @CONF[:RC_NAME_GENERATOR] = rcgen + break + end + end + end + @CONF[:RC_NAME_GENERATOR].call ext + end + + # enumerate possible rc-file base name generators + def IRB.rc_file_generators + if irbrc = ENV["IRBRC"] + yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc} + end + if home = ENV["HOME"] + yield proc{|rc| home+"/.irb#{rc}"} + end + home = Dir.pwd + yield proc{|rc| home+"/.irb#{rc}"} + yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"} + yield proc{|rc| home+"/_irb#{rc}"} + yield proc{|rc| home+"/$irb#{rc}"} + end + + # loading modules + def IRB.load_modules + for m in @CONF[:LOAD_MODULES] + begin + require m + rescue + print $@[0], ":", $!.class, ": ", $!, "\n" + end + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/input-method.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/input-method.rb new file mode 100644 index 00000000..2e504990 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/input-method.rb @@ -0,0 +1,120 @@ +# +# irb/input-method.rb - input methods used irb +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +module IRB + # + # InputMethod + # StdioInputMethod + # FileInputMethod + # (ReadlineInputMethod) + # + STDIN_FILE_NAME = "(line)" + class InputMethod + @RCS_ID='-$Id: input-method.rb 11708 2007-02-12 23:01:19Z shyouhei $-' + + def initialize(file = STDIN_FILE_NAME) + @file_name = file + end + attr_reader :file_name + + attr_accessor :prompt + + def gets + IRB.fail NotImplementedError, "gets" + end + public :gets + + def readable_atfer_eof? + false + end + end + + class StdioInputMethod < InputMethod + def initialize + super + @line_no = 0 + @line = [] + end + + def gets + print @prompt + @line[@line_no += 1] = $stdin.gets + end + + def eof? + $stdin.eof? + end + + def readable_atfer_eof? + true + end + + def line(line_no) + @line[line_no] + end + end + + class FileInputMethod < InputMethod + def initialize(file) + super + @io = open(file) + end + attr_reader :file_name + + def eof? + @io.eof? + end + + def gets + print @prompt + l = @io.gets +# print @prompt, l + l + end + end + + begin + require "readline" + class ReadlineInputMethod < InputMethod + include Readline + def initialize + super + + @line_no = 0 + @line = [] + @eof = false + end + + def gets + if l = readline(@prompt, false) + HISTORY.push(l) if !l.empty? + @line[@line_no += 1] = l + "\n" + else + @eof = true + l + end + end + + def eof? + @eof + end + + def readable_atfer_eof? + true + end + + def line(line_no) + @line[line_no] + end + end + rescue LoadError + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/error.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/error.rb new file mode 100644 index 00000000..8054f59a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/error.rb @@ -0,0 +1,30 @@ +# +# irb/lc/error.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +require "e2mmap" + +module IRB + + # exceptions + extend Exception2MessageMapper + def_exception :UnrecognizedSwitch, "Unrecognized switch: %s" + def_exception :NotImplementedError, "Need to define `%s'" + def_exception :CantReturnToNormalMode, "Can't return to normal mode." + def_exception :IllegalParameter, "Illegal parameter(%s)." + def_exception :IrbAlreadyDead, "Irb is already dead." + def_exception :IrbSwitchedToCurrentThread, "Switched to current thread." + def_exception :NoSuchJob, "No such job(%s)." + def_exception :CantShiftToMultiIrbMode, "Can't shift to multi irb mode." + def_exception :CantChangeBinding, "Can't change binding to (%s)." + def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)." + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/help-message b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/help-message new file mode 100644 index 00000000..5188ff3c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/help-message @@ -0,0 +1,35 @@ +# +# irb/lc/help-message.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +Usage: irb.rb [options] [programfile] [arguments] + -f Suppress read of ~/.irbrc + -m Bc mode (load mathn, fraction or matrix are available) + -d Set $DEBUG to true (same as `ruby -d') + -r load-module Same as `ruby -r' + -I path Specify $LOAD_PATH directory + --inspect Use `inspect' for output (default except for bc mode) + --noinspect Don't use inspect for output + --readline Use Readline extension module + --noreadline Don't use Readline extension module + --prompt prompt-mode + --prompt-mode prompt-mode + Switch prompt mode. Pre-defined prompt modes are + `default', `simple', `xmp' and `inf-ruby' + --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs. + Suppresses --readline. + --simple-prompt Simple prompt mode + --noprompt No prompt mode + --tracer Display trace for each execution of commands. + --back-trace-limit n + Display backtrace top n and tail n. The default + value is 16. + --irb_debug n Set internal debug level to n (not for popular use) + -v, --version Print the version of irb diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/ja/error.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/ja/error.rb new file mode 100644 index 00000000..b8652b56 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/ja/error.rb @@ -0,0 +1,27 @@ +# +# irb/lc/ja/error.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +require "e2mmap" + +module IRB + # exceptions + extend Exception2MessageMapper + def_exception :UnrecognizedSwitch, '$B%9%$%C%A(B(%s)$B$,J,$j$^$;$s(B' + def_exception :NotImplementedError, '`%s\'$B$NDj5A$,I,MW$G$9(B' + def_exception :CantReturnToNormalMode, 'Normal$B%b!<%I$KLa$l$^$;$s(B.' + def_exception :IllegalParameter, '$B%Q%i%a!<%?(B(%s)$B$,4V0c$C$F$$$^$9(B.' + def_exception :IrbAlreadyDead, 'Irb$B$O4{$K;`$s$G$$$^$9(B.' + def_exception :IrbSwitchedToCurrentThread, '$B%+%l%s%H%9%l%C%I$K@Z$jBX$o$j$^$7$?(B.' + def_exception :NoSuchJob, '$B$=$N$h$&$J%8%g%V(B(%s)$B$O$"$j$^$;$s(B.' + def_exception :CantShiftToMultiIrbMode, 'multi-irb mode$B$K0\$l$^$;$s(B.' + def_exception :CantChangeBinding, '$B%P%$%s%G%#%s%0(B(%s)$B$KJQ99$G$-$^$;$s(B.' + def_exception :UndefinedPromptMode, '$B%W%m%s%W%H%b!<%I(B(%s)$B$ODj5A$5$l$F$$$^$;$s(B.' +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/ja/help-message b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/ja/help-message new file mode 100644 index 00000000..719796ce --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/lc/ja/help-message @@ -0,0 +1,36 @@ +# +# irb/lc/ja/help-message.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +Usage: irb.rb [options] [programfile] [arguments] + -f ~/.irbrc $B$rFI$_9~$^$J$$(B. + -m bc$B%b!<%I(B($BJ,?t(B, $B9TNs$N7W;;$,$G$-$k(B) + -d $DEBUG $B$r(Btrue$B$K$9$k(B(ruby -d $B$HF1$8(B) + -r load-module ruby -r $B$HF1$8(B. + -I path $LOAD_PATH $B$K(B path $B$rDI2C$9$k(B. + --inspect $B7k2L=PNO$K(Binspect$B$rMQ$$$k(B(bc$B%b!<%I0J30$O%G%U%)%k%H(B). + --noinspect $B7k2L=PNO$K(Binspect$B$rMQ$$$J$$(B. + --readline readline$B%i%$%V%i%j$rMxMQ$9$k(B. + --noreadline readline$B%i%$%V%i%j$rMxMQ$7$J$$(B. + --prompt prompt-mode/--prompt-mode prompt-mode + $B%W%m%s%W%H%b!<%I$r@ZBX$($^$9(B. $B8=:_Dj5A$5$l$F$$$k%W(B + $B%m%s%W%H%b!<%I$O(B, default, simple, xmp, inf-ruby$B$,(B + $BMQ0U$5$l$F$$$^$9(B. + --inf-ruby-mode emacs$B$N(Binf-ruby-mode$BMQ$N%W%m%s%W%HI=<($r9T$J$&(B. $BFC(B + $B$K;XDj$,$J$$8B$j(B, readline$B%i%$%V%i%j$O;H$o$J$/$J$k(B. + --simple-prompt $BHs>o$K%7%s%W%k$J%W%m%s%W%H$rMQ$$$k%b!<%I$G$9(B. + --noprompt $B%W%m%s%W%HI=<($r9T$J$o$J$$(B. + --tracer $B%3%^%s%I(other) + @level <=> other.level + end + + def notify? + @base_notifier.level >= self + end + end + + class NoMsgNotifier [#0- +] + # <ºÇ¾®¥Õ¥£¡¼¥ë¥ÉÉý> (\*|\*[1-9][0-9]*\$|[1-9][0-9]*) + # <ÀºÅÙ>.(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)? + # #<Ťµ½¤ÀµÊ¸»ú>(hh|h|l|ll|L|q|j|z|t) + # <ÊÑ´¹½¤ÀµÊ¸»ú>[diouxXeEfgGcsb%] + def parse_printf_format(format, opts) + return format, opts if $1.size % 2 == 1 + end + + def foo(format) + pos = 0 + inspects = [] + format.scan(/%[#0\-+ ]?(\*(?=[^0-9])|\*[1-9][0-9]*\$|[1-9][0-9]*(?=[^0-9]))?(\.(\*(?=[^0-9])|\*[1-9][0-9]*\$|[1-9][0-9]*(?=[^0-9])))?(([1-9][0-9]*\$)*)([diouxXeEfgGcsb%])/) {|f, p, pp, pos, new_pos, c| + puts [f, p, pp, pos, new_pos, c].join("!") + pos = new_pos if new_pos + if c == "I" + inspects.push pos.to_i + (f||"")+(p||"")+(pp||"")+(pos||"")+"s" + else + $& + end + } + end + + def puts(*objs) + for obj in objs + print(*obj) + print "\n" + end + end + + def pp(*objs) + puts(*objs.collect{|obj| obj.inspect}) + end + + def ppx(prefix, *objs) + puts(*objs.collect{|obj| prefix+obj.inspect}) + end + + end + + class StdioOutputMethod 0 + end + end + @debug_level = 0 + + def initialize + lex_init + set_input(STDIN) + + @seek = 0 + @exp_line_no = @line_no = 1 + @base_char_no = 0 + @char_no = 0 + @rests = [] + @readed = [] + @here_readed = [] + + @indent = 0 + @indent_stack = [] + @lex_state = EXPR_BEG + @space_seen = false + @here_header = false + + @continue = false + @line = "" + + @skip_space = false + @readed_auto_clean_up = false + @exception_on_syntax_error = true + + @prompt = nil + end + + attr_accessor :skip_space + attr_accessor :readed_auto_clean_up + attr_accessor :exception_on_syntax_error + + attr_reader :seek + attr_reader :char_no + attr_reader :line_no + attr_reader :indent + + # io functions + def set_input(io, p = nil, &block) + @io = io + if p.respond_to?(:call) + @input = p + elsif block_given? + @input = block + else + @input = Proc.new{@io.gets} + end + end + + def get_readed + if idx = @readed.reverse.index("\n") + @base_char_no = idx + else + @base_char_no += @readed.size + end + + readed = @readed.join("") + @readed = [] + readed + end + + def getc + while @rests.empty? +# return nil unless buf_input + @rests.push nil unless buf_input + end + c = @rests.shift + if @here_header + @here_readed.push c + else + @readed.push c + end + @seek += 1 + if c == "\n" + @line_no += 1 + @char_no = 0 + else + @char_no += 1 + end + c + end + + def gets + l = "" + while c = getc + l.concat(c) + break if c == "\n" + end + return nil if l == "" and c.nil? + l + end + + def eof? + @io.eof? + end + + def getc_of_rests + if @rests.empty? + nil + else + getc + end + end + + def ungetc(c = nil) + if @here_readed.empty? + c2 = @readed.pop + else + c2 = @here_readed.pop + end + c = c2 unless c + @rests.unshift c #c = + @seek -= 1 + if c == "\n" + @line_no -= 1 + if idx = @readed.reverse.index("\n") + @char_no = @readed.size - idx + else + @char_no = @base_char_no + @readed.size + end + else + @char_no -= 1 + end + end + + def peek_equal?(str) + chrs = str.split(//) + until @rests.size >= chrs.size + return false unless buf_input + end + @rests[0, chrs.size] == chrs + end + + def peek_match?(regexp) + while @rests.empty? + return false unless buf_input + end + regexp =~ @rests.join("") + end + + def peek(i = 0) + while @rests.size <= i + return nil unless buf_input + end + @rests[i] + end + + def buf_input + prompt + line = @input.call + return nil unless line + @rests.concat line.split(//) + true + end + private :buf_input + + def set_prompt(p = nil, &block) + p = block if block_given? + if p.respond_to?(:call) + @prompt = p + else + @prompt = Proc.new{print p} + end + end + + def prompt + if @prompt + @prompt.call(@ltype, @indent, @continue, @line_no) + end + end + + def initialize_input + @ltype = nil + @quoted = nil + @indent = 0 + @indent_stack = [] + @lex_state = EXPR_BEG + @space_seen = false + @here_header = false + + @continue = false + prompt + + @line = "" + @exp_line_no = @line_no + end + + def each_top_level_statement + initialize_input + catch(:TERM_INPUT) do + loop do + begin + @continue = false + prompt + unless l = lex + throw :TERM_INPUT if @line == '' + else + #p l + @line.concat l + if @ltype or @continue or @indent > 0 + next + end + end + if @line != "\n" + yield @line, @exp_line_no + end + break unless l + @line = '' + @exp_line_no = @line_no + + @indent = 0 + @indent_stack = [] + prompt + rescue TerminateLineInput + initialize_input + prompt + get_readed + end + end + end + end + + def lex + until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) && + !@continue or + tk.nil?) + #p tk + #p @lex_state + #p self + end + line = get_readed + # print self.inspect + if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil? + nil + else + line + end + end + + def token + # require "tracer" + # Tracer.on + @prev_seek = @seek + @prev_line_no = @line_no + @prev_char_no = @char_no + begin + begin + tk = @OP.match(self) + @space_seen = tk.kind_of?(TkSPACE) + rescue SyntaxError + raise if @exception_on_syntax_error + tk = TkError.new(@seek, @line_no, @char_no) + end + end while @skip_space and tk.kind_of?(TkSPACE) + if @readed_auto_clean_up + get_readed + end + # Tracer.off + tk + end + + ENINDENT_CLAUSE = [ + "case", "class", "def", "do", "for", "if", + "module", "unless", "until", "while", "begin" #, "when" + ] + DEINDENT_CLAUSE = ["end" #, "when" + ] + + PERCENT_LTYPE = { + "q" => "\'", + "Q" => "\"", + "x" => "\`", + "r" => "/", + "w" => "]", + "W" => "]", + "s" => ":" + } + + PERCENT_PAREN = { + "{" => "}", + "[" => "]", + "<" => ">", + "(" => ")" + } + + Ltype2Token = { + "\'" => TkSTRING, + "\"" => TkSTRING, + "\`" => TkXSTRING, + "/" => TkREGEXP, + "]" => TkDSTRING, + ":" => TkSYMBOL + } + DLtype2Token = { + "\"" => TkDSTRING, + "\`" => TkDXSTRING, + "/" => TkDREGEXP, + } + + def lex_init() + @OP = IRB::SLex.new + @OP.def_rules("\0", "\004", "\032") do |op, io| + Token(TkEND_OF_SCRIPT) + end + + @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |op, io| + @space_seen = true + while getc =~ /[ \t\f\r\13]/; end + ungetc + Token(TkSPACE) + end + + @OP.def_rule("#") do |op, io| + identify_comment + end + + @OP.def_rule("=begin", + proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do + |op, io| + @ltype = "=" + until getc == "\n"; end + until peek_equal?("=end") && peek(4) =~ /\s/ + until getc == "\n"; end + end + gets + @ltype = nil + Token(TkRD_COMMENT) + end + + @OP.def_rule("\n") do |op, io| + print "\\n\n" if RubyLex.debug? + case @lex_state + when EXPR_BEG, EXPR_FNAME, EXPR_DOT + @continue = true + else + @continue = false + @lex_state = EXPR_BEG + until (@indent_stack.empty? || + [TkLPAREN, TkLBRACK, TkLBRACE, + TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) + @indent_stack.pop + end + end + @here_header = false + @here_readed = [] + Token(TkNL) + end + + @OP.def_rules("*", "**", + "=", "==", "===", + "=~", "<=>", + "<", "<=", + ">", ">=", ">>") do + |op, io| + case @lex_state + when EXPR_FNAME, EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_BEG + end + Token(op) + end + + @OP.def_rules("!", "!=", "!~") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + @OP.def_rules("<<") do + |op, io| + tk = nil + if @lex_state != EXPR_END && @lex_state != EXPR_CLASS && + (@lex_state != EXPR_ARG || @space_seen) + c = peek(0) + if /\S/ =~ c && (/["'`]/ =~ c || /[\w_]/ =~ c || c == "-") + tk = identify_here_document + end + end + unless tk + tk = Token(op) + case @lex_state + when EXPR_FNAME, EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_BEG + end + end + tk + end + + @OP.def_rules("'", '"') do + |op, io| + identify_string(op) + end + + @OP.def_rules("`") do + |op, io| + if @lex_state == EXPR_FNAME + @lex_state = EXPR_END + Token(op) + else + identify_string(op) + end + end + + @OP.def_rules('?') do + |op, io| + if @lex_state == EXPR_END + @lex_state = EXPR_BEG + Token(TkQUESTION) + else + ch = getc + if @lex_state == EXPR_ARG && ch =~ /\s/ + ungetc + @lex_state = EXPR_BEG; + Token(TkQUESTION) + else + if (ch == '\\') + read_escape + end + @lex_state = EXPR_END + Token(TkINTEGER) + end + end + end + + @OP.def_rules("&", "&&", "|", "||") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + @OP.def_rules("+=", "-=", "*=", "**=", + "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do + |op, io| + @lex_state = EXPR_BEG + op =~ /^(.*)=$/ + Token(TkOPASGN, $1) + end + + @OP.def_rule("+@", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token(op) + end + + @OP.def_rule("-@", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token(op) + end + + @OP.def_rules("+", "-") do + |op, io| + catch(:RET) do + if @lex_state == EXPR_ARG + if @space_seen and peek(0) =~ /[0-9]/ + throw :RET, identify_number + else + @lex_state = EXPR_BEG + end + elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/ + throw :RET, identify_number + else + @lex_state = EXPR_BEG + end + Token(op) + end + end + + @OP.def_rule(".") do + |op, io| + @lex_state = EXPR_BEG + if peek(0) =~ /[0-9]/ + ungetc + identify_number + else + # for "obj.if" etc. + @lex_state = EXPR_DOT + Token(TkDOT) + end + end + + @OP.def_rules("..", "...") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + lex_int2 + end + + def lex_int2 + @OP.def_rules("]", "}", ")") do + |op, io| + @lex_state = EXPR_END + @indent -= 1 + @indent_stack.pop + Token(op) + end + + @OP.def_rule(":") do + |op, io| + if @lex_state == EXPR_END || peek(0) =~ /\s/ + @lex_state = EXPR_BEG + Token(TkCOLON) + else + @lex_state = EXPR_FNAME; + Token(TkSYMBEG) + end + end + + @OP.def_rule("::") do + |op, io| +# p @lex_state.id2name, @space_seen + if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen + @lex_state = EXPR_BEG + Token(TkCOLON3) + else + @lex_state = EXPR_DOT + Token(TkCOLON2) + end + end + + @OP.def_rule("/") do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_string(op) + elsif peek(0) == '=' + getc + @lex_state = EXPR_BEG + Token(TkOPASGN, "/") #/) + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_string(op) + else + @lex_state = EXPR_BEG + Token("/") #/) + end + end + + @OP.def_rules("^") do + |op, io| + @lex_state = EXPR_BEG + Token("^") + end + + # @OP.def_rules("^=") do + # @lex_state = EXPR_BEG + # Token(OP_ASGN, :^) + # end + + @OP.def_rules(",") do + |op, io| + @lex_state = EXPR_BEG + Token(op) + end + + @OP.def_rules(";") do + |op, io| + @lex_state = EXPR_BEG + until (@indent_stack.empty? || + [TkLPAREN, TkLBRACK, TkLBRACE, + TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) + @indent_stack.pop + end + Token(op) + end + + @OP.def_rule("~") do + |op, io| + @lex_state = EXPR_BEG + Token("~") + end + + @OP.def_rule("~@", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_BEG + Token("~") + end + + @OP.def_rule("(") do + |op, io| + @indent += 1 + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + @lex_state = EXPR_BEG + tk_c = TkfLPAREN + else + @lex_state = EXPR_BEG + tk_c = TkLPAREN + end + @indent_stack.push tk_c + tk = Token(tk_c) + end + + @OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token("[]") + end + + @OP.def_rule("[]=", proc{|op, io| @lex_state == EXPR_FNAME}) do + |op, io| + @lex_state = EXPR_ARG + Token("[]=") + end + + @OP.def_rule("[") do + |op, io| + @indent += 1 + if @lex_state == EXPR_FNAME + tk_c = TkfLBRACK + else + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + tk_c = TkLBRACK + elsif @lex_state == EXPR_ARG && @space_seen + tk_c = TkLBRACK + else + tk_c = TkfLBRACK + end + @lex_state = EXPR_BEG + end + @indent_stack.push tk_c + Token(tk_c) + end + + @OP.def_rule("{") do + |op, io| + @indent += 1 + if @lex_state != EXPR_END && @lex_state != EXPR_ARG + tk_c = TkLBRACE + else + tk_c = TkfLBRACE + end + @lex_state = EXPR_BEG + @indent_stack.push tk_c + Token(tk_c) + end + + @OP.def_rule('\\') do + |op, io| + if getc == "\n" + @space_seen = true + @continue = true + Token(TkSPACE) + else + ungetc + Token("\\") + end + end + + @OP.def_rule('%') do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_quotation + elsif peek(0) == '=' + getc + Token(TkOPASGN, :%) + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_quotation + else + @lex_state = EXPR_BEG + Token("%") #)) + end + end + + @OP.def_rule('$') do + |op, io| + identify_gvar + end + + @OP.def_rule('@') do + |op, io| + if peek(0) =~ /[\w_@]/ + ungetc + identify_identifier + else + Token("@") + end + end + + # @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do + # |op, io| + # @indent += 1 + # @lex_state = EXPR_FNAME + # # @lex_state = EXPR_END + # # until @rests[0] == "\n" or @rests[0] == ";" + # # rests.shift + # # end + # end + + @OP.def_rule("") do + |op, io| + printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug? + if peek(0) =~ /[0-9]/ + t = identify_number + elsif peek(0) =~ /[\w_]/ + t = identify_identifier + end + printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug? + t + end + + p @OP if RubyLex.debug? + end + + def identify_gvar + @lex_state = EXPR_END + + case ch = getc + when /[~_*$?!@\/\\;,=:<>".]/ #" + Token(TkGVAR, "$" + ch) + when "-" + Token(TkGVAR, "$-" + getc) + when "&", "`", "'", "+" + Token(TkBACK_REF, "$"+ch) + when /[1-9]/ + while getc =~ /[0-9]/; end + ungetc + Token(TkNTH_REF) + when /\w/ + ungetc + ungetc + identify_identifier + else + ungetc + Token("$") + end + end + + def identify_identifier + token = "" + if peek(0) =~ /[$@]/ + token.concat(c = getc) + if c == "@" and peek(0) == "@" + token.concat getc + end + end + + while (ch = getc) =~ /\w|_/ + print ":", ch, ":" if RubyLex.debug? + token.concat ch + end + ungetc + + if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "=" + token.concat getc + end + + # almost fix token + + case token + when /^\$/ + return Token(TkGVAR, token) + when /^\@\@/ + @lex_state = EXPR_END + # p Token(TkCVAR, token) + return Token(TkCVAR, token) + when /^\@/ + @lex_state = EXPR_END + return Token(TkIVAR, token) + end + + if @lex_state != EXPR_DOT + print token, "\n" if RubyLex.debug? + + token_c, *trans = TkReading2Token[token] + if token_c + # reserved word? + + if (@lex_state != EXPR_BEG && + @lex_state != EXPR_FNAME && + trans[1]) + # modifiers + token_c = TkSymbol2Token[trans[1]] + @lex_state = trans[0] + else + if @lex_state != EXPR_FNAME + if ENINDENT_CLAUSE.include?(token) + # check for ``class = val'' etc. + valid = true + case token + when "class" + valid = false unless peek_match?(/^\s*(<<|\w|::)/) + when "def" + valid = false if peek_match?(/^\s*(([+-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/) + when "do" + valid = false if peek_match?(/^\s*([+-\/*]?=|\*|<|>|\&)/) + when *ENINDENT_CLAUSE + valid = false if peek_match?(/^\s*([+-\/*]?=|\*|<|>|\&|\|)/) + else + # no nothing + end + if valid + if token == "do" + if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last) + @indent += 1 + @indent_stack.push token_c + end + else + @indent += 1 + @indent_stack.push token_c + end +# p @indent_stack + end + + elsif DEINDENT_CLAUSE.include?(token) + @indent -= 1 + @indent_stack.pop + end + @lex_state = trans[0] + else + @lex_state = EXPR_END + end + end + return Token(token_c, token) + end + end + + if @lex_state == EXPR_FNAME + @lex_state = EXPR_END + if peek(0) == '=' + token.concat getc + end + elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_END + end + + if token[0, 1] =~ /[A-Z]/ + return Token(TkCONSTANT, token) + elsif token[token.size - 1, 1] =~ /[!?]/ + return Token(TkFID, token) + else + return Token(TkIDENTIFIER, token) + end + end + + def identify_here_document + ch = getc +# if lt = PERCENT_LTYPE[ch] + if ch == "-" + ch = getc + indent = true + end + if /['"`]/ =~ ch + lt = ch + quoted = "" + while (c = getc) && c != lt + quoted.concat c + end + else + lt = '"' + quoted = ch.dup + while (c = getc) && c =~ /\w/ + quoted.concat c + end + ungetc + end + + ltback, @ltype = @ltype, lt + reserve = [] + while ch = getc + reserve.push ch + if ch == "\\" + reserve.push ch = getc + elsif ch == "\n" + break + end + end + + @here_header = false + while l = gets + l = l.sub(/(:?\r)?\n\z/, '') + if (indent ? l.strip : l) == quoted + break + end + end + + @here_header = true + @here_readed.concat reserve + while ch = reserve.pop + ungetc ch + end + + @ltype = ltback + @lex_state = EXPR_END + Token(Ltype2Token[lt]) + end + + def identify_quotation + ch = getc + if lt = PERCENT_LTYPE[ch] + ch = getc + elsif ch =~ /\W/ + lt = "\"" + else + RubyLex.fail SyntaxError, "unknown type of %string" + end +# if ch !~ /\W/ +# ungetc +# next +# end + #@ltype = lt + @quoted = ch unless @quoted = PERCENT_PAREN[ch] + identify_string(lt, @quoted) + end + + def identify_number + @lex_state = EXPR_END + + if peek(0) == "0" && peek(1) !~ /[.eE]/ + getc + case peek(0) + when /[xX]/ + ch = getc + match = /[0-9a-fA-F_]/ + when /[bB]/ + ch = getc + match = /[01_]/ + when /[oO]/ + ch = getc + match = /[0-7_]/ + when /[dD]/ + ch = getc + match = /[0-9_]/ + when /[0-7]/ + match = /[0-7_]/ + when /[89]/ + RubyLex.fail SyntaxError, "Illegal octal digit" + else + return Token(TkINTEGER) + end + + len0 = true + non_digit = false + while ch = getc + if match =~ ch + if ch == "_" + if non_digit + RubyLex.fail SyntaxError, "trailing `#{ch}' in number" + else + non_digit = ch + end + else + non_digit = false + len0 = false + end + else + ungetc + if len0 + RubyLex.fail SyntaxError, "numeric literal without digits" + end + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + break + end + end + return Token(TkINTEGER) + end + + type = TkINTEGER + allow_point = true + allow_e = true + non_digit = false + while ch = getc + case ch + when /[0-9]/ + non_digit = false + when "_" + non_digit = ch + when allow_point && "." + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + type = TkFLOAT + if peek(0) !~ /[0-9]/ + type = TkINTEGER + ungetc + break + end + allow_point = false + when allow_e && "e", allow_e && "E" + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + type = TkFLOAT + if peek(0) =~ /[+-]/ + getc + end + allow_e = false + allow_point = false + non_digit = ch + else + if non_digit + RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" + end + ungetc + break + end + end + Token(type) + end + + def identify_string(ltype, quoted = ltype) + @ltype = ltype + @quoted = quoted + subtype = nil + begin + nest = 0 + while ch = getc + if @quoted == ch and nest == 0 + break + elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#" + subtype = true + elsif ch == '\\' #' + read_escape + end + if PERCENT_PAREN.values.include?(@quoted) + if PERCENT_PAREN[ch] == @quoted + nest += 1 + elsif ch == @quoted + nest -= 1 + end + end + end + if @ltype == "/" + if peek(0) =~ /i|m|x|o|e|s|u|n/ + getc + end + end + if subtype + Token(DLtype2Token[ltype]) + else + Token(Ltype2Token[ltype]) + end + ensure + @ltype = nil + @quoted = nil + @lex_state = EXPR_END + end + end + + def identify_comment + @ltype = "#" + + while ch = getc +# if ch == "\\" #" +# read_escape +# end + if ch == "\n" + @ltype = nil + ungetc + break + end + end + return Token(TkCOMMENT) + end + + def read_escape + case ch = getc + when "\n", "\r", "\f" + when "\\", "n", "t", "r", "f", "v", "a", "e", "b", "s" #" + when /[0-7]/ + ungetc ch + 3.times do + case ch = getc + when /[0-7]/ + when nil + break + else + ungetc + break + end + end + + when "x" + 2.times do + case ch = getc + when /[0-9a-fA-F]/ + when nil + break + else + ungetc + break + end + end + + when "M" + if (ch = getc) != '-' + ungetc + else + if (ch = getc) == "\\" #" + read_escape + end + end + + when "C", "c" #, "^" + if ch == "C" and (ch = getc) != "-" + ungetc + elsif (ch = getc) == "\\" #" + read_escape + end + else + # other characters + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ruby-token.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ruby-token.rb new file mode 100644 index 00000000..32308bf9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/ruby-token.rb @@ -0,0 +1,273 @@ +# +# irb/ruby-token.rb - ruby tokens +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +module RubyToken + EXPR_BEG = :EXPR_BEG + EXPR_MID = :EXPR_MID + EXPR_END = :EXPR_END + EXPR_ARG = :EXPR_ARG + EXPR_FNAME = :EXPR_FNAME + EXPR_DOT = :EXPR_DOT + EXPR_CLASS = :EXPR_CLASS + + # for ruby 1.4X + if !defined?(Symbol) + Symbol = Integer + end + + class Token + def initialize(seek, line_no, char_no) + @seek = seek + @line_no = line_no + @char_no = char_no + end + attr :seek + attr :line_no + attr :char_no + end + + class TkNode < Token + def initialize(seek, line_no, char_no) + super + end + attr :node + end + + class TkId < Token + def initialize(seek, line_no, char_no, name) + super(seek, line_no, char_no) + @name = name + end + attr :name + end + + class TkVal < Token + def initialize(seek, line_no, char_no, value = nil) + super(seek, line_no, char_no) + @value = value + end + attr :value + end + + class TkOp < Token + attr :name, true + end + + class TkOPASGN < TkOp + def initialize(seek, line_no, char_no, op) + super(seek, line_no, char_no) + op = TkReading2Token[op][0] unless op.kind_of?(Symbol) + @op = op + end + attr :op + end + + class TkUnknownChar < Token + def initialize(seek, line_no, char_no, id) + super(seek, line_no, char_no) + @name = name + end + attr :name + end + + class TkError < Token + end + + def Token(token, value = nil) + case token + when String + if (tk = TkReading2Token[token]).nil? + IRB.fail TkReading2TokenNoKey, token + end + tk = Token(tk[0], value) + if tk.kind_of?(TkOp) + tk.name = token + end + return tk + when Symbol + if (tk = TkSymbol2Token[token]).nil? + IRB.fail TkSymbol2TokenNoKey, token + end + return Token(tk[0], value) + else + if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty? + token.new(@prev_seek, @prev_line_no, @prev_char_no) + else + token.new(@prev_seek, @prev_line_no, @prev_char_no, value) + end + end + end + + TokenDefinitions = [ + [:TkCLASS, TkId, "class", EXPR_CLASS], + [:TkMODULE, TkId, "module", EXPR_BEG], + [:TkDEF, TkId, "def", EXPR_FNAME], + [:TkUNDEF, TkId, "undef", EXPR_FNAME], + [:TkBEGIN, TkId, "begin", EXPR_BEG], + [:TkRESCUE, TkId, "rescue", EXPR_MID], + [:TkENSURE, TkId, "ensure", EXPR_BEG], + [:TkEND, TkId, "end", EXPR_END], + [:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD], + [:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD], + [:TkTHEN, TkId, "then", EXPR_BEG], + [:TkELSIF, TkId, "elsif", EXPR_BEG], + [:TkELSE, TkId, "else", EXPR_BEG], + [:TkCASE, TkId, "case", EXPR_BEG], + [:TkWHEN, TkId, "when", EXPR_BEG], + [:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD], + [:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD], + [:TkFOR, TkId, "for", EXPR_BEG], + [:TkBREAK, TkId, "break", EXPR_END], + [:TkNEXT, TkId, "next", EXPR_END], + [:TkREDO, TkId, "redo", EXPR_END], + [:TkRETRY, TkId, "retry", EXPR_END], + [:TkIN, TkId, "in", EXPR_BEG], + [:TkDO, TkId, "do", EXPR_BEG], + [:TkRETURN, TkId, "return", EXPR_MID], + [:TkYIELD, TkId, "yield", EXPR_END], + [:TkSUPER, TkId, "super", EXPR_END], + [:TkSELF, TkId, "self", EXPR_END], + [:TkNIL, TkId, "nil", EXPR_END], + [:TkTRUE, TkId, "true", EXPR_END], + [:TkFALSE, TkId, "false", EXPR_END], + [:TkAND, TkId, "and", EXPR_BEG], + [:TkOR, TkId, "or", EXPR_BEG], + [:TkNOT, TkId, "not", EXPR_BEG], + [:TkIF_MOD, TkId], + [:TkUNLESS_MOD, TkId], + [:TkWHILE_MOD, TkId], + [:TkUNTIL_MOD, TkId], + [:TkALIAS, TkId, "alias", EXPR_FNAME], + [:TkDEFINED, TkId, "defined?", EXPR_END], + [:TklBEGIN, TkId, "BEGIN", EXPR_END], + [:TklEND, TkId, "END", EXPR_END], + [:Tk__LINE__, TkId, "__LINE__", EXPR_END], + [:Tk__FILE__, TkId, "__FILE__", EXPR_END], + + [:TkIDENTIFIER, TkId], + [:TkFID, TkId], + [:TkGVAR, TkId], + [:TkCVAR, TkId], + [:TkIVAR, TkId], + [:TkCONSTANT, TkId], + + [:TkINTEGER, TkVal], + [:TkFLOAT, TkVal], + [:TkSTRING, TkVal], + [:TkXSTRING, TkVal], + [:TkREGEXP, TkVal], + [:TkSYMBOL, TkVal], + + [:TkDSTRING, TkNode], + [:TkDXSTRING, TkNode], + [:TkDREGEXP, TkNode], + [:TkNTH_REF, TkNode], + [:TkBACK_REF, TkNode], + + [:TkUPLUS, TkOp, "+@"], + [:TkUMINUS, TkOp, "-@"], + [:TkPOW, TkOp, "**"], + [:TkCMP, TkOp, "<=>"], + [:TkEQ, TkOp, "=="], + [:TkEQQ, TkOp, "==="], + [:TkNEQ, TkOp, "!="], + [:TkGEQ, TkOp, ">="], + [:TkLEQ, TkOp, "<="], + [:TkANDOP, TkOp, "&&"], + [:TkOROP, TkOp, "||"], + [:TkMATCH, TkOp, "=~"], + [:TkNMATCH, TkOp, "!~"], + [:TkDOT2, TkOp, ".."], + [:TkDOT3, TkOp, "..."], + [:TkAREF, TkOp, "[]"], + [:TkASET, TkOp, "[]="], + [:TkLSHFT, TkOp, "<<"], + [:TkRSHFT, TkOp, ">>"], + [:TkCOLON2, TkOp], + [:TkCOLON3, TkOp], +# [:OPASGN, TkOp], # +=, -= etc. # + [:TkASSOC, TkOp, "=>"], + [:TkQUESTION, TkOp, "?"], #? + [:TkCOLON, TkOp, ":"], #: + + [:TkfLPAREN], # func( # + [:TkfLBRACK], # func[ # + [:TkfLBRACE], # func{ # + [:TkSTAR], # *arg + [:TkAMPER], # &arg # + [:TkSYMBEG], # :SYMBOL + + [:TkGT, TkOp, ">"], + [:TkLT, TkOp, "<"], + [:TkPLUS, TkOp, "+"], + [:TkMINUS, TkOp, "-"], + [:TkMULT, TkOp, "*"], + [:TkDIV, TkOp, "/"], + [:TkMOD, TkOp, "%"], + [:TkBITOR, TkOp, "|"], + [:TkBITXOR, TkOp, "^"], + [:TkBITAND, TkOp, "&"], + [:TkBITNOT, TkOp, "~"], + [:TkNOTOP, TkOp, "!"], + + [:TkBACKQUOTE, TkOp, "`"], + + [:TkASSIGN, Token, "="], + [:TkDOT, Token, "."], + [:TkLPAREN, Token, "("], #(exp) + [:TkLBRACK, Token, "["], #[arry] + [:TkLBRACE, Token, "{"], #{hash} + [:TkRPAREN, Token, ")"], + [:TkRBRACK, Token, "]"], + [:TkRBRACE, Token, "}"], + [:TkCOMMA, Token, ","], + [:TkSEMICOLON, Token, ";"], + + [:TkCOMMENT], + [:TkRD_COMMENT], + [:TkSPACE], + [:TkNL], + [:TkEND_OF_SCRIPT], + + [:TkBACKSLASH, TkUnknownChar, "\\"], + [:TkAT, TkUnknownChar, "@"], + [:TkDOLLAR, TkUnknownChar, "$"], + ] + + # {reading => token_class} + # {reading => [token_class, *opt]} + TkReading2Token = {} + TkSymbol2Token = {} + + def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts) + token_n = token_n.id2name if token_n.kind_of?(Symbol) + if RubyToken.const_defined?(token_n) + IRB.fail AlreadyDefinedToken, token_n + end + token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}") + + if reading + if TkReading2Token[reading] + IRB.fail TkReading2TokenDuplicateError, token_n, reading + end + if opts.empty? + TkReading2Token[reading] = [token_c] + else + TkReading2Token[reading] = [token_c].concat(opts) + end + end + TkSymbol2Token[token_n.intern] = token_c + end + + for defs in TokenDefinitions + def_token(*defs) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/slex.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/slex.rb new file mode 100644 index 00000000..0b8eb24c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/slex.rb @@ -0,0 +1,285 @@ +# +# irb/slex.rb - symple lex analizer +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# + +require "e2mmap" +require "irb/notifier" + +module IRB + class SLex + @RCS_ID='-$Id: slex.rb 11708 2007-02-12 23:01:19Z shyouhei $-' + + extend Exception2MessageMapper + def_exception :ErrNodeNothing, "node nothing" + def_exception :ErrNodeAlreadyExists, "node already exists" + + DOUT = Notifier::def_notifier("SLex::") + D_WARN = DOUT::def_notifier(1, "Warn: ") + D_DEBUG = DOUT::def_notifier(2, "Debug: ") + D_DETAIL = DOUT::def_notifier(4, "Detail: ") + + DOUT.level = Notifier::D_NOMSG + + def initialize + @head = Node.new("") + end + + def def_rule(token, preproc = nil, postproc = nil, &block) + D_DETAIL.pp token + + postproc = block if block_given? + node = create(token, preproc, postproc) + end + + def def_rules(*tokens, &block) + if block_given? + p = block + end + for token in tokens + def_rule(token, nil, p) + end + end + + def preproc(token, proc) + node = search(token) + node.preproc=proc + end + + #$BMW%A%'%C%/(B? + def postproc(token) + node = search(token, proc) + node.postproc=proc + end + + def search(token) + @head.search(token.split(//)) + end + + def create(token, preproc = nil, postproc = nil) + @head.create_subnode(token.split(//), preproc, postproc) + end + + def match(token) + case token + when Array + when String + return match(token.split(//)) + else + return @head.match_io(token) + end + ret = @head.match(token) + D_DETAIL.exec_if{D_DEATIL.printf "match end: %s:%s\n", ret, token.inspect} + ret + end + + def inspect + format("", @head.inspect) + end + + #---------------------------------------------------------------------- + # + # class Node - + # + #---------------------------------------------------------------------- + class Node + # if postproc is nil, this node is an abstract node. + # if postproc is non-nil, this node is a real node. + def initialize(preproc = nil, postproc = nil) + @Tree = {} + @preproc = preproc + @postproc = postproc + end + + attr_accessor :preproc + attr_accessor :postproc + + def search(chrs, opt = nil) + return self if chrs.empty? + ch = chrs.shift + if node = @Tree[ch] + node.search(chrs, opt) + else + if opt + chrs.unshift ch + self.create_subnode(chrs) + else + SLex.fail ErrNodeNothing + end + end + end + + def create_subnode(chrs, preproc = nil, postproc = nil) + if chrs.empty? + if @postproc + D_DETAIL.pp node + SLex.fail ErrNodeAlreadyExists + else + D_DEBUG.puts "change abstract node to real node." + @preproc = preproc + @postproc = postproc + end + return self + end + + ch = chrs.shift + if node = @Tree[ch] + if chrs.empty? + if node.postproc + DebugLogger.pp node + DebugLogger.pp self + DebugLogger.pp ch + DebugLogger.pp chrs + SLex.fail ErrNodeAlreadyExists + else + D_WARN.puts "change abstract node to real node" + node.preproc = preproc + node.postproc = postproc + end + else + node.create_subnode(chrs, preproc, postproc) + end + else + if chrs.empty? + node = Node.new(preproc, postproc) + else + node = Node.new + node.create_subnode(chrs, preproc, postproc) + end + @Tree[ch] = node + end + node + end + + # + # chrs: String + # character array + # io must have getc()/ungetc(); and ungetc() must be + # able to be called arbitrary number of times. + # + def match(chrs, op = "") + D_DETAIL.print "match>: ", chrs, "op:", op, "\n" + if chrs.empty? + if @preproc.nil? || @preproc.call(op, chrs) + DOUT.printf(D_DETAIL, "op1: %s\n", op) + @postproc.call(op, chrs) + else + nil + end + else + ch = chrs.shift + if node = @Tree[ch] + if ret = node.match(chrs, op+ch) + return ret + else + chrs.unshift ch + if @postproc and @preproc.nil? || @preproc.call(op, chrs) + DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect) + ret = @postproc.call(op, chrs) + return ret + else + return nil + end + end + else + chrs.unshift ch + if @postproc and @preproc.nil? || @preproc.call(op, chrs) + DOUT.printf(D_DETAIL, "op3: %s\n", op) + @postproc.call(op, chrs) + return "" + else + return nil + end + end + end + end + + def match_io(io, op = "") + if op == "" + ch = io.getc + if ch == nil + return nil + end + else + ch = io.getc_of_rests + end + if ch.nil? + if @preproc.nil? || @preproc.call(op, io) + D_DETAIL.printf("op1: %s\n", op) + @postproc.call(op, io) + else + nil + end + else + if node = @Tree[ch] + if ret = node.match_io(io, op+ch) + ret + else + io.ungetc ch + if @postproc and @preproc.nil? || @preproc.call(op, io) + DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect} + @postproc.call(op, io) + else + nil + end + end + else + io.ungetc ch + if @postproc and @preproc.nil? || @preproc.call(op, io) + D_DETAIL.printf("op3: %s\n", op) + @postproc.call(op, io) + else + nil + end + end + end + end + end + end +end + +SLex=IRB::SLex + +if $0 == __FILE__ + # Tracer.on + case $1 + when "1" + tr = SLex.new + print "0: ", tr.inspect, "\n" + tr.def_rule("=") {print "=\n"} + print "1: ", tr.inspect, "\n" + tr.def_rule("==") {print "==\n"} + print "2: ", tr.inspect, "\n" + + print "case 1:\n" + print tr.match("="), "\n" + print "case 2:\n" + print tr.match("=="), "\n" + print "case 3:\n" + print tr.match("=>"), "\n" + + when "2" + tr = SLex.new + print "0: ", tr.inspect, "\n" + tr.def_rule("=") {print "=\n"} + print "1: ", tr.inspect, "\n" + tr.def_rule("==", proc{false}) {print "==\n"} + print "2: ", tr.inspect, "\n" + + print "case 1:\n" + print tr.match("="), "\n" + print "case 2:\n" + print tr.match("=="), "\n" + print "case 3:\n" + print tr.match("=>"), "\n" + end + exit +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/version.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/version.rb new file mode 100644 index 00000000..dc3646ef --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/version.rb @@ -0,0 +1,16 @@ +# +# irb/version.rb - irb version definition file +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# +# +# + +module IRB + @RELEASE_VERSION = "0.9.5" + @LAST_UPDATE_DATE = "05/04/13" +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/workspace.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/workspace.rb new file mode 100644 index 00000000..d1a3a3e6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/irb/workspace.rb @@ -0,0 +1,107 @@ +# +# irb/workspace-binding.rb - +# $Release Version: 0.9.5$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# -- +# +# +# +module IRB + class WorkSpace + # create new workspace. set self to main if specified, otherwise + # inherit main from TOPLEVEL_BINDING. + def initialize(*main) + if main[0].kind_of?(Binding) + @binding = main.shift + elsif IRB.conf[:SINGLE_IRB] + @binding = TOPLEVEL_BINDING + else + case IRB.conf[:CONTEXT_MODE] + when 0 # binding in proc on TOPLEVEL_BINDING + @binding = eval("proc{binding}.call", + TOPLEVEL_BINDING, + __FILE__, + __LINE__) + when 1 # binding in loaded file + require "tempfile" + f = Tempfile.open("irb-binding") + f.print <str to out_code. + # out_code and in_code are given as constants of Kconv. + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want to decode them, use NKF.nkf. + def kconv(str, out_code, in_code = AUTO) + opt = '-' + case in_code + when ::NKF::JIS + opt << 'J' + when ::NKF::EUC + opt << 'E' + when ::NKF::SJIS + opt << 'S' + when ::NKF::UTF8 + opt << 'W' + when ::NKF::UTF16 + opt << 'W16' + end + + case out_code + when ::NKF::JIS + opt << 'j' + when ::NKF::EUC + opt << 'e' + when ::NKF::SJIS + opt << 's' + when ::NKF::UTF8 + opt << 'w' + when ::NKF::UTF16 + opt << 'w16' + when ::NKF::NOCONV + return str + end + + opt = '' if opt == '-' + + ::NKF::nkf(opt, str) + end + module_function :kconv + + # + # Encode to + # + + # call-seq: + # Kconv.tojis(str) -> string + # + # Convert str to ISO-2022-JP + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-jxm0', str). + def tojis(str) + ::NKF::nkf('-jm', str) + end + module_function :tojis + + # call-seq: + # Kconv.toeuc(str) -> string + # + # Convert str to EUC-JP + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-exm0', str). + def toeuc(str) + ::NKF::nkf('-em', str) + end + module_function :toeuc + + # call-seq: + # Kconv.tosjis(str) -> string + # + # Convert str to Shift_JIS + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-sxm0', str). + def tosjis(str) + ::NKF::nkf('-sm', str) + end + module_function :tosjis + + # call-seq: + # Kconv.toutf8(str) -> string + # + # Convert str to UTF-8 + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-wxm0', str). + def toutf8(str) + ::NKF::nkf('-wm', str) + end + module_function :toutf8 + + # call-seq: + # Kconv.toutf16(str) -> string + # + # Convert str to UTF-16 + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-w16xm0', str). + def toutf16(str) + ::NKF::nkf('-w16m', str) + end + module_function :toutf16 + + # + # guess + # + + # call-seq: + # Kconv.guess(str) -> integer + # + # Guess input encoding by NKF.guess2 + def guess(str) + ::NKF::guess(str) + end + module_function :guess + + # call-seq: + # Kconv.guess_old(str) -> integer + # + # Guess input encoding by NKF.guess1 + def guess_old(str) + ::NKF::guess1(str) + end + module_function :guess_old + + # + # isEncoding + # + + # call-seq: + # Kconv.iseuc(str) -> obj or nil + # + # Returns whether input encoding is EUC-JP or not. + # + # *Note* don't expect this return value is MatchData. + def iseuc(str) + RegexpEucjp.match( str ) + end + module_function :iseuc + + # call-seq: + # Kconv.issjis(str) -> obj or nil + # + # Returns whether input encoding is Shift_JIS or not. + # + # *Note* don't expect this return value is MatchData. + def issjis(str) + RegexpShiftjis.match( str ) + end + module_function :issjis + + # call-seq: + # Kconv.isutf8(str) -> obj or nil + # + # Returns whether input encoding is UTF-8 or not. + # + # *Note* don't expect this return value is MatchData. + def isutf8(str) + RegexpUtf8.match( str ) + end + module_function :isutf8 + +end + +class String + # call-seq: + # String#kconv(out_code, in_code = Kconv::AUTO) + # + # Convert self to out_code. + # out_code and in_code are given as constants of Kconv. + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want to decode them, use NKF.nkf. + def kconv(out_code, in_code=Kconv::AUTO) + Kconv::kconv(self, out_code, in_code) + end + + # + # to Encoding + # + + # call-seq: + # String#tojis -> string + # + # Convert self to ISO-2022-JP + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-jxm0', str). + def tojis; Kconv.tojis(self) end + + # call-seq: + # String#toeuc -> string + # + # Convert self to EUC-JP + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-exm0', str). + def toeuc; Kconv.toeuc(self) end + + # call-seq: + # String#tosjis -> string + # + # Convert self to Shift_JIS + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-sxm0', str). + def tosjis; Kconv.tosjis(self) end + + # call-seq: + # String#toutf8 -> string + # + # Convert self to UTF-8 + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-wxm0', str). + def toutf8; Kconv.toutf8(self) end + + # call-seq: + # String#toutf16 -> string + # + # Convert self to UTF-16 + # + # *Note* + # This method decode MIME encoded string and + # convert halfwidth katakana to fullwidth katakana. + # If you don't want it, use NKF.nkf('-w16xm0', str). + def toutf16; Kconv.toutf16(self) end + + # + # is Encoding + # + + # call-seq: + # String#iseuc -> obj or nil + # + # Returns whether self's encoding is EUC-JP or not. + # + # *Note* don't expect this return value is MatchData. + def iseuc; Kconv.iseuc(self) end + + # call-seq: + # String#issjis -> obj or nil + # + # Returns whether self's encoding is Shift_JIS or not. + # + # *Note* don't expect this return value is MatchData. + def issjis; Kconv.issjis(self) end + + # call-seq: + # String#isutf8 -> obj or nil + # + # Returns whether self's encoding is UTF-8 or not. + # + # *Note* don't expect this return value is MatchData. + def isutf8; Kconv.isutf8(self) end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/logger.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/logger.rb new file mode 100644 index 00000000..6fdd6c88 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/logger.rb @@ -0,0 +1,703 @@ +# logger.rb - saimple logging utility +# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi . + +require 'monitor' + +# Simple logging utility. +# +# Author:: NAKAMURA, Hiroshi +# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair +# License:: +# You can redistribute it and/or modify it under the same terms of Ruby's +# license; either the dual license version in 2003, or any later version. +# Revision:: $Id: logger.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# +# == Description +# +# The Logger class provides a simple but sophisticated logging utility that +# anyone can use because it's included in the Ruby 1.8.x standard library. +# +# The HOWTOs below give a code-based overview of Logger's usage, but the basic +# concept is as follows. You create a Logger object (output to a file or +# elsewhere), and use it to log messages. The messages will have varying +# levels (+info+, +error+, etc), reflecting their varying importance. The +# levels, and their meanings, are: +# +# +FATAL+:: an unhandleable error that results in a program crash +# +ERROR+:: a handleable error condition +# +WARN+:: a warning +# +INFO+:: generic (useful) information about system operation +# +DEBUG+:: low-level information for developers +# +# So each message has a level, and the Logger itself has a level, which acts +# as a filter, so you can control the amount of information emitted from the +# logger without having to remove actual messages. +# +# For instance, in a production system, you may have your logger(s) set to +# +INFO+ (or +WARN+ if you don't want the log files growing large with +# repetitive information). When you are developing it, though, you probably +# want to know about the program's internal state, and would set them to +# +DEBUG+. +# +# === Example +# +# A simple example demonstrates the above explanation: +# +# log = Logger.new(STDOUT) +# log.level = Logger::WARN +# +# log.debug("Created logger") +# log.info("Program started") +# log.warn("Nothing to do!") +# +# begin +# File.each_line(path) do |line| +# unless line =~ /^(\w+) = (.*)$/ +# log.error("Line in wrong format: #{line}") +# end +# end +# rescue => err +# log.fatal("Caught exception; exiting") +# log.fatal(err) +# end +# +# Because the Logger's level is set to +WARN+, only the warning, error, and +# fatal messages are recorded. The debug and info messages are silently +# discarded. +# +# === Features +# +# There are several interesting features that Logger provides, like +# auto-rolling of log files, setting the format of log messages, and +# specifying a program name in conjunction with the message. The next section +# shows you how to achieve these things. +# +# +# == HOWTOs +# +# === How to create a logger +# +# The options below give you various choices, in more or less increasing +# complexity. +# +# 1. Create a logger which logs messages to STDERR/STDOUT. +# +# logger = Logger.new(STDERR) +# logger = Logger.new(STDOUT) +# +# 2. Create a logger for the file which has the specified name. +# +# logger = Logger.new('logfile.log') +# +# 3. Create a logger for the specified file. +# +# file = File.open('foo.log', File::WRONLY | File::APPEND) +# # To create new (and to remove old) logfile, add File::CREAT like; +# # file = open('foo.log', File::WRONLY | File::APPEND | File::CREAT) +# logger = Logger.new(file) +# +# 4. Create a logger which ages logfile once it reaches a certain size. Leave +# 10 "old log files" and each file is about 1,024,000 bytes. +# +# logger = Logger.new('foo.log', 10, 1024000) +# +# 5. Create a logger which ages logfile daily/weekly/monthly. +# +# logger = Logger.new('foo.log', 'daily') +# logger = Logger.new('foo.log', 'weekly') +# logger = Logger.new('foo.log', 'monthly') +# +# === How to log a message +# +# Notice the different methods (+fatal+, +error+, +info+) being used to log +# messages of various levels. Other methods in this family are +warn+ and +# +debug+. +add+ is used below to log a message of an arbitrary (perhaps +# dynamic) level. +# +# 1. Message in block. +# +# logger.fatal { "Argument 'foo' not given." } +# +# 2. Message as a string. +# +# logger.error "Argument #{ @foo } mismatch." +# +# 3. With progname. +# +# logger.info('initialize') { "Initializing..." } +# +# 4. With severity. +# +# logger.add(Logger::FATAL) { 'Fatal error!' } +# +# === How to close a logger +# +# logger.close +# +# === Setting severity threshold +# +# 1. Original interface. +# +# logger.sev_threshold = Logger::WARN +# +# 2. Log4r (somewhat) compatible interface. +# +# logger.level = Logger::INFO +# +# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN +# +# +# == Format +# +# Log messages are rendered in the output stream in a certain format. The +# default format and a sample are shown below: +# +# Log format: +# SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message +# +# Log sample: +# I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074] INFO -- Main: info. +# +# You may change the date and time format in this manner: +# +# logger.datetime_format = "%Y-%m-%d %H:%M:%S" +# # e.g. "2004-01-03 00:54:26" +# +# There is currently no supported way to change the overall format, but you may +# have some luck hacking the Format constant. +# + + +class Logger + VERSION = "1.2.6" + /: (\S+),v (\S+)/ =~ %q$Id: logger.rb 11708 2007-02-12 23:01:19Z shyouhei $ + ProgName = "#{$1}/#{$2}" + + class Error < RuntimeError; end + class ShiftingError < Error; end + + # Logging severity. + module Severity + DEBUG = 0 + INFO = 1 + WARN = 2 + ERROR = 3 + FATAL = 4 + UNKNOWN = 5 + end + include Severity + + # Logging severity threshold (e.g. Logger::INFO). + attr_accessor :level + + # Logging program name. + attr_accessor :progname + + # Logging date-time format (string passed to +strftime+). + def datetime_format=(datetime_format) + @default_formatter.datetime_format = datetime_format + end + + def datetime_format + @default_formatter.datetime_format + end + + # Logging formatter. formatter#call is invoked with 4 arguments; severity, + # time, progname and msg for each log. Bear in mind that time is a Time and + # msg is an Object that user passed and it could not be a String. It is + # expected to return a logdev#write-able Object. Default formatter is used + # when no formatter is set. + attr_accessor :formatter + + alias sev_threshold level + alias sev_threshold= level= + + # Returns +true+ iff the current severity level allows for the printing of + # +DEBUG+ messages. + def debug?; @level <= DEBUG; end + + # Returns +true+ iff the current severity level allows for the printing of + # +INFO+ messages. + def info?; @level <= INFO; end + + # Returns +true+ iff the current severity level allows for the printing of + # +WARN+ messages. + def warn?; @level <= WARN; end + + # Returns +true+ iff the current severity level allows for the printing of + # +ERROR+ messages. + def error?; @level <= ERROR; end + + # Returns +true+ iff the current severity level allows for the printing of + # +FATAL+ messages. + def fatal?; @level <= FATAL; end + + # + # === Synopsis + # + # Logger.new(name, shift_age = 7, shift_size = 1048576) + # Logger.new(name, shift_age = 'weekly') + # + # === Args + # + # +logdev+:: + # The log device. This is a filename (String) or IO object (typically + # +STDOUT+, +STDERR+, or an open file). + # +shift_age+:: + # Number of old log files to keep, *or* frequency of rotation (+daily+, + # +weekly+ or +monthly+). + # +shift_size+:: + # Maximum logfile size (only applies when +shift_age+ is a number). + # + # === Description + # + # Create an instance. + # + def initialize(logdev, shift_age = 0, shift_size = 1048576) + @progname = nil + @level = DEBUG + @default_formatter = Formatter.new + @formatter = nil + @logdev = nil + if logdev + @logdev = LogDevice.new(logdev, :shift_age => shift_age, + :shift_size => shift_size) + end + end + + # + # === Synopsis + # + # Logger#add(severity, message = nil, progname = nil) { ... } + # + # === Args + # + # +severity+:: + # Severity. Constants are defined in Logger namespace: +DEBUG+, +INFO+, + # +WARN+, +ERROR+, +FATAL+, or +UNKNOWN+. + # +message+:: + # The log message. A String or Exception. + # +progname+:: + # Program name string. Can be omitted. Treated as a message if no +message+ and + # +block+ are given. + # +block+:: + # Can be omitted. Called to get a message string if +message+ is nil. + # + # === Return + # + # +true+ if successful, +false+ otherwise. + # + # When the given severity is not high enough (for this particular logger), log + # no message, and return +true+. + # + # === Description + # + # Log a message if the given severity is high enough. This is the generic + # logging method. Users will be more inclined to use #debug, #info, #warn, + # #error, and #fatal. + # + # Message format: +message+ can be any object, but it has to be + # converted to a String in order to log it. Generally, +inspect+ is used + # if the given object is not a String. + # A special case is an +Exception+ object, which will be printed in detail, + # including message, class, and backtrace. See #msg2str for the + # implementation if required. + # + # === Bugs + # + # * Logfile is not locked. + # * Append open does not need to lock file. + # * But on the OS which supports multi I/O, records possibly be mixed. + # + def add(severity, message = nil, progname = nil, &block) + severity ||= UNKNOWN + if @logdev.nil? or severity < @level + return true + end + progname ||= @progname + if message.nil? + if block_given? + message = yield + else + message = progname + progname = @progname + end + end + @logdev.write( + format_message(format_severity(severity), Time.now, progname, message)) + true + end + alias log add + + # + # Dump given message to the log device without any formatting. If no log + # device exists, return +nil+. + # + def <<(msg) + unless @logdev.nil? + @logdev.write(msg) + end + end + + # + # Log a +DEBUG+ message. + # + # See #info for more information. + # + def debug(progname = nil, &block) + add(DEBUG, nil, progname, &block) + end + + # + # Log an +INFO+ message. + # + # The message can come either from the +progname+ argument or the +block+. If + # both are provided, then the +block+ is used as the message, and +progname+ + # is used as the program name. + # + # === Examples + # + # logger.info("MainApp") { "Received connection from #{ip}" } + # # ... + # logger.info "Waiting for input from user" + # # ... + # logger.info { "User typed #{input}" } + # + # You'll probably stick to the second form above, unless you want to provide a + # program name (which you can do with Logger#progname= as well). + # + # === Return + # + # See #add. + # + def info(progname = nil, &block) + add(INFO, nil, progname, &block) + end + + # + # Log a +WARN+ message. + # + # See #info for more information. + # + def warn(progname = nil, &block) + add(WARN, nil, progname, &block) + end + + # + # Log an +ERROR+ message. + # + # See #info for more information. + # + def error(progname = nil, &block) + add(ERROR, nil, progname, &block) + end + + # + # Log a +FATAL+ message. + # + # See #info for more information. + # + def fatal(progname = nil, &block) + add(FATAL, nil, progname, &block) + end + + # + # Log an +UNKNOWN+ message. This will be printed no matter what the logger + # level. + # + # See #info for more information. + # + def unknown(progname = nil, &block) + add(UNKNOWN, nil, progname, &block) + end + + # + # Close the logging device. + # + def close + @logdev.close if @logdev + end + +private + + # Severity label for logging. (max 5 char) + SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY) + + def format_severity(severity) + SEV_LABEL[severity] || 'ANY' + end + + def format_message(severity, datetime, progname, msg) + (@formatter || @default_formatter).call(severity, datetime, progname, msg) + end + + + class Formatter + Format = "%s, [%s#%d] %5s -- %s: %s\n" + + attr_accessor :datetime_format + + def initialize + @datetime_format = nil + end + + def call(severity, time, progname, msg) + Format % [severity[0..0], format_datetime(time), $$, severity, progname, + msg2str(msg)] + end + + private + + def format_datetime(time) + if @datetime_format.nil? + time.strftime("%Y-%m-%dT%H:%M:%S.") << "%06d " % time.usec + else + time.strftime(@datetime_format) + end + end + + def msg2str(msg) + case msg + when ::String + msg + when ::Exception + "#{ msg.message } (#{ msg.class })\n" << + (msg.backtrace || []).join("\n") + else + msg.inspect + end + end + end + + + class LogDevice + attr_reader :dev + attr_reader :filename + + class LogDeviceMutex + include MonitorMixin + end + + def initialize(log = nil, opt = {}) + @dev = @filename = @shift_age = @shift_size = nil + @mutex = LogDeviceMutex.new + if log.respond_to?(:write) and log.respond_to?(:close) + @dev = log + else + @dev = open_logfile(log) + @dev.sync = true + @filename = log + @shift_age = opt[:shift_age] || 7 + @shift_size = opt[:shift_size] || 1048576 + end + end + + def write(message) + @mutex.synchronize do + if @shift_age and @dev.respond_to?(:stat) + begin + check_shift_log + rescue + raise Logger::ShiftingError.new("Shifting failed. #{$!}") + end + end + @dev.write(message) + end + end + + def close + @mutex.synchronize do + @dev.close + end + end + + private + + def open_logfile(filename) + if (FileTest.exist?(filename)) + open(filename, (File::WRONLY | File::APPEND)) + else + create_logfile(filename) + end + end + + def create_logfile(filename) + logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT)) + logdev.sync = true + add_log_header(logdev) + logdev + end + + def add_log_header(file) + file.write( + "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName] + ) + end + + SiD = 24 * 60 * 60 + + def check_shift_log + if @shift_age.is_a?(Integer) + # Note: always returns false if '0'. + if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size) + shift_log_age + end + else + now = Time.now + if @dev.stat.mtime <= previous_period_end(now) + shift_log_period(now) + end + end + end + + def shift_log_age + (@shift_age-3).downto(0) do |i| + if FileTest.exist?("#{@filename}.#{i}") + File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}") + end + end + @dev.close + File.rename("#{@filename}", "#{@filename}.0") + @dev = create_logfile(@filename) + return true + end + + def shift_log_period(now) + postfix = previous_period_end(now).strftime("%Y%m%d") # YYYYMMDD + age_file = "#{@filename}.#{postfix}" + if FileTest.exist?(age_file) + raise RuntimeError.new("'#{ age_file }' already exists.") + end + @dev.close + File.rename("#{@filename}", age_file) + @dev = create_logfile(@filename) + return true + end + + def previous_period_end(now) + case @shift_age + when /^daily$/ + eod(now - 1 * SiD) + when /^weekly$/ + eod(now - ((now.wday + 1) * SiD)) + when /^monthly$/ + eod(now - now.mday * SiD) + else + now + end + end + + def eod(t) + Time.mktime(t.year, t.month, t.mday, 23, 59, 59) + end + end + + + # + # == Description + # + # Application -- Add logging support to your application. + # + # == Usage + # + # 1. Define your application class as a sub-class of this class. + # 2. Override 'run' method in your class to do many things. + # 3. Instantiate it and invoke 'start'. + # + # == Example + # + # class FooApp < Application + # def initialize(foo_app, application_specific, arguments) + # super('FooApp') # Name of the application. + # end + # + # def run + # ... + # log(WARN, 'warning', 'my_method1') + # ... + # @log.error('my_method2') { 'Error!' } + # ... + # end + # end + # + # status = FooApp.new(....).start + # + class Application + include Logger::Severity + + attr_reader :appname + attr_reader :logdev + + # + # == Synopsis + # + # Application.new(appname = '') + # + # == Args + # + # +appname+:: Name of the application. + # + # == Description + # + # Create an instance. Log device is +STDERR+ by default. This can be + # changed with #set_log. + # + def initialize(appname = nil) + @appname = appname + @log = Logger.new(STDERR) + @log.progname = @appname + @level = @log.level + end + + # + # Start the application. Return the status code. + # + def start + status = -1 + begin + log(INFO, "Start of #{ @appname }.") + status = run + rescue + log(FATAL, "Detected an exception. Stopping ... #{$!} (#{$!.class})\n" << $@.join("\n")) + ensure + log(INFO, "End of #{ @appname }. (status: #{ status.to_s })") + end + status + end + + # + # Sets the log device for this application. See the class Logger for an + # explanation of the arguments. + # + def set_log(logdev, shift_age = 0, shift_size = 1024000) + @log = Logger.new(logdev, shift_age, shift_size) + @log.progname = @appname + @log.level = @level + end + + def log=(logdev) + set_log(logdev) + end + + # + # Set the logging threshold, just like Logger#level=. + # + def level=(level) + @level = level + @log.level = @level + end + + # + # See Logger#add. This application's +appname+ is used. + # + def log(severity, message = nil, &block) + @log.add(severity, message, @appname, &block) if @log + end + + private + + def run + raise RuntimeError.new('Method run must be defined in the derived class.') + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mailread.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mailread.rb new file mode 100644 index 00000000..08b33c92 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mailread.rb @@ -0,0 +1,62 @@ +# The Mail class represents an internet mail message (as per RFC822, RFC2822) +# with headers and a body. +class Mail + + # Create a new Mail where +f+ is either a stream which responds to gets(), + # or a path to a file. If +f+ is a path it will be opened. + # + # The whole message is read so it can be made available through the #header, + # #[] and #body methods. + # + # The "From " line is ignored if the mail is in mbox format. + def initialize(f) + unless defined? f.gets + f = open(f, "r") + opened = true + end + + @header = {} + @body = [] + begin + while line = f.gets() + line.chop! + next if /^From /=~line # skip From-line + break if /^$/=~line # end of header + + if /^(\S+?):\s*(.*)/=~line + (attr = $1).capitalize! + @header[attr] = $2 + elsif attr + line.sub!(/^\s*/, '') + @header[attr] += "\n" + line + end + end + + return unless line + + while line = f.gets() + break if /^From /=~line + @body.push(line) + end + ensure + f.close if opened + end + end + + # Return the headers as a Hash. + def header + return @header + end + + # Return the message body as an Array of lines + def body + return @body + end + + # Return the header corresponding to +field+. + # + # Matching is case-insensitive. + def [](field) + @header[field.capitalize] + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mathn.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mathn.rb new file mode 100644 index 00000000..a5a121c6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mathn.rb @@ -0,0 +1,308 @@ +# +# mathn.rb - +# $Release Version: 0.5 $ +# $Revision: 1.1.1.1.4.1 $ +# $Date: 1998/01/16 12:36:05 $ +# by Keiju ISHITSUKA(SHL Japan Inc.) +# +# -- +# +# +# + +require "complex.rb" +require "rational.rb" +require "matrix.rb" + +class Integer + + def gcd2(int) + a = self.abs + b = int.abs + a, b = b, a if a < b + + pd_a = a.prime_division + pd_b = b.prime_division + + gcd = 1 + for pair in pd_a + as = pd_b.assoc(pair[0]) + if as + gcd *= as[0] ** [as[1], pair[1]].min + end + end + return gcd + end + + def Integer.from_prime_division(pd) + value = 1 + for prime, index in pd + value *= prime**index + end + value + end + + def prime_division + raise ZeroDivisionError if self == 0 + ps = Prime.new + value = self + pv = [] + for prime in ps + count = 0 + while (value1, mod = value.divmod(prime) + mod) == 0 + value = value1 + count += 1 + end + if count != 0 + pv.push [prime, count] + end + break if prime * prime >= value + end + if value > 1 + pv.push [value, 1] + end + return pv + end +end + +class Prime + include Enumerable + + def initialize + @seed = 1 + @primes = [] + @counts = [] + end + + def succ + i = -1 + size = @primes.size + while i < size + if i == -1 + @seed += 1 + i += 1 + else + while @seed > @counts[i] + @counts[i] += @primes[i] + end + if @seed != @counts[i] + i += 1 + else + i = -1 + end + end + end + @primes.push @seed + @counts.push @seed + @seed + return @seed + end + alias next succ + + def each + loop do + yield succ + end + end +end + +class Fixnum + alias / quo +end + +class Bignum + alias / quo +end + +class Rational + Unify = true + + def inspect + format "%s/%s", numerator.inspect, denominator.inspect + end + + alias power! ** + + def ** (other) + if other.kind_of?(Rational) + other2 = other + if self < 0 + return Complex.new!(self, 0) ** other + elsif other == 0 + return Rational(1,1) + elsif self == 0 + return Rational(0,1) + elsif self == 1 + return Rational(1,1) + end + + npd = numerator.prime_division + dpd = denominator.prime_division + if other < 0 + other = -other + npd, dpd = dpd, npd + end + + for elm in npd + elm[1] = elm[1] * other + if !elm[1].kind_of?(Integer) and elm[1].denominator != 1 + return Float(self) ** other2 + end + elm[1] = elm[1].to_i + end + + for elm in dpd + elm[1] = elm[1] * other + if !elm[1].kind_of?(Integer) and elm[1].denominator != 1 + return Float(self) ** other2 + end + elm[1] = elm[1].to_i + end + + num = Integer.from_prime_division(npd) + den = Integer.from_prime_division(dpd) + + Rational(num,den) + + elsif other.kind_of?(Integer) + if other > 0 + num = numerator ** other + den = denominator ** other + elsif other < 0 + num = denominator ** -other + den = numerator ** -other + elsif other == 0 + num = 1 + den = 1 + end + Rational.new!(num, den) + elsif other.kind_of?(Float) + Float(self) ** other + else + x , y = other.coerce(self) + x ** y + end + end + + def power2(other) + if other.kind_of?(Rational) + if self < 0 + return Complex(self, 0) ** other + elsif other == 0 + return Rational(1,1) + elsif self == 0 + return Rational(0,1) + elsif self == 1 + return Rational(1,1) + end + + dem = nil + x = self.denominator.to_f.to_i + neard = self.denominator.to_f ** (1.0/other.denominator.to_f) + loop do + if (neard**other.denominator == self.denominator) + dem = neaed + break + end + end + nearn = self.numerator.to_f ** (1.0/other.denominator.to_f) + Rational(num,den) + + elsif other.kind_of?(Integer) + if other > 0 + num = numerator ** other + den = denominator ** other + elsif other < 0 + num = denominator ** -other + den = numerator ** -other + elsif other == 0 + num = 1 + den = 1 + end + Rational.new!(num, den) + elsif other.kind_of?(Float) + Float(self) ** other + else + x , y = other.coerce(self) + x ** y + end + end +end + +module Math + def sqrt(a) + if a.kind_of?(Complex) + abs = sqrt(a.real*a.real + a.image*a.image) +# if not abs.kind_of?(Rational) +# return a**Rational(1,2) +# end + x = sqrt((a.real + abs)/Rational(2)) + y = sqrt((-a.real + abs)/Rational(2)) +# if !(x.kind_of?(Rational) and y.kind_of?(Rational)) +# return a**Rational(1,2) +# end + if a.image >= 0 + Complex(x, y) + else + Complex(x, -y) + end + elsif a >= 0 + rsqrt(a) + else + Complex(0,rsqrt(-a)) + end + end + + def rsqrt(a) + if a.kind_of?(Float) + sqrt!(a) + elsif a.kind_of?(Rational) + rsqrt(a.numerator)/rsqrt(a.denominator) + else + src = a + max = 2 ** 32 + byte_a = [src & 0xffffffff] + # ruby's bug + while (src >= max) and (src >>= 32) + byte_a.unshift src & 0xffffffff + end + + answer = 0 + main = 0 + side = 0 + for elm in byte_a + main = (main << 32) + elm + side <<= 16 + if answer != 0 + if main * 4 < side * side + applo = main.div(side) + else + applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1 + end + else + applo = sqrt!(main).to_i + 1 + end + + while (x = (side + applo) * applo) > main + applo -= 1 + end + main -= x + answer = (answer << 16) + applo + side += applo * 2 + end + if main == 0 + answer + else + sqrt!(a) + end + end + end + + module_function :sqrt + module_function :rsqrt +end + +class Complex + Unify = true +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/matrix.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/matrix.rb new file mode 100644 index 00000000..c62acdf9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/matrix.rb @@ -0,0 +1,1272 @@ +#!/usr/local/bin/ruby +#-- +# matrix.rb - +# $Release Version: 1.0$ +# $Revision: 1.11 $ +# $Date: 1999/10/06 11:01:53 $ +# Original Version from Smalltalk-80 version +# on July 23, 1985 at 8:37:17 am +# by Keiju ISHITSUKA +#++ +# +# = matrix.rb +# +# An implementation of Matrix and Vector classes. +# +# Author:: Keiju ISHITSUKA +# Documentation:: Gavin Sinclair (sourced from Ruby in a Nutshell (Matsumoto, O'Reilly)) +# +# See classes Matrix and Vector for documentation. +# + + +require "e2mmap.rb" + +module ExceptionForMatrix # :nodoc: + extend Exception2MessageMapper + def_e2message(TypeError, "wrong argument type %s (expected %s)") + def_e2message(ArgumentError, "Wrong # of arguments(%d for %d)") + + def_exception("ErrDimensionMismatch", "\#{self.name} dimension mismatch") + def_exception("ErrNotRegular", "Not Regular Matrix") + def_exception("ErrOperationNotDefined", "This operation(%s) can\\'t defined") +end + +# +# The +Matrix+ class represents a mathematical matrix, and provides methods for creating +# special-case matrices (zero, identity, diagonal, singular, vector), operating on them +# arithmetically and algebraically, and determining their mathematical properties (trace, rank, +# inverse, determinant). +# +# Note that although matrices should theoretically be rectangular, this is not +# enforced by the class. +# +# Also note that the determinant of integer matrices may be incorrectly calculated unless you +# also require 'mathn'. This may be fixed in the future. +# +# == Method Catalogue +# +# To create a matrix: +# * Matrix[*rows] +# * Matrix.[](*rows) +# * Matrix.rows(rows, copy = true) +# * Matrix.columns(columns) +# * Matrix.diagonal(*values) +# * Matrix.scalar(n, value) +# * Matrix.scalar(n, value) +# * Matrix.identity(n) +# * Matrix.unit(n) +# * Matrix.I(n) +# * Matrix.zero(n) +# * Matrix.row_vector(row) +# * Matrix.column_vector(column) +# +# To access Matrix elements/columns/rows/submatrices/properties: +# * [](i, j) +# * #row_size +# * #column_size +# * #row(i) +# * #column(j) +# * #collect +# * #map +# * #minor(*param) +# +# Properties of a matrix: +# * #regular? +# * #singular? +# * #square? +# +# Matrix arithmetic: +# * *(m) +# * +(m) +# * -(m) +# * #/(m) +# * #inverse +# * #inv +# * ** +# +# Matrix functions: +# * #determinant +# * #det +# * #rank +# * #trace +# * #tr +# * #transpose +# * #t +# +# Conversion to other data types: +# * #coerce(other) +# * #row_vectors +# * #column_vectors +# * #to_a +# +# String representations: +# * #to_s +# * #inspect +# +class Matrix + @RCS_ID='-$Id: matrix.rb,v 1.11 1999/10/06 11:01:53 keiju Exp keiju $-' + +# extend Exception2MessageMapper + include ExceptionForMatrix + + # instance creations + private_class_method :new + + # + # Creates a matrix where each argument is a row. + # Matrix[ [25, 93], [-1, 66] ] + # => 25 93 + # -1 66 + # + def Matrix.[](*rows) + new(:init_rows, rows, false) + end + + # + # Creates a matrix where +rows+ is an array of arrays, each of which is a row + # to the matrix. If the optional argument +copy+ is false, use the given + # arrays as the internal structure of the matrix without copying. + # Matrix.rows([[25, 93], [-1, 66]]) + # => 25 93 + # -1 66 + def Matrix.rows(rows, copy = true) + new(:init_rows, rows, copy) + end + + # + # Creates a matrix using +columns+ as an array of column vectors. + # Matrix.columns([[25, 93], [-1, 66]]) + # => 25 -1 + # 93 66 + # + # + def Matrix.columns(columns) + rows = (0 .. columns[0].size - 1).collect { + |i| + (0 .. columns.size - 1).collect { + |j| + columns[j][i] + } + } + Matrix.rows(rows, false) + end + + # + # Creates a matrix where the diagonal elements are composed of +values+. + # Matrix.diagonal(9, 5, -3) + # => 9 0 0 + # 0 5 0 + # 0 0 -3 + # + def Matrix.diagonal(*values) + size = values.size + rows = (0 .. size - 1).collect { + |j| + row = Array.new(size).fill(0, 0, size) + row[j] = values[j] + row + } + rows(rows, false) + end + + # + # Creates an +n+ by +n+ diagonal matrix where each diagonal element is + # +value+. + # Matrix.scalar(2, 5) + # => 5 0 + # 0 5 + # + def Matrix.scalar(n, value) + Matrix.diagonal(*Array.new(n).fill(value, 0, n)) + end + + # + # Creates an +n+ by +n+ identity matrix. + # Matrix.identity(2) + # => 1 0 + # 0 1 + # + def Matrix.identity(n) + Matrix.scalar(n, 1) + end + class << Matrix + alias unit identity + alias I identity + end + + # + # Creates an +n+ by +n+ zero matrix. + # Matrix.zero(2) + # => 0 0 + # 0 0 + # + def Matrix.zero(n) + Matrix.scalar(n, 0) + end + + # + # Creates a single-row matrix where the values of that row are as given in + # +row+. + # Matrix.row_vector([4,5,6]) + # => 4 5 6 + # + def Matrix.row_vector(row) + case row + when Vector + Matrix.rows([row.to_a], false) + when Array + Matrix.rows([row.dup], false) + else + Matrix.rows([[row]], false) + end + end + + # + # Creates a single-column matrix where the values of that column are as given + # in +column+. + # Matrix.column_vector([4,5,6]) + # => 4 + # 5 + # 6 + # + def Matrix.column_vector(column) + case column + when Vector + Matrix.columns([column.to_a]) + when Array + Matrix.columns([column]) + else + Matrix.columns([[column]]) + end + end + + # + # This method is used by the other methods that create matrices, and is of no + # use to general users. + # + def initialize(init_method, *argv) + self.send(init_method, *argv) + end + + def init_rows(rows, copy) + if copy + @rows = rows.collect{|row| row.dup} + else + @rows = rows + end + self + end + private :init_rows + + # + # Returns element (+i+,+j+) of the matrix. That is: row +i+, column +j+. + # + def [](i, j) + @rows[i][j] + end + + # + # Returns the number of rows. + # + def row_size + @rows.size + end + + # + # Returns the number of columns. Note that it is possible to construct a + # matrix with uneven columns (e.g. Matrix[ [1,2,3], [4,5] ]), but this is + # mathematically unsound. This method uses the first row to determine the + # result. + # + def column_size + @rows[0].size + end + + # + # Returns row vector number +i+ of the matrix as a Vector (starting at 0 like + # an array). When a block is given, the elements of that vector are iterated. + # + def row(i) # :yield: e + if block_given? + for e in @rows[i] + yield e + end + else + Vector.elements(@rows[i]) + end + end + + # + # Returns column vector number +j+ of the matrix as a Vector (starting at 0 + # like an array). When a block is given, the elements of that vector are + # iterated. + # + def column(j) # :yield: e + if block_given? + 0.upto(row_size - 1) do + |i| + yield @rows[i][j] + end + else + col = (0 .. row_size - 1).collect { + |i| + @rows[i][j] + } + Vector.elements(col, false) + end + end + + # + # Returns a matrix that is the result of iteration of the given block over all + # elements of the matrix. + # Matrix[ [1,2], [3,4] ].collect { |i| i**2 } + # => 1 4 + # 9 16 + # + def collect # :yield: e + rows = @rows.collect{|row| row.collect{|e| yield e}} + Matrix.rows(rows, false) + end + alias map collect + + # + # Returns a section of the matrix. The parameters are either: + # * start_row, nrows, start_col, ncols; OR + # * col_range, row_range + # + # Matrix.diagonal(9, 5, -3).minor(0..1, 0..2) + # => 9 0 0 + # 0 5 0 + # + def minor(*param) + case param.size + when 2 + from_row = param[0].first + size_row = param[0].end - from_row + size_row += 1 unless param[0].exclude_end? + from_col = param[1].first + size_col = param[1].end - from_col + size_col += 1 unless param[1].exclude_end? + when 4 + from_row = param[0] + size_row = param[1] + from_col = param[2] + size_col = param[3] + else + Matrix.Raise ArgumentError, param.inspect + end + + rows = @rows[from_row, size_row].collect{ + |row| + row[from_col, size_col] + } + Matrix.rows(rows, false) + end + + #-- + # TESTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Returns +true+ if this is a regular matrix. + # + def regular? + square? and rank == column_size + end + + # + # Returns +true+ is this is a singular (i.e. non-regular) matrix. + # + def singular? + not regular? + end + + # + # Returns +true+ is this is a square matrix. See note in column_size about this + # being unreliable, though. + # + def square? + column_size == row_size + end + + #-- + # OBJECT METHODS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Returns +true+ if and only if the two matrices contain equal elements. + # + def ==(other) + return false unless Matrix === other + + other.compare_by_row_vectors(@rows) + end + alias eql? == + + # + # Not really intended for general consumption. + # + def compare_by_row_vectors(rows) + return false unless @rows.size == rows.size + + 0.upto(@rows.size - 1) do + |i| + return false unless @rows[i] == rows[i] + end + true + end + + # + # Returns a clone of the matrix, so that the contents of each do not reference + # identical objects. + # + def clone + Matrix.rows(@rows) + end + + # + # Returns a hash-code for the matrix. + # + def hash + value = 0 + for row in @rows + for e in row + value ^= e.hash + end + end + return value + end + + #-- + # ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Matrix multiplication. + # Matrix[[2,4], [6,8]] * Matrix.identity(2) + # => 2 4 + # 6 8 + # + def *(m) # m is matrix or vector or number + case(m) + when Numeric + rows = @rows.collect { + |row| + row.collect { + |e| + e * m + } + } + return Matrix.rows(rows, false) + when Vector + m = Matrix.column_vector(m) + r = self * m + return r.column(0) + when Matrix + Matrix.Raise ErrDimensionMismatch if column_size != m.row_size + + rows = (0 .. row_size - 1).collect { + |i| + (0 .. m.column_size - 1).collect { + |j| + vij = 0 + 0.upto(column_size - 1) do + |k| + vij += self[i, k] * m[k, j] + end + vij + } + } + return Matrix.rows(rows, false) + else + x, y = m.coerce(self) + return x * y + end + end + + # + # Matrix addition. + # Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]] + # => 6 0 + # -4 12 + # + def +(m) + case m + when Numeric + Matrix.Raise ErrOperationNotDefined, "+" + when Vector + m = Matrix.column_vector(m) + when Matrix + else + x, y = m.coerce(self) + return x + y + end + + Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size + + rows = (0 .. row_size - 1).collect { + |i| + (0 .. column_size - 1).collect { + |j| + self[i, j] + m[i, j] + } + } + Matrix.rows(rows, false) + end + + # + # Matrix subtraction. + # Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]] + # => -8 2 + # 8 1 + # + def -(m) + case m + when Numeric + Matrix.Raise ErrOperationNotDefined, "-" + when Vector + m = Matrix.column_vector(m) + when Matrix + else + x, y = m.coerce(self) + return x - y + end + + Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size + + rows = (0 .. row_size - 1).collect { + |i| + (0 .. column_size - 1).collect { + |j| + self[i, j] - m[i, j] + } + } + Matrix.rows(rows, false) + end + + # + # Matrix division (multiplication by the inverse). + # Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]] + # => -7 1 + # -3 -6 + # + def /(other) + case other + when Numeric + rows = @rows.collect { + |row| + row.collect { + |e| + e / other + } + } + return Matrix.rows(rows, false) + when Matrix + return self * other.inverse + else + x, y = other.coerce(self) + rerurn x / y + end + end + + # + # Returns the inverse of the matrix. + # Matrix[[1, 2], [2, 1]].inverse + # => -1 1 + # 0 -1 + # + def inverse + Matrix.Raise ErrDimensionMismatch unless square? + Matrix.I(row_size).inverse_from(self) + end + alias inv inverse + + # + # Not for public consumption? + # + def inverse_from(src) + size = row_size - 1 + a = src.to_a + + for k in 0..size + if (akk = a[k][k]) == 0 + i = k + begin + Matrix.Raise ErrNotRegular if (i += 1) > size + end while a[i][k] == 0 + a[i], a[k] = a[k], a[i] + @rows[i], @rows[k] = @rows[k], @rows[i] + akk = a[k][k] + end + + for i in 0 .. size + next if i == k + q = a[i][k] / akk + a[i][k] = 0 + + (k + 1).upto(size) do + |j| + a[i][j] -= a[k][j] * q + end + 0.upto(size) do + |j| + @rows[i][j] -= @rows[k][j] * q + end + end + + (k + 1).upto(size) do + |j| + a[k][j] /= akk + end + 0.upto(size) do + |j| + @rows[k][j] /= akk + end + end + self + end + #alias reciprocal inverse + + # + # Matrix exponentiation. Defined for integer powers only. Equivalent to + # multiplying the matrix by itself N times. + # Matrix[[7,6], [3,9]] ** 2 + # => 67 96 + # 48 99 + # + def ** (other) + if other.kind_of?(Integer) + x = self + if other <= 0 + x = self.inverse + return Matrix.identity(self.column_size) if other == 0 + other = -other + end + z = x + n = other - 1 + while n != 0 + while (div, mod = n.divmod(2) + mod == 0) + x = x * x + n = div + end + z *= x + n -= 1 + end + z + elsif other.kind_of?(Float) || defined?(Rational) && other.kind_of?(Rational) + Matrix.Raise ErrOperationNotDefined, "**" + else + Matrix.Raise ErrOperationNotDefined, "**" + end + end + + #-- + # MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Returns the determinant of the matrix. If the matrix is not square, the + # result is 0. + # Matrix[[7,6], [3,9]].determinant + # => 63 + # + def determinant + return 0 unless square? + + size = row_size - 1 + a = to_a + + det = 1 + k = 0 + begin + if (akk = a[k][k]) == 0 + i = k + begin + return 0 if (i += 1) > size + end while a[i][k] == 0 + a[i], a[k] = a[k], a[i] + akk = a[k][k] + det *= -1 + end + (k + 1).upto(size) do + |i| + q = a[i][k] / akk + (k + 1).upto(size) do + |j| + a[i][j] -= a[k][j] * q + end + end + det *= akk + end while (k += 1) <= size + det + end + alias det determinant + + # + # Returns the rank of the matrix. Beware that using Float values, with their + # usual lack of precision, can affect the value returned by this method. Use + # Rational values instead if this is important to you. + # Matrix[[7,6], [3,9]].rank + # => 2 + # + def rank + if column_size > row_size + a = transpose.to_a + a_column_size = row_size + a_row_size = column_size + else + a = to_a + a_column_size = column_size + a_row_size = row_size + end + rank = 0 + k = 0 + begin + if (akk = a[k][k]) == 0 + i = k + exists = true + begin + if (i += 1) > a_column_size - 1 + exists = false + break + end + end while a[i][k] == 0 + if exists + a[i], a[k] = a[k], a[i] + akk = a[k][k] + else + i = k + exists = true + begin + if (i += 1) > a_row_size - 1 + exists = false + break + end + end while a[k][i] == 0 + if exists + k.upto(a_column_size - 1) do + |j| + a[j][k], a[j][i] = a[j][i], a[j][k] + end + akk = a[k][k] + else + next + end + end + end + (k + 1).upto(a_row_size - 1) do + |i| + q = a[i][k] / akk + (k + 1).upto(a_column_size - 1) do + |j| + a[i][j] -= a[k][j] * q + end + end + rank += 1 + end while (k += 1) <= a_column_size - 1 + return rank + end + + # + # Returns the trace (sum of diagonal elements) of the matrix. + # Matrix[[7,6], [3,9]].trace + # => 16 + # + def trace + tr = 0 + 0.upto(column_size - 1) do + |i| + tr += @rows[i][i] + end + tr + end + alias tr trace + + # + # Returns the transpose of the matrix. + # Matrix[[1,2], [3,4], [5,6]] + # => 1 2 + # 3 4 + # 5 6 + # Matrix[[1,2], [3,4], [5,6]].transpose + # => 1 3 5 + # 2 4 6 + # + def transpose + Matrix.columns(@rows) + end + alias t transpose + + #-- + # CONVERTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # FIXME: describe #coerce. + # + def coerce(other) + case other + when Numeric + return Scalar.new(other), self + else + raise TypeError, "#{self.class} can't be coerced into #{other.class}" + end + end + + # + # Returns an array of the row vectors of the matrix. See Vector. + # + def row_vectors + rows = (0 .. row_size - 1).collect { + |i| + row(i) + } + rows + end + + # + # Returns an array of the column vectors of the matrix. See Vector. + # + def column_vectors + columns = (0 .. column_size - 1).collect { + |i| + column(i) + } + columns + end + + # + # Returns an array of arrays that describe the rows of the matrix. + # + def to_a + @rows.collect{|row| row.collect{|e| e}} + end + + #-- + # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Overrides Object#to_s + # + def to_s + "Matrix[" + @rows.collect{ + |row| + "[" + row.collect{|e| e.to_s}.join(", ") + "]" + }.join(", ")+"]" + end + + # + # Overrides Object#inspect + # + def inspect + "Matrix"+@rows.inspect + end + + # Private CLASS + + class Scalar < Numeric # :nodoc: + include ExceptionForMatrix + + def initialize(value) + @value = value + end + + # ARITHMETIC + def +(other) + case other + when Numeric + Scalar.new(@value + other) + when Vector, Matrix + Scalar.Raise WrongArgType, other.class, "Numeric or Scalar" + when Scalar + Scalar.new(@value + other.value) + else + x, y = other.coerce(self) + x + y + end + end + + def -(other) + case other + when Numeric + Scalar.new(@value - other) + when Vector, Matrix + Scalar.Raise WrongArgType, other.class, "Numeric or Scalar" + when Scalar + Scalar.new(@value - other.value) + else + x, y = other.coerce(self) + x - y + end + end + + def *(other) + case other + when Numeric + Scalar.new(@value * other) + when Vector, Matrix + other.collect{|e| @value * e} + else + x, y = other.coerce(self) + x * y + end + end + + def / (other) + case other + when Numeric + Scalar.new(@value / other) + when Vector + Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix" + when Matrix + self * _M.inverse + else + x, y = other.coerce(self) + x / y + end + end + + def ** (other) + case other + when Numeric + Scalar.new(@value ** other) + when Vector + Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix" + when Matrix + other.powered_by(self) + else + x, y = other.coerce(self) + x ** y + end + end + end +end + + +# +# The +Vector+ class represents a mathematical vector, which is useful in its own right, and +# also constitutes a row or column of a Matrix. +# +# == Method Catalogue +# +# To create a Vector: +# * Vector.[](*array) +# * Vector.elements(array, copy = true) +# +# To access elements: +# * [](i) +# +# To enumerate the elements: +# * #each2(v) +# * #collect2(v) +# +# Vector arithmetic: +# * *(x) "is matrix or number" +# * +(v) +# * -(v) +# +# Vector functions: +# * #inner_product(v) +# * #collect +# * #map +# * #map2(v) +# * #r +# * #size +# +# Conversion to other data types: +# * #covector +# * #to_a +# * #coerce(other) +# +# String representations: +# * #to_s +# * #inspect +# +class Vector + include ExceptionForMatrix + + #INSTANCE CREATION + + private_class_method :new + + # + # Creates a Vector from a list of elements. + # Vector[7, 4, ...] + # + def Vector.[](*array) + new(:init_elements, array, copy = false) + end + + # + # Creates a vector from an Array. The optional second argument specifies + # whether the array itself or a copy is used internally. + # + def Vector.elements(array, copy = true) + new(:init_elements, array, copy) + end + + # + # For internal use. + # + def initialize(method, array, copy) + self.send(method, array, copy) + end + + # + # For internal use. + # + def init_elements(array, copy) + if copy + @elements = array.dup + else + @elements = array + end + end + + # ACCESSING + + # + # Returns element number +i+ (starting at zero) of the vector. + # + def [](i) + @elements[i] + end + + # + # Returns the number of elements in the vector. + # + def size + @elements.size + end + + #-- + # ENUMERATIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Iterate over the elements of this vector and +v+ in conjunction. + # + def each2(v) # :yield: e1, e2 + Vector.Raise ErrDimensionMismatch if size != v.size + 0.upto(size - 1) do + |i| + yield @elements[i], v[i] + end + end + + # + # Collects (as in Enumerable#collect) over the elements of this vector and +v+ + # in conjunction. + # + def collect2(v) # :yield: e1, e2 + Vector.Raise ErrDimensionMismatch if size != v.size + (0 .. size - 1).collect do + |i| + yield @elements[i], v[i] + end + end + + #-- + # COMPARING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Returns +true+ iff the two vectors have the same elements in the same order. + # + def ==(other) + return false unless Vector === other + + other.compare_by(@elements) + end + alias eqn? == + + # + # For internal use. + # + def compare_by(elements) + @elements == elements + end + + # + # Return a copy of the vector. + # + def clone + Vector.elements(@elements) + end + + # + # Return a hash-code for the vector. + # + def hash + @elements.hash + end + + #-- + # ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Multiplies the vector by +x+, where +x+ is a number or another vector. + # + def *(x) + case x + when Numeric + els = @elements.collect{|e| e * x} + Vector.elements(els, false) + when Matrix + Matrix.column_vector(self) * x + else + s, x = x.coerce(self) + s * x + end + end + + # + # Vector addition. + # + def +(v) + case v + when Vector + Vector.Raise ErrDimensionMismatch if size != v.size + els = collect2(v) { + |v1, v2| + v1 + v2 + } + Vector.elements(els, false) + when Matrix + Matrix.column_vector(self) + v + else + s, x = v.coerce(self) + s + x + end + end + + # + # Vector subtraction. + # + def -(v) + case v + when Vector + Vector.Raise ErrDimensionMismatch if size != v.size + els = collect2(v) { + |v1, v2| + v1 - v2 + } + Vector.elements(els, false) + when Matrix + Matrix.column_vector(self) - v + else + s, x = v.coerce(self) + s - x + end + end + + #-- + # VECTOR FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Returns the inner product of this vector with the other. + # Vector[4,7].inner_product Vector[10,1] => 47 + # + def inner_product(v) + Vector.Raise ErrDimensionMismatch if size != v.size + + p = 0 + each2(v) { + |v1, v2| + p += v1 * v2 + } + p + end + + # + # Like Array#collect. + # + def collect # :yield: e + els = @elements.collect { + |v| + yield v + } + Vector.elements(els, false) + end + alias map collect + + # + # Like Vector#collect2, but returns a Vector instead of an Array. + # + def map2(v) # :yield: e1, e2 + els = collect2(v) { + |v1, v2| + yield v1, v2 + } + Vector.elements(els, false) + end + + # + # Returns the modulus (Pythagorean distance) of the vector. + # Vector[5,8,2].r => 9.643650761 + # + def r + v = 0 + for e in @elements + v += e*e + end + return Math.sqrt(v) + end + + #-- + # CONVERTING + #++ + + # + # Creates a single-row matrix from this vector. + # + def covector + Matrix.row_vector(self) + end + + # + # Returns the elements of the vector in an array. + # + def to_a + @elements.dup + end + + # + # FIXME: describe Vector#coerce. + # + def coerce(other) + case other + when Numeric + return Scalar.new(other), self + else + raise TypeError, "#{self.class} can't be coerced into #{other.class}" + end + end + + #-- + # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + #++ + + # + # Overrides Object#to_s + # + def to_s + "Vector[" + @elements.join(", ") + "]" + end + + # + # Overrides Object#inspect + # + def inspect + str = "Vector"+@elements.inspect + end +end + + +# Documentation comments: +# - Matrix#coerce and Vector#coerce need to be documented diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/md5.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/md5.rb new file mode 100644 index 00000000..e3fc2788 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/md5.rb @@ -0,0 +1,23 @@ +# just for compatibility; requiring "md5" is obsoleted +# +# $RoughId: md5.rb,v 1.4 2001/07/13 15:38:27 knu Exp $ +# $Id: md5.rb 12008 2007-03-06 10:12:12Z knu $ + +require 'digest/md5' + +class MD5 < Digest::MD5 + class << self + alias orig_new new + def new(str = nil) + if str + orig_new.update(str) + else + orig_new + end + end + + def md5(*args) + new(*args) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mkmf.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mkmf.rb new file mode 100644 index 00000000..31f4878b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mkmf.rb @@ -0,0 +1,1554 @@ +# module to create Makefile for extension modules +# invoke like: ruby -r mkmf extconf.rb + +require 'rbconfig' +require 'fileutils' +require 'shellwords' + +CONFIG = Config::MAKEFILE_CONFIG +ORIG_LIBPATH = ENV['LIB'] + +CXX_EXT = %w[cc cxx cpp] +if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os'] + CXX_EXT.concat(%w[C]) +end +SRC_EXT = %w[c m] << CXX_EXT +$static = $config_h = nil +$default_static = $static + +unless defined? $configure_args + $configure_args = {} + args = CONFIG["configure_args"] + if ENV["CONFIGURE_ARGS"] + args << " " << ENV["CONFIGURE_ARGS"] + end + for arg in Shellwords::shellwords(args) + arg, val = arg.split('=', 2) + next unless arg + arg.tr!('_', '-') + if arg.sub!(/^(?!--)/, '--') + val or next + arg.downcase! + end + next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg + $configure_args[arg] = val || true + end + for arg in ARGV + arg, val = arg.split('=', 2) + next unless arg + arg.tr!('_', '-') + if arg.sub!(/^(?!--)/, '--') + val or next + arg.downcase! + end + $configure_args[arg] = val || true + end +end + +$libdir = CONFIG["libdir"] +$rubylibdir = CONFIG["rubylibdir"] +$archdir = CONFIG["archdir"] +$sitedir = CONFIG["sitedir"] +$sitelibdir = CONFIG["sitelibdir"] +$sitearchdir = CONFIG["sitearchdir"] + +$mswin = /mswin/ =~ RUBY_PLATFORM +$bccwin = /bccwin/ =~ RUBY_PLATFORM +$mingw = /mingw/ =~ RUBY_PLATFORM +$cygwin = /cygwin/ =~ RUBY_PLATFORM +$human = /human/ =~ RUBY_PLATFORM +$netbsd = /netbsd/ =~ RUBY_PLATFORM +$os2 = /os2/ =~ RUBY_PLATFORM +$beos = /beos/ =~ RUBY_PLATFORM +$solaris = /solaris/ =~ RUBY_PLATFORM +$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/) + +def config_string(key, config = CONFIG) + s = config[key] and !s.empty? and block_given? ? yield(s) : s +end + +def dir_re(dir) + Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?') +end + +INSTALL_DIRS = [ + [dir_re('commondir'), "$(RUBYCOMMONDIR)"], + [dir_re("sitedir"), "$(RUBYCOMMONDIR)"], + [dir_re('rubylibdir'), "$(RUBYLIBDIR)"], + [dir_re('archdir'), "$(RUBYARCHDIR)"], + [dir_re('sitelibdir'), "$(RUBYLIBDIR)"], + [dir_re('sitearchdir'), "$(RUBYARCHDIR)"] +] + +def install_dirs(target_prefix = nil) + if $extout + dirs = [ + ['RUBYCOMMONDIR', '$(extout)/common'], + ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'], + ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'], + ['extout', "#$extout"], + ['extout_prefix', "#$extout_prefix"], + ] + elsif $extmk + dirs = [ + ['RUBYCOMMONDIR', '$(rubylibdir)'], + ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'], + ['RUBYARCHDIR', '$(archdir)$(target_prefix)'], + ] + else + dirs = [ + ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'], + ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'], + ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'], + ] + end + dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")] + dirs +end + +def map_dir(dir, map = nil) + map ||= INSTALL_DIRS + map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)} +end + +topdir = File.dirname(libdir = File.dirname(__FILE__)) +extdir = File.expand_path("ext", topdir) +$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/" +if not $extmk and File.exist?(Config::CONFIG["archdir"] + "/ruby.h") + $hdrdir = $topdir = Config::CONFIG["archdir"] +elsif File.exist?(($top_srcdir ||= topdir) + "/ruby.h") and + File.exist?(($topdir ||= Config::CONFIG["topdir"]) + "/config.h") + $hdrdir = $top_srcdir +else + abort "can't find header files for ruby." +end + +OUTFLAG = CONFIG['OUTFLAG'] +CPPOUTFILE = CONFIG['CPPOUTFILE'] + +CONFTEST_C = "conftest.c" + +class String + def quote + /\s/ =~ self ? "\"#{self}\"" : self + end +end +class Array + def quote + map {|s| s.quote} + end +end + +def rm_f(*files) + FileUtils.rm_f(Dir[files.join("\0")]) +end + +def modified?(target, times) + (t = File.mtime(target)) rescue return nil + Array === times or times = [times] + t if times.all? {|n| n <= t} +end + +def merge_libs(*libs) + libs.inject([]) do |x, y| + xy = x & y + xn = yn = 0 + y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e} + y.each_with_index do |v, yi| + if xy.include?(v) + xi = [x.index(v), xn].max() + x[xi, 1] = y[yn..yi] + xn, yn = xi + (yi - yn + 1), yi + 1 + end + end + x.concat(y[yn..-1] || []) + end +end + +module Logging + @log = nil + @logfile = 'mkmf.log' + @orgerr = $stderr.dup + @orgout = $stdout.dup + @postpone = 0 + + def self::open + @log ||= File::open(@logfile, 'w') + @log.sync = true + $stderr.reopen(@log) + $stdout.reopen(@log) + yield + ensure + $stderr.reopen(@orgerr) + $stdout.reopen(@orgout) + end + + def self::message(*s) + @log ||= File::open(@logfile, 'w') + @log.sync = true + @log.printf(*s) + end + + def self::logfile file + @logfile = file + if @log and not @log.closed? + @log.flush + @log.close + @log = nil + end + end + + def self::postpone + tmplog = "mkmftmp#{@postpone += 1}.log" + open do + log, *save = @log, @logfile, @orgout, @orgerr + @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log + begin + log.print(open {yield}) + @log.close + File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} + ensure + @log, @logfile, @orgout, @orgerr = log, *save + @postpone -= 1 + rm_f tmplog + end + end + end +end + +def xsystem command + Logging::open do + puts command.quote + system(command) + end +end + +def xpopen command, *mode, &block + Logging::open do + case mode[0] + when nil, /^r/ + puts "#{command} |" + else + puts "| #{command}" + end + IO.popen(command, *mode, &block) + end +end + +def log_src(src) + src = src.split(/^/) + fmt = "%#{src.size.to_s.size}d: %s" + Logging::message <<"EOM" +checked program was: +/* begin */ +EOM + src.each_with_index {|line, no| Logging::message fmt, no+1, line} + Logging::message <<"EOM" +/* end */ + +EOM +end + +def create_tmpsrc(src) + src = yield(src) if block_given? + src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n") + open(CONFTEST_C, "wb") do |cfile| + cfile.print src + end + src +end + +def try_do(src, command, &b) + src = create_tmpsrc(src, &b) + xsystem(command) +ensure + log_src(src) +end + +def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH) + conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, + 'src' => CONFTEST_C, + 'INCFLAGS' => $INCFLAGS, + 'CPPFLAGS' => $CPPFLAGS, + 'CFLAGS' => "#$CFLAGS", + 'ARCH_FLAG' => "#$ARCH_FLAG", + 'LDFLAGS' => "#$LDFLAGS #{ldflags}", + 'LIBPATH' => libpathflag(libpath), + 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs", + 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS") + Config::expand(TRY_LINK.dup, conf) +end + +def cc_command(opt="") + conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote) + Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}", + conf) +end + +def cpp_command(outfile, opt="") + conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote) + Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}", + conf) +end + +def libpathflag(libpath=$DEFLIBPATH|$LIBPATH) + libpath.map{|x| + case x + when "$(topdir)", /\A\./ + LIBPATHFLAG + else + LIBPATHFLAG+RPATHFLAG + end % x.quote + }.join +end + +def try_link0(src, opt="", &b) + try_do(src, link_command("", opt), &b) +end + +def try_link(src, opt="", &b) + try_link0(src, opt, &b) +ensure + rm_f "conftest*", "c0x32*" +end + +def try_compile(src, opt="", &b) + try_do(src, cc_command(opt), &b) +ensure + rm_f "conftest*" +end + +def try_cpp(src, opt="", &b) + try_do(src, cpp_command(CPPOUTFILE, opt), &b) +ensure + rm_f "conftest*" +end + +def cpp_include(header) + if header + header = [header] unless header.kind_of? Array + header.map {|h| "#include <#{h}>\n"}.join + else + "" + end +end + +def with_cppflags(flags) + cppflags = $CPPFLAGS + $CPPFLAGS = flags + ret = yield +ensure + $CPPFLAGS = cppflags unless ret +end + +def with_cflags(flags) + cflags = $CFLAGS + $CFLAGS = flags + ret = yield +ensure + $CFLAGS = cflags unless ret +end + +def with_ldflags(flags) + ldflags = $LDFLAGS + $LDFLAGS = flags + ret = yield +ensure + $LDFLAGS = ldflags unless ret +end + +def try_static_assert(expr, headers = nil, opt = "", &b) + headers = cpp_include(headers) + try_compile(< 0", headers, opt) + # positive constant + elsif try_static_assert("#{const} < 0", headers, opt) + neg = true + const = "-(#{const})" + elsif try_static_assert("#{const} == 0", headers, opt) + return 0 + else + # not a constant + return nil + end + upper = 1 + lower = 0 + until try_static_assert("#{const} <= #{upper}", headers, opt) + lower = upper + upper <<= 1 + end + return nil unless lower + while upper > lower + 1 + mid = (upper + lower) / 2 + if try_static_assert("#{const} > #{mid}", headers, opt) + lower = mid + else + upper = mid + end + end + upper = -upper if neg + return upper + else + src = %{#{COMMON_HEADERS} +#{includes} +#include +/*top*/ +int conftest_const = (int)(#{const}); +int main() {printf("%d\\n", conftest_const); return 0;} +} + if try_link0(src, opt, &b) + xpopen("./conftest") do |f| + return Integer(f.gets) + end + end + end + nil +end + +def try_func(func, libs, headers = nil, &b) + headers = cpp_include(headers) + try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b) +#{COMMON_HEADERS} +#{headers} +/*top*/ +int main() { return 0; } +int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; } +SRC +#{headers} +/*top*/ +int main() { return 0; } +int t() { #{func}(); return 0; } +SRC +end + +def try_var(var, headers = nil, &b) + headers = cpp_include(headers) + try_compile(<<"SRC", &b) +#{COMMON_HEADERS} +#{headers} +/*top*/ +int main() { return 0; } +int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; } +SRC +end + +def egrep_cpp(pat, src, opt = "", &b) + src = create_tmpsrc(src, &b) + xpopen(cpp_command('', opt)) do |f| + if Regexp === pat + puts(" ruby -ne 'print if #{pat.inspect}'") + f.grep(pat) {|l| + puts "#{f.lineno}: #{l}" + return true + } + false + else + puts(" egrep '#{pat}'") + begin + stdin = $stdin.dup + $stdin.reopen(f) + system("egrep", pat) + ensure + $stdin.reopen(stdin) + end + end + end +ensure + rm_f "conftest*" + log_src(src) +end + +def macro_defined?(macro, src, opt = "", &b) + src = src.sub(/[^\n]\z/, "\\&\n") + try_compile(src + <<"SRC", opt, &b) +/*top*/ +#ifndef #{macro} +# error +>>>>>> #{macro} undefined <<<<<< +#endif +SRC +end + +def try_run(src, opt = "", &b) + if try_link0(src, opt, &b) + xsystem("./conftest") + else + nil + end +ensure + rm_f "conftest*" +end + +def install_files(mfile, ifiles, map = nil, srcprefix = nil) + ifiles or return + srcprefix ||= '$(srcdir)' + Config::expand(srcdir = srcprefix.dup) + dirs = [] + path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]} + ifiles.each do |files, dir, prefix| + dir = map_dir(dir, map) + prefix = %r|\A#{Regexp.quote(prefix)}/?| if prefix + if /\A\.\// =~ files + # install files which are in current working directory. + files = files[2..-1] + len = nil + else + # install files which are under the $(srcdir). + files = File.join(srcdir, files) + len = srcdir.size + end + f = nil + Dir.glob(files) do |f| + f[0..len] = "" if len + d = File.dirname(f) + d.sub!(prefix, "") if prefix + d = (d.empty? || d == ".") ? dir : File.join(dir, d) + f = File.join(srcprefix, f) if len + path[d] << f + end + unless len or f + d = File.dirname(files) + d.sub!(prefix, "") if prefix + d = (d.empty? || d == ".") ? dir : File.join(dir, d) + path[d] << files + end + end + dirs +end + +def install_rb(mfile, dest, srcdir = nil) + install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir) +end + +def append_library(libs, lib) + format(LIBARG, lib) + " " + libs +end + +def message(*s) + unless $extmk and not $VERBOSE + printf(*s) + $stdout.flush + end +end + +def checking_for(m, fmt = nil) + f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim + m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... " + message "%s", m + a = r = nil + Logging::postpone do + r = yield + a = (fmt ? fmt % r : r ? "yes" : "no") << "\n" + "#{f}#{m}-------------------- #{a}\n" + end + message(a) + Logging::message "--------------------\n\n" + r +end + +def checking_message(target, place = nil, opt = nil) + [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)| + if noun + [[:to_str], [:join, ","], [:to_s]].each do |meth, *args| + if noun.respond_to?(meth) + break noun = noun.send(meth, *args) + end + end + msg << " #{pre} #{noun}" unless noun.empty? + end + msg + end +end + +# Returns whether or not +macro+ is defined either in the common header +# files or within any +headers+ you provide. +# +# Any options you pass to +opt+ are passed along to the compiler. +# +def have_macro(macro, headers = nil, opt = "", &b) + checking_for checking_message(macro, headers, opt) do + macro_defined?(macro, cpp_include(headers), opt, &b) + end +end + +# Returns whether or not the given entry point +func+ can be found within +# +lib+. If +func+ is nil, the 'main()' entry point is used by default. +# If found, it adds the library to list of libraries to be used when linking +# your extension. +# +# If +headers+ are provided, it will include those header files as the +# header files it looks in when searching for +func+. +# +# Real name of the library to be linked can be altered by +# '--with-FOOlib' configuration option. +# +def have_library(lib, func = nil, headers = nil, &b) + func = "main" if !func or func.empty? + lib = with_config(lib+'lib', lib) + checking_for checking_message("#{func}()", LIBARG%lib) do + if COMMON_LIBS.include?(lib) + true + else + libs = append_library($libs, lib) + if try_func(func, libs, headers, &b) + $libs = libs + true + else + false + end + end + end +end + +# Returns whether or not the entry point +func+ can be found within the library +# +lib+ in one of the +paths+ specified, where +paths+ is an array of strings. +# If +func+ is nil , then the main() function is used as the entry point. +# +# If +lib+ is found, then the path it was found on is added to the list of +# library paths searched and linked against. +# +def find_library(lib, func, *paths, &b) + func = "main" if !func or func.empty? + lib = with_config(lib+'lib', lib) + paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten + checking_for "#{func}() in #{LIBARG%lib}" do + libpath = $LIBPATH + libs = append_library($libs, lib) + begin + until r = try_func(func, libs, &b) or paths.empty? + $LIBPATH = libpath | [paths.shift] + end + if r + $libs = libs + libpath = nil + end + ensure + $LIBPATH = libpath if libpath + end + r + end +end + +# Returns whether or not the function +func+ can be found in the common +# header files, or within any +headers+ that you provide. If found, a +# macro is passed as a preprocessor constant to the compiler using the +# function name, in uppercase, prepended with 'HAVE_'. +# +# For example, if have_func('foo') returned true, then the HAVE_FOO +# preprocessor macro would be passed to the compiler. +# +def have_func(func, headers = nil, &b) + checking_for checking_message("#{func}()", headers) do + if try_func(func, $libs, headers, &b) + $defs.push(format("-DHAVE_%s", func.upcase)) + true + else + false + end + end +end + +# Returns whether or not the variable +var+ can be found in the common +# header files, or within any +headers+ that you provide. If found, a +# macro is passed as a preprocessor constant to the compiler using the +# variable name, in uppercase, prepended with 'HAVE_'. +# +# For example, if have_var('foo') returned true, then the HAVE_FOO +# preprocessor macro would be passed to the compiler. +# +def have_var(var, headers = nil, &b) + checking_for checking_message(var, headers) do + if try_var(var, headers, &b) + $defs.push(format("-DHAVE_%s", var.upcase)) + true + else + false + end + end +end + +# Returns whether or not the given +header+ file can be found on your system. +# If found, a macro is passed as a preprocessor constant to the compiler using +# the header file name, in uppercase, prepended with 'HAVE_'. +# +# For example, if have_header('foo.h') returned true, then the HAVE_FOO_H +# preprocessor macro would be passed to the compiler. +# +def have_header(header, &b) + checking_for header do + if try_cpp(cpp_include(header), &b) + $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___"))) + true + else + false + end + end +end + +# Instructs mkmf to search for the given +header+ in any of the +paths+ +# provided, and returns whether or not it was found in those paths. +# +# If the header is found then the path it was found on is added to the list +# of included directories that are sent to the compiler (via the -I switch). +# +def find_header(header, *paths) + header = cpp_include(header) + checking_for header do + if try_cpp(header) + true + else + found = false + paths.each do |dir| + opt = "-I#{dir}".quote + if try_cpp(header, opt) + $INCFLAGS << " " << opt + found = true + break + end + end + found + end + end +end + +# Returns whether or not the struct of type +type+ contains +member+. If +# it does not, or the struct type can't be found, then false is returned. You +# may optionally specify additional +headers+ in which to look for the struct +# (in addition to the common header files). +# +# If found, a macro is passed as a preprocessor constant to the compiler using +# the member name, in uppercase, prepended with 'HAVE_ST_'. +# +# For example, if have_struct_member('foo', 'bar') returned true, then the +# HAVE_ST_BAR preprocessor macro would be passed to the compiler. +# +def have_struct_member(type, member, headers = nil, &b) + checking_for checking_message("#{type}.#{member}", headers) do + if try_compile(<<"SRC", &b) +#{COMMON_HEADERS} +#{cpp_include(headers)} +/*top*/ +int main() { return 0; } +int s = (char *)&((#{type}*)0)->#{member} - (char *)0; +SRC + $defs.push(format("-DHAVE_ST_%s", member.upcase)) + true + else + false + end + end +end + +# Returns whether or not the static type +type+ is defined. You may +# optionally pass additional +headers+ to check against in addition to the +# common header files. +# +# You may also pass additional flags to +opt+ which are then passed along to +# the compiler. +# +# If found, a macro is passed as a preprocessor constant to the compiler using +# the type name, in uppercase, prepended with 'HAVE_TYPE_'. +# +# For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO +# preprocessor macro would be passed to the compiler. +# +def have_type(type, headers = nil, opt = "", &b) + checking_for checking_message(type, headers, opt) do + headers = cpp_include(headers) + if try_compile(<<"SRC", opt, &b) +#{COMMON_HEADERS} +#{headers} +/*top*/ +typedef #{type} conftest_type; +static conftest_type conftestval[sizeof(conftest_type)?1:-1]; +SRC + $defs.push(format("-DHAVE_TYPE_%s", type.strip.upcase.tr_s("^A-Z0-9_", "_"))) + true + else + false + end + end +end + +# Returns the size of the given +type+. You may optionally specify additional +# +headers+ to search in for the +type+. +# +# If found, a macro is passed as a preprocessor constant to the compiler using +# the type name, in uppercase, prepended with 'SIZEOF_', followed by the type +# name, followed by '=X' where 'X' is the actual size. +# +# For example, if check_sizeof('mystruct') returned 12, then the +# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler. +# +def check_sizeof(type, headers = nil, &b) + expr = "sizeof(#{type})" + fmt = "%d" + def fmt.%(x) + x ? super : "failed" + end + checking_for checking_message("size of #{type}", headers), fmt do + if size = try_constant(expr, headers, &b) + $defs.push(format("-DSIZEOF_%s=%d", type.upcase.tr_s("^A-Z0-9_", "_"), size)) + size + end + end +end + +def scalar_ptr_type?(type, member = nil, headers = nil, &b) + try_compile(<<"SRC", &b) # pointer +#{COMMON_HEADERS} +#{cpp_include(headers)} +/*top*/ +volatile #{type} conftestval; +int main() { return 0; } +int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));} +SRC +end + +def scalar_type?(type, member = nil, headers = nil, &b) + try_compile(<<"SRC", &b) # pointer +#{COMMON_HEADERS} +#{cpp_include(headers)} +/*top*/ +volatile #{type} conftestval; +int main() { return 0; } +int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));} +SRC +end + +def what_type?(type, member = nil, headers = nil, &b) + m = "#{type}" + name = type + if member + m << "." << member + name = "(((#{type} *)0)->#{member})" + end + fmt = "seems %s" + def fmt.%(x) + x ? super : "unknown" + end + checking_for checking_message(m, headers), fmt do + if scalar_ptr_type?(type, member, headers, &b) + if try_static_assert("sizeof(*#{name}) == 1", headers) + "string" + end + elsif scalar_type?(type, member, headers, &b) + if try_static_assert("sizeof(#{name}) > sizeof(long)", headers) + "long long" + elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers) + "long" + elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers) + "int" + elsif try_static_assert("sizeof(#{name}) > 1", headers) + "short" + else + "char" + end + end + end +end + +def find_executable0(bin, path = nil) + ext = config_string('EXEEXT') + if File.expand_path(bin) == bin + return bin if File.executable?(bin) + ext and File.executable?(file = bin + ext) and return file + return nil + end + if path ||= ENV['PATH'] + path = path.split(File::PATH_SEPARATOR) + else + path = %w[/usr/local/bin /usr/ucb /usr/bin /bin] + end + file = nil + path.each do |dir| + return file if File.executable?(file = File.join(dir, bin)) + return file if ext and File.executable?(file << ext) + end + nil +end + +def find_executable(bin, path = nil) + checking_for checking_message(bin, path) do + find_executable0(bin, path) + end +end + +def arg_config(config, *defaults, &block) + $arg_config << [config, *defaults] + defaults << nil if !block and defaults.empty? + $configure_args.fetch(config.tr('_', '-'), *defaults, &block) +end + +def with_config(config, *defaults) + config = config.sub(/^--with[-_]/, '') + val = arg_config("--with-"+config) do + if arg_config("--without-"+config) + false + elsif block_given? + yield(config, *defaults) + else + break *defaults + end + end + case val + when "yes" + true + when "no" + false + else + val + end +end + +def enable_config(config, *defaults) + if arg_config("--enable-"+config) + true + elsif arg_config("--disable-"+config) + false + elsif block_given? + yield(config, *defaults) + else + return *defaults + end +end + +def create_header(header = "extconf.h") + message "creating %s\n", header + sym = header.tr("a-z./\055", "A-Z___") + hdr = ["#ifndef #{sym}\n#define #{sym}\n"] + for line in $defs + case line + when /^-D([^=]+)(?:=(.*))?/ + hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n" + when /^-U(.*)/ + hdr << "#undef #$1\n" + end + end + hdr << "#endif\n" + hdr = hdr.join + unless (IO.read(header) == hdr rescue false) + open(header, "w") do |hfile| + hfile.write(hdr) + end + end + $extconf_h = header +end + +# Sets a +target+ name that the user can then use to configure various 'with' +# options with on the command line by using that name. For example, if the +# target is set to "foo", then the user could use the --with-foo-dir command +# line option. +# +# You may pass along additional 'include' or 'lib' defaults via the +idefault+ +# and +ldefault+ parameters, respectively. +# +# Note that dir_config only adds to the list of places to search for libraries +# and include files. It does not link the libraries into your application. +# +def dir_config(target, idefault=nil, ldefault=nil) + if dir = with_config(target + "-dir", (idefault unless ldefault)) + defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR) + idefault = ldefault = nil + end + + idir = with_config(target + "-include", idefault) + $arg_config.last[1] ||= "${#{target}-dir}/include" + ldir = with_config(target + "-lib", ldefault) + $arg_config.last[1] ||= "${#{target}-dir}/lib" + + idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : [] + if defaults + idirs.concat(defaults.collect {|dir| dir + "/include"}) + idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR) + end + unless idirs.empty? + idirs.collect! {|dir| "-I" + dir} + idirs -= Shellwords.shellwords($CPPFLAGS) + unless idirs.empty? + $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ") + end + end + + ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : [] + if defaults + ldirs.concat(defaults.collect {|dir| dir + "/lib"}) + ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR) + end + $LIBPATH = ldirs | $LIBPATH + + [idir, ldir] +end + +def pkg_config(pkg) + if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig) + # iff package specific config command is given + get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} + elsif ($PKGCONFIG ||= + (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) && + find_executable0(pkgconfig) && pkgconfig) and + system("#{$PKGCONFIG} --exists #{pkg}") + # default to pkg-config command + get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp} + elsif find_executable0(pkgconfig = "#{pkg}-config") + # default to package specific config command, as a last resort. + get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp} + end + if get + cflags = get['cflags'] + ldflags = get['libs'] + libs = get['libs-only-l'] + ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ") + $CFLAGS += " " << cflags + $LDFLAGS += " " << ldflags + $libs += " " << libs + Logging::message "package configuration for %s\n", pkg + Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n", + cflags, ldflags, libs + [cflags, ldflags, libs] + else + Logging::message "package configuration for %s is not found\n", pkg + nil + end +end + +def with_destdir(dir) + dir = dir.sub($dest_prefix_pattern, '') + /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir +end + +def winsep(s) + s.tr('/', '\\') +end + +def configuration(srcdir) + mk = [] + vpath = %w[$(srcdir) $(topdir) $(hdrdir)] + if !CROSS_COMPILING + case CONFIG['build_os'] + when 'cygwin' + if CONFIG['target_os'] != 'cygwin' + vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')} + end + when 'msdosdjgpp', 'mingw32' + CONFIG['PATH_SEPARATOR'] = ';' + end + end + mk << %{ +SHELL = /bin/sh + +#### Start of system configuration section. #### + +srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {CONFIG[$1||$2]}.quote} +topdir = #{($extmk ? CONFIG["topdir"] : $topdir).quote} +hdrdir = #{$extmk ? CONFIG["hdrdir"].quote : '$(topdir)'} +VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])} +} + if $extmk + mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n" + end + if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1] + mk << "\nDESTDIR = #{destdir}\n" + end + CONFIG.each do |key, var| + next unless /prefix$/ =~ key + mk << "#{key} = #{with_destdir(var)}\n" + end + CONFIG.each do |key, var| + next if /^abs_/ =~ key + next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1 + mk << "#{key} = #{with_destdir(var)}\n" + end + if !$extmk and !$configure_args.has_key?('--ruby') and + sep = config_string('BUILD_FILE_SEPARATOR') + sep = ":/=#{sep}" + else + sep = "" + end + extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" " + mk << %{ +CC = #{CONFIG['CC']} +LIBRUBY = #{CONFIG['LIBRUBY']} +LIBRUBY_A = #{CONFIG['LIBRUBY_A']} +LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED +LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC + +RUBY_EXTCONF_H = #{$extconf_h} +CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG +INCFLAGS = -I. #$INCFLAGS +DEFS = #{CONFIG['DEFS']} +CPPFLAGS = #{extconf_h}#{$CPPFLAGS} +CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']} +DLDFLAGS = #$LDFLAGS #$DLDFLAGS #$ARCH_FLAG +LDSHARED = #{CONFIG['LDSHARED']} +AR = #{CONFIG['AR']} +EXEEXT = #{CONFIG['EXEEXT']} + +RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']} +RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']} +arch = #{CONFIG['arch']} +sitearch = #{CONFIG['sitearch']} +ruby_version = #{Config::CONFIG['ruby_version']} +ruby = #{$ruby} +RUBY = $(ruby#{sep}) +RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'} +MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'} +INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'} +INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'} +INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'} +COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'} + +#### End of system configuration section. #### + +preload = #{$preload ? $preload.join(' ') : ''} +} + if $nmake == ?b + mk.each do |x| + x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do + "!ifndef " + $1 + "\n" + + $& + + "!endif\n" + end + end + end + mk +end + +def dummy_makefile(srcdir) + configuration(srcdir) << <>$(INSTALLED_LIST)\n" + end + end + end + mfile.print("install-rb: pre-install-rb install-rb-default\n") + mfile.print("install-rb-default: pre-install-rb-default\n") + mfile.print("pre-install-rb: Makefile\n") + mfile.print("pre-install-rb-default: Makefile\n") + for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]] + files = install_files(mfile, i, nil, srcprefix) or next + for dir, *files in files + unless dirs.include?(dir) + dirs << dir + mfile.print "pre-install-rb#{sfx}: #{dir}\n" + end + files.each do |f| + dest = "#{dir}/#{File.basename(f)}" + mfile.print("install-rb#{sfx}: #{dest}\n") + mfile.print("#{dest}: #{f}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ") + sep = config_string('BUILD_FILE_SEPARATOR') + if sep + f = f.gsub("/", sep) + sep = ":/="+sep + f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2} + f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2} + else + sep = "" + end + mfile.print("#{f} $(@D#{sep})\n") + if defined?($installed_list) and !$extout + mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n") + end + end + end + end + dirs.unshift(sodir) if target and !dirs.include?(sodir) + dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"} + + mfile.print <<-SITEINSTALL + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + + SITEINSTALL + + return unless target + + mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b + mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n" + mfile.print "\n" + + CXX_EXT.each do |ext| + COMPILE_RULES.each do |rule| + mfile.printf(rule, ext, $OBJEXT) + mfile.printf("\n\t%s\n\n", COMPILE_CXX) + end + end + %w[c].each do |ext| + COMPILE_RULES.each do |rule| + mfile.printf(rule, ext, $OBJEXT) + mfile.printf("\n\t%s\n\n", COMPILE_C) + end + end + + mfile.print "$(RUBYARCHDIR)/" if $extout + mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n" + mfile.print "\t@-$(RM) $@\n" + mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout + link_so = LINK_SO.gsub(/^/, "\t") + mfile.print link_so, "\n\n" + unless $static.nil? + mfile.print "$(STATIC_LIB): $(OBJS)\n\t" + mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)" + config_string('RANLIB') do |ranlib| + mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true" + end + end + mfile.print "\n\n" + if makedef + mfile.print "$(DEFFILE): #{origdef}\n" + mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n" + end + + depend = File.join(srcdir, "depend") + if File.exist?(depend) + suffixes = [] + depout = [] + open(depend, "r") do |dfile| + mfile.printf "###\n" + cont = implicit = nil + impconv = proc do + COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]} + implicit = nil + end + ruleconv = proc do |line| + if implicit + if /\A\t/ =~ line + implicit[1] << line + next + else + impconv[] + end + end + if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line) + suffixes << m[1] << m[2] + implicit = [[m[1], m[2]], [m.post_match]] + next + elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line + line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2} + end + depout << line + end + while line = dfile.gets() + line.gsub!(/\.o\b/, ".#{$OBJEXT}") + line.gsub!(/\$\(hdrdir\)\/config.h/, $config_h) if $config_h + if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line + (cont ||= []) << line + next + elsif cont + line = (cont << line).join + cont = nil + end + ruleconv.call(line) + end + if cont + ruleconv.call(cont.join) + elsif implicit + impconv.call + end + end + unless suffixes.empty? + mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n" + end + mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h + mfile.print depout + else + headers = %w[ruby.h defines.h] + if RULE_SUBST + headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}} + end + headers << $config_h if $config_h + headers << "$(RUBY_EXTCONF_H)" if $extconf_h + mfile.print "$(OBJS): ", headers.join(' '), "\n" + end + + $makefile_created = true +ensure + mfile.close if mfile +end + +def init_mkmf(config = CONFIG) + $makefile_created = false + $arg_config = [] + $enable_shared = config['ENABLE_SHARED'] == 'yes' + $defs = [] + $extconf_h = nil + $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup + $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup + $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup + $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup + $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)" + $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup + $LIBEXT = config['LIBEXT'].dup + $OBJEXT = config["OBJEXT"].dup + $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}" + $LIBRUBYARG = "" + $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC'] + $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED'] + $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"] + $DEFLIBPATH.unshift(".") + $LIBPATH = [] + $INSTALLFILES = nil + + $objs = nil + $srcs = nil + $libs = "" + if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup) + $LIBRUBYARG = config['LIBRUBYARG'] + end + + $LOCAL_LIBS = "" + + $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || [] + $cleanfiles << "mkmf.log" + $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || [] + + $extout ||= nil + $extout_prefix ||= nil + + $arg_config.clear + dir_config("opt") +end + +FailedMessage = <"} +end +COMMON_HEADERS = hdr.join("\n") +COMMON_LIBS = config_string('COMMON_LIBS', &split) || [] + +COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:] +RULE_SUBST = config_string('RULE_SUBST') +COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<' +COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<' +TRY_LINK = config_string('TRY_LINK') || + "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \ + "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)" +LINK_SO = config_string('LINK_SO') || + if CONFIG["DLEXT"] == $OBJEXT + "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n" + else + "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \ + "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)" + end +LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"' +RPATHFLAG = config_string('RPATHFLAG') || '' +LIBARG = config_string('LIBARG') || '-l%s' + +sep = config_string('BUILD_FILE_SEPARATOR') {|sep| ":/=#{sep}" if sep != "/"} || "" +CLEANINGS = " +clean: + @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) + +distclean: clean + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep}) + +realclean: distclean +" + +if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0) + END {mkmf_failed($0)} +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/monitor.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/monitor.rb new file mode 100644 index 00000000..4c146c80 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/monitor.rb @@ -0,0 +1,352 @@ +=begin + += monitor.rb + +Copyright (C) 2001 Shugo Maeda + +This library is distributed under the terms of the Ruby license. +You can freely distribute/modify this library. + +== example + +This is a simple example. + + require 'monitor.rb' + + buf = [] + buf.extend(MonitorMixin) + empty_cond = buf.new_cond + + # consumer + Thread.start do + loop do + buf.synchronize do + empty_cond.wait_while { buf.empty? } + print buf.shift + end + end + end + + # producer + while line = ARGF.gets + buf.synchronize do + buf.push(line) + empty_cond.signal + end + end + +The consumer thread waits for the producer thread to push a line +to buf while buf.empty?, and the producer thread (main thread) +reads a line from ARGF and push it to buf, then call +empty_cond.signal. + +=end + + +# +# Adds monitor functionality to an arbitrary object by mixing the module with +# +include+. For example: +# +# require 'monitor.rb' +# +# buf = [] +# buf.extend(MonitorMixin) +# empty_cond = buf.new_cond +# +# # consumer +# Thread.start do +# loop do +# buf.synchronize do +# empty_cond.wait_while { buf.empty? } +# print buf.shift +# end +# end +# end +# +# # producer +# while line = ARGF.gets +# buf.synchronize do +# buf.push(line) +# empty_cond.signal +# end +# end +# +# The consumer thread waits for the producer thread to push a line +# to buf while buf.empty?, and the producer thread (main thread) +# reads a line from ARGF and push it to buf, then call +# empty_cond.signal. +# +module MonitorMixin + # + # FIXME: This isn't documented in Nutshell. + # + # Since MonitorMixin.new_cond returns a ConditionVariable, and the example + # above calls while_wait and signal, this class should be documented. + # + class ConditionVariable + class Timeout < Exception; end + + # Create a new timer with the argument timeout, and add the + # current thread to the list of waiters. Then the thread is + # stopped. It will be resumed when a corresponding #signal + # occurs. + def wait(timeout = nil) + @monitor.instance_eval {mon_check_owner()} + timer = create_timer(timeout) + + Thread.critical = true + count = @monitor.instance_eval {mon_exit_for_cond()} + @waiters.push(Thread.current) + + begin + Thread.stop + return true + rescue Timeout + return false + ensure + Thread.critical = true + begin + if timer && timer.alive? + Thread.kill(timer) + end + if @waiters.include?(Thread.current) # interrupted? + @waiters.delete(Thread.current) + end + @monitor.instance_eval {mon_enter_for_cond(count)} + ensure + Thread.critical = false + end + end + end + + + # call #wait while the supplied block returns +true+. + def wait_while + while yield + wait + end + end + + # call #wait until the supplied block returns +true+. + def wait_until + until yield + wait + end + end + + # Wake up and run the next waiter + def signal + @monitor.instance_eval {mon_check_owner()} + Thread.critical = true + t = @waiters.shift + t.wakeup if t + Thread.critical = false + Thread.pass + end + + # Wake up all the waiters. + def broadcast + @monitor.instance_eval {mon_check_owner()} + Thread.critical = true + for t in @waiters + t.wakeup + end + @waiters.clear + Thread.critical = false + Thread.pass + end + + def count_waiters + return @waiters.length + end + + private + + def initialize(monitor) + @monitor = monitor + @waiters = [] + end + + def create_timer(timeout) + if timeout + waiter = Thread.current + return Thread.start { + Thread.pass + sleep(timeout) + Thread.critical = true + waiter.raise(Timeout.new) + } + else + return nil + end + end + end + + def self.extend_object(obj) + super(obj) + obj.instance_eval {mon_initialize()} + end + + # + # Attempts to enter exclusive section. Returns +false+ if lock fails. + # + def mon_try_enter + result = false + Thread.critical = true + if @mon_owner.nil? + @mon_owner = Thread.current + end + if @mon_owner == Thread.current + @mon_count += 1 + result = true + end + Thread.critical = false + return result + end + # For backward compatibility + alias try_mon_enter mon_try_enter + + # + # Enters exclusive section. + # + def mon_enter + Thread.critical = true + mon_acquire(@mon_entering_queue) + @mon_count += 1 + ensure + Thread.critical = false + end + + # + # Leaves exclusive section. + # + def mon_exit + mon_check_owner + Thread.critical = true + @mon_count -= 1 + if @mon_count == 0 + mon_release + end + Thread.critical = false + Thread.pass + end + + # + # Enters exclusive section and executes the block. Leaves the exclusive + # section automatically when the block exits. See example under + # +MonitorMixin+. + # + def mon_synchronize + mon_enter + begin + yield + ensure + mon_exit + end + end + alias synchronize mon_synchronize + + # + # FIXME: This isn't documented in Nutshell. + # + # Create a new condition variable for this monitor. + # This facilitates control of the monitor with #signal and #wait. + # + def new_cond + return ConditionVariable.new(self) + end + + private + + def initialize(*args) + super + mon_initialize + end + + # called by initialize method to set defaults for instance variables. + def mon_initialize + @mon_owner = nil + @mon_count = 0 + @mon_entering_queue = [] + @mon_waiting_queue = [] + end + + # Throw a ThreadError exception if the current thread + # does't own the monitor + def mon_check_owner + if @mon_owner != Thread.current + raise ThreadError, "current thread not owner" + end + end + + def mon_acquire(queue) + while @mon_owner && @mon_owner != Thread.current + queue.push(Thread.current) + Thread.stop + Thread.critical = true + end + @mon_owner = Thread.current + end + + def mon_release + @mon_owner = nil + t = @mon_waiting_queue.shift + t = @mon_entering_queue.shift unless t + t.wakeup if t + end + + def mon_enter_for_cond(count) + mon_acquire(@mon_waiting_queue) + @mon_count = count + end + + def mon_exit_for_cond + count = @mon_count + @mon_count = 0 + return count + ensure + mon_release + end +end + +# Monitors provide means of mutual exclusion for Thread programming. +# A critical region is created by means of the synchronize method, +# which takes a block. +# The condition variables (created with #new_cond) may be used +# to control the execution of a monitor with #signal and #wait. +# +# the Monitor class wraps MonitorMixin, and provides aliases +# alias try_enter try_mon_enter +# alias enter mon_enter +# alias exit mon_exit +# to access its methods more concisely. +class Monitor + include MonitorMixin + alias try_enter try_mon_enter + alias enter mon_enter + alias exit mon_exit +end + + +# Documentation comments: +# - All documentation comes from Nutshell. +# - MonitorMixin.new_cond appears in the example, but is not documented in +# Nutshell. +# - All the internals (internal modules Accessible and Initializable, class +# ConditionVariable) appear in RDoc. It might be good to hide them, by +# making them private, or marking them :nodoc:, etc. +# - The entire example from the RD section at the top is replicated in the RDoc +# comment for MonitorMixin. Does the RD section need to remain? +# - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but +# not synchronize. +# - mon_owner is in Nutshell, but appears as an accessor in a separate module +# here, so is hard/impossible to RDoc. Some other useful accessors +# (mon_count and some queue stuff) are also in this module, and don't appear +# directly in the RDoc output. +# - in short, it may be worth changing the code layout in this file to make the +# documentation easier + +# Local variables: +# mode: Ruby +# tab-width: 8 +# End: diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mutex_m.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mutex_m.rb new file mode 100644 index 00000000..8e0d42bc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/mutex_m.rb @@ -0,0 +1,122 @@ +#-- +# mutex_m.rb - +# $Release Version: 3.0$ +# $Revision: 1.7 $ +# $Date: 1998/02/27 04:28:57 $ +# Original from mutex.rb +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# modified by matz +# patched by akira yamada +#++ +# +# == Usage +# +# Extend an object and use it like a Mutex object: +# +# require "mutex_m.rb" +# obj = Object.new +# obj.extend Mutex_m +# # ... +# +# Or, include Mutex_m in a class to have its instances behave like a Mutex +# object: +# +# class Foo +# include Mutex_m +# # ... +# end +# +# obj = Foo.new + +module Mutex_m + def Mutex_m.define_aliases(cl) + cl.module_eval %q{ + alias locked? mu_locked? + alias lock mu_lock + alias unlock mu_unlock + alias try_lock mu_try_lock + alias synchronize mu_synchronize + } + end + + def Mutex_m.append_features(cl) + super + define_aliases(cl) unless cl.instance_of?(Module) + end + + def Mutex_m.extend_object(obj) + super + obj.mu_extended + end + + def mu_extended + unless (defined? locked? and + defined? lock and + defined? unlock and + defined? try_lock and + defined? synchronize) + Mutex_m.define_aliases(class<. +# +# Documentation by Gavin Sinclair, sourced from "Programming Ruby" (Hunt/Thomas) +# and "Ruby In a Nutshell" (Matsumoto), used with permission. +# +# This library is distributed under the terms of the Ruby license. +# You can freely distribute/modify this library. +# +# It is included in the Ruby standard library. +# +# See the Net::FTP class for an overview. +# + +require "socket" +require "monitor" + +module Net + + # :stopdoc: + class FTPError < StandardError; end + class FTPReplyError < FTPError; end + class FTPTempError < FTPError; end + class FTPPermError < FTPError; end + class FTPProtoError < FTPError; end + # :startdoc: + + # + # This class implements the File Transfer Protocol. If you have used a + # command-line FTP program, and are familiar with the commands, you will be + # able to use this class easily. Some extra features are included to take + # advantage of Ruby's style and strengths. + # + # == Example + # + # require 'net/ftp' + # + # === Example 1 + # + # ftp = Net::FTP.new('ftp.netlab.co.jp') + # ftp.login + # files = ftp.chdir('pub/lang/ruby/contrib') + # files = ftp.list('n*') + # ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024) + # ftp.close + # + # === Example 2 + # + # Net::FTP.open('ftp.netlab.co.jp') do |ftp| + # ftp.login + # files = ftp.chdir('pub/lang/ruby/contrib') + # files = ftp.list('n*') + # ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024) + # end + # + # == Major Methods + # + # The following are the methods most likely to be useful to users: + # - FTP.open + # - #getbinaryfile + # - #gettextfile + # - #putbinaryfile + # - #puttextfile + # - #chdir + # - #nlst + # - #size + # - #rename + # - #delete + # + class FTP + include MonitorMixin + + # :stopdoc: + FTP_PORT = 21 + CRLF = "\r\n" + DEFAULT_BLOCKSIZE = 4096 + # :startdoc: + + # When +true+, transfers are performed in binary mode. Default: +true+. + attr_accessor :binary + + # When +true+, the connection is in passive mode. Default: +false+. + attr_accessor :passive + + # When +true+, all traffic to and from the server is written + # to +$stdout+. Default: +false+. + attr_accessor :debug_mode + + # Sets or retrieves the +resume+ status, which decides whether incomplete + # transfers are resumed or restarted. Default: +false+. + attr_accessor :resume + + # The server's welcome message. + attr_reader :welcome + + # The server's last response code. + attr_reader :last_response_code + alias lastresp last_response_code + + # The server's last response. + attr_reader :last_response + + # + # A synonym for FTP.new, but with a mandatory host parameter. + # + # If a block is given, it is passed the +FTP+ object, which will be closed + # when the block finishes, or when an exception is raised. + # + def FTP.open(host, user = nil, passwd = nil, acct = nil) + if block_given? + ftp = new(host, user, passwd, acct) + begin + yield ftp + ensure + ftp.close + end + else + new(host, user, passwd, acct) + end + end + + # + # Creates and returns a new +FTP+ object. If a +host+ is given, a connection + # is made. Additionally, if the +user+ is given, the given user name, + # password, and (optionally) account are used to log in. See #login. + # + def initialize(host = nil, user = nil, passwd = nil, acct = nil) + super() + @binary = true + @passive = false + @debug_mode = false + @resume = false + if host + connect(host) + if user + login(user, passwd, acct) + end + end + end + + # Obsolete + def return_code + $stderr.puts("warning: Net::FTP#return_code is obsolete and do nothing") + return "\n" + end + + # Obsolete + def return_code=(s) + $stderr.puts("warning: Net::FTP#return_code= is obsolete and do nothing") + end + + def open_socket(host, port) + if defined? SOCKSsocket and ENV["SOCKS_SERVER"] + @passive = true + return SOCKSsocket.open(host, port) + else + return TCPSocket.open(host, port) + end + end + private :open_socket + + # + # Establishes an FTP connection to host, optionally overriding the default + # port. If the environment variable +SOCKS_SERVER+ is set, sets up the + # connection through a SOCKS proxy. Raises an exception (typically + # Errno::ECONNREFUSED) if the connection cannot be established. + # + def connect(host, port = FTP_PORT) + if @debug_mode + print "connect: ", host, ", ", port, "\n" + end + synchronize do + @sock = open_socket(host, port) + voidresp + end + end + + # + # WRITEME or make private + # + def set_socket(sock, get_greeting = true) + synchronize do + @sock = sock + if get_greeting + voidresp + end + end + end + + def sanitize(s) + if s =~ /^PASS /i + return s[0, 5] + "*" * (s.length - 5) + else + return s + end + end + private :sanitize + + def putline(line) + if @debug_mode + print "put: ", sanitize(line), "\n" + end + line = line + CRLF + @sock.write(line) + end + private :putline + + def getline + line = @sock.readline # if get EOF, raise EOFError + line.sub!(/(\r\n|\n|\r)\z/n, "") + if @debug_mode + print "get: ", sanitize(line), "\n" + end + return line + end + private :getline + + def getmultiline + line = getline + buff = line + if line[3] == ?- + code = line[0, 3] + begin + line = getline + buff << "\n" << line + end until line[0, 3] == code and line[3] != ?- + end + return buff << "\n" + end + private :getmultiline + + def getresp + @last_response = getmultiline + @last_response_code = @last_response[0, 3] + case @last_response_code + when /\A[123]/ + return @last_response + when /\A4/ + raise FTPTempError, @last_response + when /\A5/ + raise FTPPermError, @last_response + else + raise FTPProtoError, @last_response + end + end + private :getresp + + def voidresp + resp = getresp + if resp[0] != ?2 + raise FTPReplyError, resp + end + end + private :voidresp + + # + # Sends a command and returns the response. + # + def sendcmd(cmd) + synchronize do + putline(cmd) + return getresp + end + end + + # + # Sends a command and expect a response beginning with '2'. + # + def voidcmd(cmd) + synchronize do + putline(cmd) + voidresp + end + end + + def sendport(host, port) + af = (@sock.peeraddr)[0] + if af == "AF_INET" + cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",") + elsif af == "AF_INET6" + cmd = sprintf("EPRT |2|%s|%d|", host, port) + else + raise FTPProtoError, host + end + voidcmd(cmd) + end + private :sendport + + def makeport + sock = TCPServer.open(@sock.addr[3], 0) + port = sock.addr[1] + host = sock.addr[3] + resp = sendport(host, port) + return sock + end + private :makeport + + def makepasv + if @sock.peeraddr[0] == "AF_INET" + host, port = parse227(sendcmd("PASV")) + else + host, port = parse229(sendcmd("EPSV")) + # host, port = parse228(sendcmd("LPSV")) + end + return host, port + end + private :makepasv + + def transfercmd(cmd, rest_offset = nil) + if @passive + host, port = makepasv + conn = open_socket(host, port) + if @resume and rest_offset + resp = sendcmd("REST " + rest_offset.to_s) + if resp[0] != ?3 + raise FTPReplyError, resp + end + end + resp = sendcmd(cmd) + if resp[0] != ?1 + raise FTPReplyError, resp + end + else + sock = makeport + if @resume and rest_offset + resp = sendcmd("REST " + rest_offset.to_s) + if resp[0] != ?3 + raise FTPReplyError, resp + end + end + resp = sendcmd(cmd) + if resp[0] != ?1 + raise FTPReplyError, resp + end + conn = sock.accept + sock.close + end + return conn + end + private :transfercmd + + def getaddress + thishost = Socket.gethostname + if not thishost.index(".") + thishost = Socket.gethostbyname(thishost)[0] + end + if ENV.has_key?("LOGNAME") + realuser = ENV["LOGNAME"] + elsif ENV.has_key?("USER") + realuser = ENV["USER"] + else + realuser = "anonymous" + end + return realuser + "@" + thishost + end + private :getaddress + + # + # Logs in to the remote host. The session must have been previously + # connected. If +user+ is the string "anonymous" and the +password+ is + # +nil+, a password of user@host is synthesized. If the +acct+ + # parameter is not +nil+, an FTP ACCT command is sent following the + # successful login. Raises an exception on error (typically + # Net::FTPPermError). + # + def login(user = "anonymous", passwd = nil, acct = nil) + if user == "anonymous" and passwd == nil + passwd = getaddress + end + + resp = "" + synchronize do + resp = sendcmd('USER ' + user) + if resp[0] == ?3 + resp = sendcmd('PASS ' + passwd) + end + if resp[0] == ?3 + resp = sendcmd('ACCT ' + acct) + end + end + if resp[0] != ?2 + raise FTPReplyError, resp + end + @welcome = resp + end + + # + # Puts the connection into binary (image) mode, issues the given command, + # and fetches the data returned, passing it to the associated block in + # chunks of +blocksize+ characters. Note that +cmd+ is a server command + # (such as "RETR myfile"). + # + def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data + synchronize do + voidcmd("TYPE I") + conn = transfercmd(cmd, rest_offset) + loop do + data = conn.read(blocksize) + break if data == nil + yield(data) + end + conn.close + voidresp + end + end + + # + # Puts the connection into ASCII (text) mode, issues the given command, and + # passes the resulting data, one line at a time, to the associated block. If + # no block is given, prints the lines. Note that +cmd+ is a server command + # (such as "RETR myfile"). + # + def retrlines(cmd) # :yield: line + synchronize do + voidcmd("TYPE A") + conn = transfercmd(cmd) + loop do + line = conn.gets + break if line == nil + if line[-2, 2] == CRLF + line = line[0 .. -3] + elsif line[-1] == ?\n + line = line[0 .. -2] + end + yield(line) + end + conn.close + voidresp + end + end + + # + # Puts the connection into binary (image) mode, issues the given server-side + # command (such as "STOR myfile"), and sends the contents of the file named + # +file+ to the server. If the optional block is given, it also passes it + # the data, in chunks of +blocksize+ characters. + # + def storbinary(cmd, file, blocksize, rest_offset = nil, &block) # :yield: data + if rest_offset + file.seek(rest_offset, IO::SEEK_SET) + end + synchronize do + voidcmd("TYPE I") + conn = transfercmd(cmd, rest_offset) + loop do + buf = file.read(blocksize) + break if buf == nil + conn.write(buf) + yield(buf) if block + end + conn.close + voidresp + end + end + + # + # Puts the connection into ASCII (text) mode, issues the given server-side + # command (such as "STOR myfile"), and sends the contents of the file + # named +file+ to the server, one line at a time. If the optional block is + # given, it also passes it the lines. + # + def storlines(cmd, file, &block) # :yield: line + synchronize do + voidcmd("TYPE A") + conn = transfercmd(cmd) + loop do + buf = file.gets + break if buf == nil + if buf[-2, 2] != CRLF + buf = buf.chomp + CRLF + end + conn.write(buf) + yield(buf) if block + end + conn.close + voidresp + end + end + + # + # Retrieves +remotefile+ in binary mode, storing the result in +localfile+. + # If a block is supplied, it is passed the retrieved data in +blocksize+ + # chunks. + # + def getbinaryfile(remotefile, localfile = File.basename(remotefile), + blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data + if @resume + rest_offset = File.size?(localfile) + f = open(localfile, "a") + else + rest_offset = nil + f = open(localfile, "w") + end + begin + f.binmode + retrbinary("RETR " + remotefile, blocksize, rest_offset) do |data| + f.write(data) + yield(data) if block + end + ensure + f.close + end + end + + # + # Retrieves +remotefile+ in ASCII (text) mode, storing the result in + # +localfile+. If a block is supplied, it is passed the retrieved data one + # line at a time. + # + def gettextfile(remotefile, localfile = File.basename(remotefile), &block) # :yield: line + f = open(localfile, "w") + begin + retrlines("RETR " + remotefile) do |line| + f.puts(line) + yield(line) if block + end + ensure + f.close + end + end + + # + # Retrieves +remotefile+ in whatever mode the session is set (text or + # binary). See #gettextfile and #getbinaryfile. + # + def get(remotefile, localfile = File.basename(remotefile), + blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data + unless @binary + gettextfile(remotefile, localfile, &block) + else + getbinaryfile(remotefile, localfile, blocksize, &block) + end + end + + # + # Transfers +localfile+ to the server in binary mode, storing the result in + # +remotefile+. If a block is supplied, calls it, passing in the transmitted + # data in +blocksize+ chunks. + # + def putbinaryfile(localfile, remotefile = File.basename(localfile), + blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data + if @resume + begin + rest_offset = size(remotefile) + rescue Net::FTPPermError + rest_offset = nil + end + else + rest_offset = nil + end + f = open(localfile) + begin + f.binmode + storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block) + ensure + f.close + end + end + + # + # Transfers +localfile+ to the server in ASCII (text) mode, storing the result + # in +remotefile+. If callback or an associated block is supplied, calls it, + # passing in the transmitted data one line at a time. + # + def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line + f = open(localfile) + begin + storlines("STOR " + remotefile, f, &block) + ensure + f.close + end + end + + # + # Transfers +localfile+ to the server in whatever mode the session is set + # (text or binary). See #puttextfile and #putbinaryfile. + # + def put(localfile, remotefile = File.basename(localfile), + blocksize = DEFAULT_BLOCKSIZE, &block) + unless @binary + puttextfile(localfile, remotefile, &block) + else + putbinaryfile(localfile, remotefile, blocksize, &block) + end + end + + # + # Sends the ACCT command. TODO: more info. + # + def acct(account) + cmd = "ACCT " + account + voidcmd(cmd) + end + + # + # Returns an array of filenames in the remote directory. + # + def nlst(dir = nil) + cmd = "NLST" + if dir + cmd = cmd + " " + dir + end + files = [] + retrlines(cmd) do |line| + files.push(line) + end + return files + end + + # + # Returns an array of file information in the directory (the output is like + # `ls -l`). If a block is given, it iterates through the listing. + # + def list(*args, &block) # :yield: line + cmd = "LIST" + args.each do |arg| + cmd = cmd + " " + arg + end + if block + retrlines(cmd, &block) + else + lines = [] + retrlines(cmd) do |line| + lines << line + end + return lines + end + end + alias ls list + alias dir list + + # + # Renames a file on the server. + # + def rename(fromname, toname) + resp = sendcmd("RNFR " + fromname) + if resp[0] != ?3 + raise FTPReplyError, resp + end + voidcmd("RNTO " + toname) + end + + # + # Deletes a file on the server. + # + def delete(filename) + resp = sendcmd("DELE " + filename) + if resp[0, 3] == "250" + return + elsif resp[0] == ?5 + raise FTPPermError, resp + else + raise FTPReplyError, resp + end + end + + # + # Changes the (remote) directory. + # + def chdir(dirname) + if dirname == ".." + begin + voidcmd("CDUP") + return + rescue FTPPermError + if $![0, 3] != "500" + raise FTPPermError, $! + end + end + end + cmd = "CWD " + dirname + voidcmd(cmd) + end + + # + # Returns the size of the given (remote) filename. + # + def size(filename) + voidcmd("TYPE I") + resp = sendcmd("SIZE " + filename) + if resp[0, 3] != "213" + raise FTPReplyError, resp + end + return resp[3..-1].strip.to_i + end + + MDTM_REGEXP = /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ # :nodoc: + + # + # Returns the last modification time of the (remote) file. If +local+ is + # +true+, it is returned as a local time, otherwise it's a UTC time. + # + def mtime(filename, local = false) + str = mdtm(filename) + ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i} + return local ? Time.local(*ary) : Time.gm(*ary) + end + + # + # Creates a remote directory. + # + def mkdir(dirname) + resp = sendcmd("MKD " + dirname) + return parse257(resp) + end + + # + # Removes a remote directory. + # + def rmdir(dirname) + voidcmd("RMD " + dirname) + end + + # + # Returns the current remote directory. + # + def pwd + resp = sendcmd("PWD") + return parse257(resp) + end + alias getdir pwd + + # + # Returns system information. + # + def system + resp = sendcmd("SYST") + if resp[0, 3] != "215" + raise FTPReplyError, resp + end + return resp[4 .. -1] + end + + # + # Aborts the previous command (ABOR command). + # + def abort + line = "ABOR" + CRLF + print "put: ABOR\n" if @debug_mode + @sock.send(line, Socket::MSG_OOB) + resp = getmultiline + unless ["426", "226", "225"].include?(resp[0, 3]) + raise FTPProtoError, resp + end + return resp + end + + # + # Returns the status (STAT command). + # + def status + line = "STAT" + CRLF + print "put: STAT\n" if @debug_mode + @sock.send(line, Socket::MSG_OOB) + return getresp + end + + # + # Issues the MDTM command. TODO: more info. + # + def mdtm(filename) + resp = sendcmd("MDTM " + filename) + if resp[0, 3] == "213" + return resp[3 .. -1].strip + end + end + + # + # Issues the HELP command. + # + def help(arg = nil) + cmd = "HELP" + if arg + cmd = cmd + " " + arg + end + sendcmd(cmd) + end + + # + # Exits the FTP session. + # + def quit + voidcmd("QUIT") + end + + # + # Issues a NOOP command. + # + def noop + voidcmd("NOOP") + end + + # + # Issues a SITE command. + # + def site(arg) + cmd = "SITE " + arg + voidcmd(cmd) + end + + # + # Closes the connection. Further operations are impossible until you open + # a new connection with #connect. + # + def close + @sock.close if @sock and not @sock.closed? + end + + # + # Returns +true+ iff the connection is closed. + # + def closed? + @sock == nil or @sock.closed? + end + + def parse227(resp) + if resp[0, 3] != "227" + raise FTPReplyError, resp + end + left = resp.index("(") + right = resp.index(")") + if left == nil or right == nil + raise FTPProtoError, resp + end + numbers = resp[left + 1 .. right - 1].split(",") + if numbers.length != 6 + raise FTPProtoError, resp + end + host = numbers[0, 4].join(".") + port = (numbers[4].to_i << 8) + numbers[5].to_i + return host, port + end + private :parse227 + + def parse228(resp) + if resp[0, 3] != "228" + raise FTPReplyError, resp + end + left = resp.index("(") + right = resp.index(")") + if left == nil or right == nil + raise FTPProtoError, resp + end + numbers = resp[left + 1 .. right - 1].split(",") + if numbers[0] == "4" + if numbers.length != 9 || numbers[1] != "4" || numbers[2 + 4] != "2" + raise FTPProtoError, resp + end + host = numbers[2, 4].join(".") + port = (numbers[7].to_i << 8) + numbers[8].to_i + elsif numbers[0] == "6" + if numbers.length != 21 || numbers[1] != "16" || numbers[2 + 16] != "2" + raise FTPProtoError, resp + end + v6 = ["", "", "", "", "", "", "", ""] + for i in 0 .. 7 + v6[i] = sprintf("%02x%02x", numbers[(i * 2) + 2].to_i, + numbers[(i * 2) + 3].to_i) + end + host = v6[0, 8].join(":") + port = (numbers[19].to_i << 8) + numbers[20].to_i + end + return host, port + end + private :parse228 + + def parse229(resp) + if resp[0, 3] != "229" + raise FTPReplyError, resp + end + left = resp.index("(") + right = resp.index(")") + if left == nil or right == nil + raise FTPProtoError, resp + end + numbers = resp[left + 1 .. right - 1].split(resp[left + 1, 1]) + if numbers.length != 4 + raise FTPProtoError, resp + end + port = numbers[3].to_i + host = (@sock.peeraddr())[3] + return host, port + end + private :parse229 + + def parse257(resp) + if resp[0, 3] != "257" + raise FTPReplyError, resp + end + if resp[3, 2] != ' "' + return "" + end + dirname = "" + i = 5 + n = resp.length + while i < n + c = resp[i, 1] + i = i + 1 + if c == '"' + if i > n or resp[i, 1] != '"' + break + end + i = i + 1 + end + dirname = dirname + c + end + return dirname + end + private :parse257 + end + +end + + +# Documentation comments: +# - sourced from pickaxe and nutshell, with improvements (hopefully) +# - three methods should be private (search WRITEME) +# - two methods need more information (search TODO) diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/ftptls.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/ftptls.rb new file mode 100644 index 00000000..4c245420 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/ftptls.rb @@ -0,0 +1,53 @@ +=begin += $RCSfile$ -- SSL/TLS enhancement for Net::HTTP. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2003 Blaz Grilc + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Requirements + += Version + $Id: ftptls.rb 16878 2008-06-07 16:16:46Z shyouhei $ + += Notes + Tested on FreeBSD 5-CURRENT and 4-STABLE + - ruby 1.6.8 (2003-01-17) [i386-freebsd5] + - OpenSSL 0.9.7a Feb 19 2003 + - ruby-openssl-0.2.0.p0 + tested on ftp server: glftpd 1.30 +=end + +require 'socket' +require 'openssl' +require 'net/ftp' + +module Net + class FTPTLS < FTP + def connect(host, port=FTP_PORT) + @hostname = host + super + end + + def login(user = "anonymous", passwd = nil, acct = nil) + store = OpenSSL::X509::Store.new + store.set_default_paths + ctx = OpenSSL::SSL::SSLContext.new('SSLv23') + ctx.cert_store = store + ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER + ctx.key = nil + ctx.cert = nil + voidcmd("AUTH TLS") + @sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx) + @sock.connect + @sock.post_connection_check(@hostname) + super(user, passwd, acct) + voidcmd("PBSZ 0") + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/http.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/http.rb new file mode 100644 index 00000000..7831618d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/http.rb @@ -0,0 +1,2277 @@ +# +# = net/http.rb +# +# Copyright (c) 1999-2006 Yukihiro Matsumoto +# Copyright (c) 1999-2006 Minero Aoki +# Copyright (c) 2001 GOTOU Yuuzou +# +# Written and maintained by Minero Aoki . +# HTTPS support added by GOTOU Yuuzou . +# +# This file is derived from "http-access.rb". +# +# Documented by Minero Aoki; converted to RDoc by William Webber. +# +# This program is free software. You can re-distribute and/or +# modify this program under the same terms of ruby itself --- +# Ruby Distribution License or GNU General Public License. +# +# See Net::HTTP for an overview and examples. +# +# NOTE: You can find Japanese version of this document here: +# http://www.ruby-lang.org/ja/man/?cmd=view;name=net%2Fhttp.rb +# +#-- +# $Id: http.rb 16878 2008-06-07 16:16:46Z shyouhei $ +#++ + +require 'net/protocol' +require 'uri' + +module Net #:nodoc: + + # :stopdoc: + class HTTPBadResponse < StandardError; end + class HTTPHeaderSyntaxError < StandardError; end + # :startdoc: + + # == What Is This Library? + # + # This library provides your program functions to access WWW + # documents via HTTP, Hyper Text Transfer Protocol version 1.1. + # For details of HTTP, refer [RFC2616] + # (http://www.ietf.org/rfc/rfc2616.txt). + # + # == Examples + # + # === Getting Document From WWW Server + # + # Example #1: Simple GET+print + # + # require 'net/http' + # Net::HTTP.get_print 'www.example.com', '/index.html' + # + # Example #2: Simple GET+print by URL + # + # require 'net/http' + # require 'uri' + # Net::HTTP.get_print URI.parse('http://www.example.com/index.html') + # + # Example #3: More generic GET+print + # + # require 'net/http' + # require 'uri' + # + # url = URI.parse('http://www.example.com/index.html') + # res = Net::HTTP.start(url.host, url.port) {|http| + # http.get('/index.html') + # } + # puts res.body + # + # Example #4: More generic GET+print + # + # require 'net/http' + # + # url = URI.parse('http://www.example.com/index.html') + # req = Net::HTTP::Get.new(url.path) + # res = Net::HTTP.start(url.host, url.port) {|http| + # http.request(req) + # } + # puts res.body + # + # === Posting Form Data + # + # require 'net/http' + # require 'uri' + # + # #1: Simple POST + # res = Net::HTTP.post_form(URI.parse('http://www.example.com/search.cgi'), + # {'q'=>'ruby', 'max'=>'50'}) + # puts res.body + # + # #2: POST with basic authentication + # res = Net::HTTP.post_form(URI.parse('http://jack:pass@www.example.com/todo.cgi'), + # {'from'=>'2005-01-01', 'to'=>'2005-03-31'}) + # puts res.body + # + # #3: Detailed control + # url = URI.parse('http://www.example.com/todo.cgi') + # req = Net::HTTP::Post.new(url.path) + # req.basic_auth 'jack', 'pass' + # req.set_form_data({'from'=>'2005-01-01', 'to'=>'2005-03-31'}, ';') + # res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) } + # case res + # when Net::HTTPSuccess, Net::HTTPRedirection + # # OK + # else + # res.error! + # end + # + # === Accessing via Proxy + # + # Net::HTTP.Proxy creates http proxy class. It has same + # methods of Net::HTTP but its instances always connect to + # proxy, instead of given host. + # + # require 'net/http' + # + # proxy_addr = 'your.proxy.host' + # proxy_port = 8080 + # : + # Net::HTTP::Proxy(proxy_addr, proxy_port).start('www.example.com') {|http| + # # always connect to your.proxy.addr:8080 + # : + # } + # + # Since Net::HTTP.Proxy returns Net::HTTP itself when proxy_addr is nil, + # there's no need to change code if there's proxy or not. + # + # There are two additional parameters in Net::HTTP.Proxy which allow to + # specify proxy user name and password: + # + # Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user = nil, proxy_pass = nil) + # + # You may use them to work with authorization-enabled proxies: + # + # require 'net/http' + # require 'uri' + # + # proxy_host = 'your.proxy.host' + # proxy_port = 8080 + # uri = URI.parse(ENV['http_proxy']) + # proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo + # Net::HTTP::Proxy(proxy_host, proxy_port, + # proxy_user, proxy_pass).start('www.example.com') {|http| + # # always connect to your.proxy.addr:8080 using specified username and password + # : + # } + # + # Note that net/http never rely on HTTP_PROXY environment variable. + # If you want to use proxy, set it explicitly. + # + # === Following Redirection + # + # require 'net/http' + # require 'uri' + # + # def fetch(uri_str, limit = 10) + # # You should choose better exception. + # raise ArgumentError, 'HTTP redirect too deep' if limit == 0 + # + # response = Net::HTTP.get_response(URI.parse(uri_str)) + # case response + # when Net::HTTPSuccess then response + # when Net::HTTPRedirection then fetch(response['location'], limit - 1) + # else + # response.error! + # end + # end + # + # print fetch('http://www.ruby-lang.org') + # + # Net::HTTPSuccess and Net::HTTPRedirection is a HTTPResponse class. + # All HTTPResponse objects belong to its own response class which + # indicate HTTP result status. For details of response classes, + # see section "HTTP Response Classes". + # + # === Basic Authentication + # + # require 'net/http' + # + # Net::HTTP.start('www.example.com') {|http| + # req = Net::HTTP::Get.new('/secret-page.html') + # req.basic_auth 'account', 'password' + # response = http.request(req) + # print response.body + # } + # + # === HTTP Request Classes + # + # Here is HTTP request class hierarchy. + # + # Net::HTTPRequest + # Net::HTTP::Get + # Net::HTTP::Head + # Net::HTTP::Post + # Net::HTTP::Put + # Net::HTTP::Proppatch + # Net::HTTP::Lock + # Net::HTTP::Unlock + # Net::HTTP::Options + # Net::HTTP::Propfind + # Net::HTTP::Delete + # Net::HTTP::Move + # Net::HTTP::Copy + # Net::HTTP::Mkcol + # Net::HTTP::Trace + # + # === HTTP Response Classes + # + # Here is HTTP response class hierarchy. + # All classes are defined in Net module. + # + # HTTPResponse + # HTTPUnknownResponse + # HTTPInformation # 1xx + # HTTPContinue # 100 + # HTTPSwitchProtocl # 101 + # HTTPSuccess # 2xx + # HTTPOK # 200 + # HTTPCreated # 201 + # HTTPAccepted # 202 + # HTTPNonAuthoritativeInformation # 203 + # HTTPNoContent # 204 + # HTTPResetContent # 205 + # HTTPPartialContent # 206 + # HTTPRedirection # 3xx + # HTTPMultipleChoice # 300 + # HTTPMovedPermanently # 301 + # HTTPFound # 302 + # HTTPSeeOther # 303 + # HTTPNotModified # 304 + # HTTPUseProxy # 305 + # HTTPTemporaryRedirect # 307 + # HTTPClientError # 4xx + # HTTPBadRequest # 400 + # HTTPUnauthorized # 401 + # HTTPPaymentRequired # 402 + # HTTPForbidden # 403 + # HTTPNotFound # 404 + # HTTPMethodNotAllowed # 405 + # HTTPNotAcceptable # 406 + # HTTPProxyAuthenticationRequired # 407 + # HTTPRequestTimeOut # 408 + # HTTPConflict # 409 + # HTTPGone # 410 + # HTTPLengthRequired # 411 + # HTTPPreconditionFailed # 412 + # HTTPRequestEntityTooLarge # 413 + # HTTPRequestURITooLong # 414 + # HTTPUnsupportedMediaType # 415 + # HTTPRequestedRangeNotSatisfiable # 416 + # HTTPExpectationFailed # 417 + # HTTPServerError # 5xx + # HTTPInternalServerError # 500 + # HTTPNotImplemented # 501 + # HTTPBadGateway # 502 + # HTTPServiceUnavailable # 503 + # HTTPGatewayTimeOut # 504 + # HTTPVersionNotSupported # 505 + # + # == Switching Net::HTTP versions + # + # You can use net/http.rb 1.1 features (bundled with Ruby 1.6) + # by calling HTTP.version_1_1. Calling Net::HTTP.version_1_2 + # allows you to use 1.2 features again. + # + # # example + # Net::HTTP.start {|http1| ...(http1 has 1.2 features)... } + # + # Net::HTTP.version_1_1 + # Net::HTTP.start {|http2| ...(http2 has 1.1 features)... } + # + # Net::HTTP.version_1_2 + # Net::HTTP.start {|http3| ...(http3 has 1.2 features)... } + # + # This function is NOT thread-safe. + # + class HTTP < Protocol + + # :stopdoc: + Revision = %q$Revision: 16878 $.split[1] + HTTPVersion = '1.1' + @newimpl = true + # :startdoc: + + # Turns on net/http 1.2 (ruby 1.8) features. + # Defaults to ON in ruby 1.8. + # + # I strongly recommend to call this method always. + # + # require 'net/http' + # Net::HTTP.version_1_2 + # + def HTTP.version_1_2 + @newimpl = true + end + + # Turns on net/http 1.1 (ruby 1.6) features. + # Defaults to OFF in ruby 1.8. + def HTTP.version_1_1 + @newimpl = false + end + + # true if net/http is in version 1.2 mode. + # Defaults to true. + def HTTP.version_1_2? + @newimpl + end + + # true if net/http is in version 1.1 compatible mode. + # Defaults to true. + def HTTP.version_1_1? + not @newimpl + end + + class << HTTP + alias is_version_1_1? version_1_1? #:nodoc: + alias is_version_1_2? version_1_2? #:nodoc: + end + + # + # short cut methods + # + + # + # Get body from target and output it to +$stdout+. The + # target can either be specified as (+uri+), or as + # (+host+, +path+, +port+ = 80); so: + # + # Net::HTTP.get_print URI.parse('http://www.example.com/index.html') + # + # or: + # + # Net::HTTP.get_print 'www.example.com', '/index.html' + # + def HTTP.get_print(uri_or_host, path = nil, port = nil) + get_response(uri_or_host, path, port) {|res| + res.read_body do |chunk| + $stdout.print chunk + end + } + nil + end + + # Send a GET request to the target and return the response + # as a string. The target can either be specified as + # (+uri+), or as (+host+, +path+, +port+ = 80); so: + # + # print Net::HTTP.get(URI.parse('http://www.example.com/index.html')) + # + # or: + # + # print Net::HTTP.get('www.example.com', '/index.html') + # + def HTTP.get(uri_or_host, path = nil, port = nil) + get_response(uri_or_host, path, port).body + end + + # Send a GET request to the target and return the response + # as a Net::HTTPResponse object. The target can either be specified as + # (+uri+), or as (+host+, +path+, +port+ = 80); so: + # + # res = Net::HTTP.get_response(URI.parse('http://www.example.com/index.html')) + # print res.body + # + # or: + # + # res = Net::HTTP.get_response('www.example.com', '/index.html') + # print res.body + # + def HTTP.get_response(uri_or_host, path = nil, port = nil, &block) + if path + host = uri_or_host + new(host, port || HTTP.default_port).start {|http| + return http.request_get(path, &block) + } + else + uri = uri_or_host + new(uri.host, uri.port).start {|http| + return http.request_get(uri.request_uri, &block) + } + end + end + + # Posts HTML form data to the +URL+. + # Form data must be represented as a Hash of String to String, e.g: + # + # { "cmd" => "search", "q" => "ruby", "max" => "50" } + # + # This method also does Basic Authentication iff +URL+.user exists. + # + # Example: + # + # require 'net/http' + # require 'uri' + # + # HTTP.post_form URI.parse('http://www.example.com/search.cgi'), + # { "q" => "ruby", "max" => "50" } + # + def HTTP.post_form(url, params) + req = Post.new(url.path) + req.form_data = params + req.basic_auth url.user, url.password if url.user + new(url.host, url.port).start {|http| + http.request(req) + } + end + + # + # HTTP session management + # + + # The default port to use for HTTP requests; defaults to 80. + def HTTP.default_port + http_default_port() + end + + # The default port to use for HTTP requests; defaults to 80. + def HTTP.http_default_port + 80 + end + + # The default port to use for HTTPS requests; defaults to 443. + def HTTP.https_default_port + 443 + end + + def HTTP.socket_type #:nodoc: obsolete + BufferedIO + end + + # creates a new Net::HTTP object and opens its TCP connection and + # HTTP session. If the optional block is given, the newly + # created Net::HTTP object is passed to it and closed when the + # block finishes. In this case, the return value of this method + # is the return value of the block. If no block is given, the + # return value of this method is the newly created Net::HTTP object + # itself, and the caller is responsible for closing it upon completion. + def HTTP.start(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil, &block) # :yield: +http+ + new(address, port, p_addr, p_port, p_user, p_pass).start(&block) + end + + class << HTTP + alias newobj new + end + + # Creates a new Net::HTTP object. + # If +proxy_addr+ is given, creates an Net::HTTP object with proxy support. + # This method does not open the TCP connection. + def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil) + h = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port) + h.instance_eval { + @newimpl = ::Net::HTTP.version_1_2? + } + h + end + + # Creates a new Net::HTTP object for the specified +address+. + # This method does not open the TCP connection. + def initialize(address, port = nil) + @address = address + @port = (port || HTTP.default_port) + @curr_http_version = HTTPVersion + @seems_1_0_server = false + @close_on_empty_response = false + @socket = nil + @started = false + @open_timeout = nil + @read_timeout = 60 + @debug_output = nil + @use_ssl = false + @ssl_context = nil + end + + def inspect + "#<#{self.class} #{@address}:#{@port} open=#{started?}>" + end + + # *WARNING* This method causes serious security hole. + # Never use this method in production code. + # + # Set an output stream for debugging. + # + # http = Net::HTTP.new + # http.set_debug_output $stderr + # http.start { .... } + # + def set_debug_output(output) + warn 'Net::HTTP#set_debug_output called after HTTP started' if started? + @debug_output = output + end + + # The host name to connect to. + attr_reader :address + + # The port number to connect to. + attr_reader :port + + # Seconds to wait until connection is opened. + # If the HTTP object cannot open a connection in this many seconds, + # it raises a TimeoutError exception. + attr_accessor :open_timeout + + # Seconds to wait until reading one block (by one read(2) call). + # If the HTTP object cannot open a connection in this many seconds, + # it raises a TimeoutError exception. + attr_reader :read_timeout + + # Setter for the read_timeout attribute. + def read_timeout=(sec) + @socket.read_timeout = sec if @socket + @read_timeout = sec + end + + # returns true if the HTTP session is started. + def started? + @started + end + + alias active? started? #:nodoc: obsolete + + attr_accessor :close_on_empty_response + + # returns true if use SSL/TLS with HTTP. + def use_ssl? + false # redefined in net/https + end + + # Opens TCP connection and HTTP session. + # + # When this method is called with block, gives a HTTP object + # to the block and closes the TCP connection / HTTP session + # after the block executed. + # + # When called with a block, returns the return value of the + # block; otherwise, returns self. + # + def start # :yield: http + raise IOError, 'HTTP session already opened' if @started + if block_given? + begin + do_start + return yield(self) + ensure + do_finish + end + end + do_start + self + end + + def do_start + connect + @started = true + end + private :do_start + + def connect + D "opening connection to #{conn_address()}..." + s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) } + D "opened" + if use_ssl? + unless @ssl_context.verify_mode + warn "warning: peer certificate won't be verified in this SSL session" + @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context) + s.sync_close = true + end + @socket = BufferedIO.new(s) + @socket.read_timeout = @read_timeout + @socket.debug_output = @debug_output + if use_ssl? + if proxy? + @socket.writeline sprintf('CONNECT %s:%s HTTP/%s', + @address, @port, HTTPVersion) + @socket.writeline "Host: #{@address}:#{@port}" + if proxy_user + credential = ["#{proxy_user}:#{proxy_pass}"].pack('m') + credential.delete!("\r\n") + @socket.writeline "Proxy-Authorization: Basic #{credential}" + end + @socket.writeline '' + HTTPResponse.read_new(@socket).value + end + s.connect + if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE + s.post_connection_check(@address) + end + end + on_connect + end + private :connect + + def on_connect + end + private :on_connect + + # Finishes HTTP session and closes TCP connection. + # Raises IOError if not started. + def finish + raise IOError, 'HTTP session not yet started' unless started? + do_finish + end + + def do_finish + @started = false + @socket.close if @socket and not @socket.closed? + @socket = nil + end + private :do_finish + + # + # proxy + # + + public + + # no proxy + @is_proxy_class = false + @proxy_addr = nil + @proxy_port = nil + @proxy_user = nil + @proxy_pass = nil + + # Creates an HTTP proxy class. + # Arguments are address/port of proxy host and username/password + # if authorization on proxy server is required. + # You can replace the HTTP class with created proxy class. + # + # If ADDRESS is nil, this method returns self (Net::HTTP). + # + # # Example + # proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080) + # : + # proxy_class.start('www.ruby-lang.org') {|http| + # # connecting proxy.foo.org:8080 + # : + # } + # + def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil) + return self unless p_addr + delta = ProxyDelta + proxyclass = Class.new(self) + proxyclass.module_eval { + include delta + # with proxy + @is_proxy_class = true + @proxy_address = p_addr + @proxy_port = p_port || default_port() + @proxy_user = p_user + @proxy_pass = p_pass + } + proxyclass + end + + class << HTTP + # returns true if self is a class which was created by HTTP::Proxy. + def proxy_class? + @is_proxy_class + end + + attr_reader :proxy_address + attr_reader :proxy_port + attr_reader :proxy_user + attr_reader :proxy_pass + end + + # True if self is a HTTP proxy class. + def proxy? + self.class.proxy_class? + end + + # Address of proxy host. If self does not use a proxy, nil. + def proxy_address + self.class.proxy_address + end + + # Port number of proxy host. If self does not use a proxy, nil. + def proxy_port + self.class.proxy_port + end + + # User name for accessing proxy. If self does not use a proxy, nil. + def proxy_user + self.class.proxy_user + end + + # User password for accessing proxy. If self does not use a proxy, nil. + def proxy_pass + self.class.proxy_pass + end + + alias proxyaddr proxy_address #:nodoc: obsolete + alias proxyport proxy_port #:nodoc: obsolete + + private + + # without proxy + + def conn_address + address() + end + + def conn_port + port() + end + + def edit_path(path) + path + end + + module ProxyDelta #:nodoc: internal use only + private + + def conn_address + proxy_address() + end + + def conn_port + proxy_port() + end + + def edit_path(path) + use_ssl? ? path : "http://#{addr_port()}#{path}" + end + end + + # + # HTTP operations + # + + public + + # Gets data from +path+ on the connected-to host. + # +header+ must be a Hash like { 'Accept' => '*/*', ... }. + # + # In version 1.1 (ruby 1.6), this method returns a pair of objects, + # a Net::HTTPResponse object and the entity body string. + # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse + # object. + # + # If called with a block, yields each fragment of the + # entity body in turn as a string as it is read from + # the socket. Note that in this case, the returned response + # object will *not* contain a (meaningful) body. + # + # +dest+ argument is obsolete. + # It still works but you must not use it. + # + # In version 1.1, this method might raise an exception for + # 3xx (redirect). In this case you can get a HTTPResponse object + # by "anException.response". + # + # In version 1.2, this method never raises exception. + # + # # version 1.1 (bundled with Ruby 1.6) + # response, body = http.get('/index.html') + # + # # version 1.2 (bundled with Ruby 1.8 or later) + # response = http.get('/index.html') + # + # # using block + # File.open('result.txt', 'w') {|f| + # http.get('/~foo/') do |str| + # f.write str + # end + # } + # + def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+ + res = nil + request(Get.new(path, initheader)) {|r| + r.read_body dest, &block + res = r + } + unless @newimpl + res.value + return res, res.body + end + + res + end + + # Gets only the header from +path+ on the connected-to host. + # +header+ is a Hash like { 'Accept' => '*/*', ... }. + # + # This method returns a Net::HTTPResponse object. + # + # In version 1.1, this method might raise an exception for + # 3xx (redirect). On the case you can get a HTTPResponse object + # by "anException.response". + # In version 1.2, this method never raises an exception. + # + # response = nil + # Net::HTTP.start('some.www.server', 80) {|http| + # response = http.head('/index.html') + # } + # p response['content-type'] + # + def head(path, initheader = nil) + res = request(Head.new(path, initheader)) + res.value unless @newimpl + res + end + + # Posts +data+ (must be a String) to +path+. +header+ must be a Hash + # like { 'Accept' => '*/*', ... }. + # + # In version 1.1 (ruby 1.6), this method returns a pair of objects, a + # Net::HTTPResponse object and an entity body string. + # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse object. + # + # If called with a block, yields each fragment of the + # entity body in turn as a string as it are read from + # the socket. Note that in this case, the returned response + # object will *not* contain a (meaningful) body. + # + # +dest+ argument is obsolete. + # It still works but you must not use it. + # + # In version 1.1, this method might raise an exception for + # 3xx (redirect). In this case you can get an HTTPResponse object + # by "anException.response". + # In version 1.2, this method never raises exception. + # + # # version 1.1 + # response, body = http.post('/cgi-bin/search.rb', 'query=foo') + # + # # version 1.2 + # response = http.post('/cgi-bin/search.rb', 'query=foo') + # + # # using block + # File.open('result.txt', 'w') {|f| + # http.post('/cgi-bin/search.rb', 'query=foo') do |str| + # f.write str + # end + # } + # + # You should set Content-Type: header field for POST. + # If no Content-Type: field given, this method uses + # "application/x-www-form-urlencoded" by default. + # + def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+ + res = nil + request(Post.new(path, initheader), data) {|r| + r.read_body dest, &block + res = r + } + unless @newimpl + res.value + return res, res.body + end + res + end + + def put(path, data, initheader = nil) #:nodoc: + res = request(Put.new(path, initheader), data) + res.value unless @newimpl + res + end + + # Sends a PROPPATCH request to the +path+ and gets a response, + # as an HTTPResponse object. + def proppatch(path, body, initheader = nil) + request(Proppatch.new(path, initheader), body) + end + + # Sends a LOCK request to the +path+ and gets a response, + # as an HTTPResponse object. + def lock(path, body, initheader = nil) + request(Lock.new(path, initheader), body) + end + + # Sends a UNLOCK request to the +path+ and gets a response, + # as an HTTPResponse object. + def unlock(path, body, initheader = nil) + request(Unlock.new(path, initheader), body) + end + + # Sends a OPTIONS request to the +path+ and gets a response, + # as an HTTPResponse object. + def options(path, initheader = nil) + request(Options.new(path, initheader)) + end + + # Sends a PROPFIND request to the +path+ and gets a response, + # as an HTTPResponse object. + def propfind(path, body = nil, initheader = {'Depth' => '0'}) + request(Propfind.new(path, initheader), body) + end + + # Sends a DELETE request to the +path+ and gets a response, + # as an HTTPResponse object. + def delete(path, initheader = {'Depth' => 'Infinity'}) + request(Delete.new(path, initheader)) + end + + # Sends a MOVE request to the +path+ and gets a response, + # as an HTTPResponse object. + def move(path, initheader = nil) + request(Move.new(path, initheader)) + end + + # Sends a COPY request to the +path+ and gets a response, + # as an HTTPResponse object. + def copy(path, initheader = nil) + request(Copy.new(path, initheader)) + end + + # Sends a MKCOL request to the +path+ and gets a response, + # as an HTTPResponse object. + def mkcol(path, body = nil, initheader = nil) + request(Mkcol.new(path, initheader), body) + end + + # Sends a TRACE request to the +path+ and gets a response, + # as an HTTPResponse object. + def trace(path, initheader = nil) + request(Trace.new(path, initheader)) + end + + # Sends a GET request to the +path+ and gets a response, + # as an HTTPResponse object. + # + # When called with a block, yields an HTTPResponse object. + # The body of this response will not have been read yet; + # the caller can process it using HTTPResponse#read_body, + # if desired. + # + # Returns the response. + # + # This method never raises Net::* exceptions. + # + # response = http.request_get('/index.html') + # # The entity body is already read here. + # p response['content-type'] + # puts response.body + # + # # using block + # http.request_get('/index.html') {|response| + # p response['content-type'] + # response.read_body do |str| # read body now + # print str + # end + # } + # + def request_get(path, initheader = nil, &block) # :yield: +response+ + request(Get.new(path, initheader), &block) + end + + # Sends a HEAD request to the +path+ and gets a response, + # as an HTTPResponse object. + # + # Returns the response. + # + # This method never raises Net::* exceptions. + # + # response = http.request_head('/index.html') + # p response['content-type'] + # + def request_head(path, initheader = nil, &block) + request(Head.new(path, initheader), &block) + end + + # Sends a POST request to the +path+ and gets a response, + # as an HTTPResponse object. + # + # When called with a block, yields an HTTPResponse object. + # The body of this response will not have been read yet; + # the caller can process it using HTTPResponse#read_body, + # if desired. + # + # Returns the response. + # + # This method never raises Net::* exceptions. + # + # # example + # response = http.request_post('/cgi-bin/nice.rb', 'datadatadata...') + # p response.status + # puts response.body # body is already read + # + # # using block + # http.request_post('/cgi-bin/nice.rb', 'datadatadata...') {|response| + # p response.status + # p response['content-type'] + # response.read_body do |str| # read body now + # print str + # end + # } + # + def request_post(path, data, initheader = nil, &block) # :yield: +response+ + request Post.new(path, initheader), data, &block + end + + def request_put(path, data, initheader = nil, &block) #:nodoc: + request Put.new(path, initheader), data, &block + end + + alias get2 request_get #:nodoc: obsolete + alias head2 request_head #:nodoc: obsolete + alias post2 request_post #:nodoc: obsolete + alias put2 request_put #:nodoc: obsolete + + + # Sends an HTTP request to the HTTP server. + # This method also sends DATA string if DATA is given. + # + # Returns a HTTPResponse object. + # + # This method never raises Net::* exceptions. + # + # response = http.send_request('GET', '/index.html') + # puts response.body + # + def send_request(name, path, data = nil, header = nil) + r = HTTPGenericRequest.new(name,(data ? true : false),true,path,header) + request r, data + end + + # Sends an HTTPRequest object REQUEST to the HTTP server. + # This method also sends DATA string if REQUEST is a post/put request. + # Giving DATA for get/head request causes ArgumentError. + # + # When called with a block, yields an HTTPResponse object. + # The body of this response will not have been read yet; + # the caller can process it using HTTPResponse#read_body, + # if desired. + # + # Returns a HTTPResponse object. + # + # This method never raises Net::* exceptions. + # + def request(req, body = nil, &block) # :yield: +response+ + unless started? + start { + req['connection'] ||= 'close' + return request(req, body, &block) + } + end + if proxy_user() + unless use_ssl? + req.proxy_basic_auth proxy_user(), proxy_pass() + end + end + + req.set_body_internal body + begin_transport req + req.exec @socket, @curr_http_version, edit_path(req.path) + begin + res = HTTPResponse.read_new(@socket) + end while res.kind_of?(HTTPContinue) + res.reading_body(@socket, req.response_body_permitted?) { + yield res if block_given? + } + end_transport req, res + + res + end + + private + + def begin_transport(req) + if @socket.closed? + connect + end + if @seems_1_0_server + req['connection'] ||= 'close' + end + if not req.response_body_permitted? and @close_on_empty_response + req['connection'] ||= 'close' + end + req['host'] ||= addr_port() + end + + def end_transport(req, res) + @curr_http_version = res.http_version + if not res.body and @close_on_empty_response + D 'Conn close' + @socket.close + elsif keep_alive?(req, res) + D 'Conn keep-alive' + if @socket.closed? + D 'Conn (but seems 1.0 server)' + @seems_1_0_server = true + end + else + D 'Conn close' + @socket.close + end + end + + def keep_alive?(req, res) + return false if /close/i =~ req['connection'].to_s + return false if @seems_1_0_server + return true if /keep-alive/i =~ res['connection'].to_s + return false if /close/i =~ res['connection'].to_s + return true if /keep-alive/i =~ res['proxy-connection'].to_s + return false if /close/i =~ res['proxy-connection'].to_s + (@curr_http_version == '1.1') + end + + # + # utils + # + + private + + def addr_port + if use_ssl? + address() + (port == HTTP.https_default_port ? '' : ":#{port()}") + else + address() + (port == HTTP.http_default_port ? '' : ":#{port()}") + end + end + + def D(msg) + return unless @debug_output + @debug_output << msg + @debug_output << "\n" + end + + end + + HTTPSession = HTTP + + + # + # Header module. + # + # Provides access to @header in the mixed-into class as a hash-like + # object, except with case-insensitive keys. Also provides + # methods for accessing commonly-used header values in a more + # convenient format. + # + module HTTPHeader + + def initialize_http_header(initheader) + @header = {} + return unless initheader + initheader.each do |key, value| + warn "net/http: warning: duplicated HTTP header: #{key}" if key?(key) and $VERBOSE + @header[key.downcase] = [value.strip] + end + end + + def size #:nodoc: obsolete + @header.size + end + + alias length size #:nodoc: obsolete + + # Returns the header field corresponding to the case-insensitive key. + # For example, a key of "Content-Type" might return "text/html" + def [](key) + a = @header[key.downcase] or return nil + a.join(', ') + end + + # Sets the header field corresponding to the case-insensitive key. + def []=(key, val) + unless val + @header.delete key.downcase + return val + end + @header[key.downcase] = [val] + end + + # [Ruby 1.8.3] + # Adds header field instead of replace. + # Second argument +val+ must be a String. + # See also #[]=, #[] and #get_fields. + # + # request.add_field 'X-My-Header', 'a' + # p request['X-My-Header'] #=> "a" + # p request.get_fields('X-My-Header') #=> ["a"] + # request.add_field 'X-My-Header', 'b' + # p request['X-My-Header'] #=> "a, b" + # p request.get_fields('X-My-Header') #=> ["a", "b"] + # request.add_field 'X-My-Header', 'c' + # p request['X-My-Header'] #=> "a, b, c" + # p request.get_fields('X-My-Header') #=> ["a", "b", "c"] + # + def add_field(key, val) + if @header.key?(key.downcase) + @header[key.downcase].push val + else + @header[key.downcase] = [val] + end + end + + # [Ruby 1.8.3] + # Returns an array of header field strings corresponding to the + # case-insensitive +key+. This method allows you to get duplicated + # header fields without any processing. See also #[]. + # + # p response.get_fields('Set-Cookie') + # #=> ["session=al98axx; expires=Fri, 31-Dec-1999 23:58:23", + # "query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"] + # p response['Set-Cookie'] + # #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23" + # + def get_fields(key) + return nil unless @header[key.downcase] + @header[key.downcase].dup + end + + # Returns the header field corresponding to the case-insensitive key. + # Returns the default value +args+, or the result of the block, or nil, + # if there's no header field named key. See Hash#fetch + def fetch(key, *args, &block) #:yield: +key+ + a = @header.fetch(key.downcase, *args, &block) + a.join(', ') + end + + # Iterates for each header names and values. + def each_header #:yield: +key+, +value+ + @header.each do |k,va| + yield k, va.join(', ') + end + end + + alias each each_header + + # Iterates for each header names. + def each_name(&block) #:yield: +key+ + @header.each_key(&block) + end + + alias each_key each_name + + # Iterates for each capitalized header names. + def each_capitalized_name(&block) #:yield: +key+ + @header.each_key do |k| + yield capitalize(k) + end + end + + # Iterates for each header values. + def each_value #:yield: +value+ + @header.each_value do |va| + yield va.join(', ') + end + end + + # Removes a header field. + def delete(key) + @header.delete(key.downcase) + end + + # true if +key+ header exists. + def key?(key) + @header.key?(key.downcase) + end + + # Returns a Hash consist of header names and values. + def to_hash + @header.dup + end + + # As for #each_header, except the keys are provided in capitalized form. + def each_capitalized + @header.each do |k,v| + yield capitalize(k), v.join(', ') + end + end + + alias canonical_each each_capitalized + + def capitalize(name) + name.split(/-/).map {|s| s.capitalize }.join('-') + end + private :capitalize + + # Returns an Array of Range objects which represents Range: header field, + # or +nil+ if there is no such header. + def range + return nil unless @header['range'] + self['Range'].split(/,/).map {|spec| + m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or + raise HTTPHeaderSyntaxError, "wrong Range: #{spec}" + d1 = m[1].to_i + d2 = m[2].to_i + if m[1] and m[2] then d1..d2 + elsif m[1] then d1..-1 + elsif m[2] then -d2..-1 + else + raise HTTPHeaderSyntaxError, 'range is not specified' + end + } + end + + # Set Range: header from Range (arg r) or beginning index and + # length from it (arg idx&len). + # + # req.range = (0..1023) + # req.set_range 0, 1023 + # + def set_range(r, e = nil) + unless r + @header.delete 'range' + return r + end + r = (r...r+e) if e + case r + when Numeric + n = r.to_i + rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}") + when Range + first = r.first + last = r.last + last -= 1 if r.exclude_end? + if last == -1 + rangestr = (first > 0 ? "#{first}-" : "-#{-first}") + else + raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0 + raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0 + raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last + rangestr = "#{first}-#{last}" + end + else + raise TypeError, 'Range/Integer is required' + end + @header['range'] = ["bytes=#{rangestr}"] + r + end + + alias range= set_range + + # Returns an Integer object which represents the Content-Length: header field + # or +nil+ if that field is not provided. + def content_length + return nil unless key?('Content-Length') + len = self['Content-Length'].slice(/\d+/) or + raise HTTPHeaderSyntaxError, 'wrong Content-Length format' + len.to_i + end + + def content_length=(len) + unless len + @header.delete 'content-length' + return nil + end + @header['content-length'] = [len.to_i.to_s] + end + + # Returns "true" if the "transfer-encoding" header is present and + # set to "chunked". This is an HTTP/1.1 feature, allowing the + # the content to be sent in "chunks" without at the outset + # stating the entire content length. + def chunked? + return false unless @header['transfer-encoding'] + field = self['Transfer-Encoding'] + (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false + end + + # Returns a Range object which represents Content-Range: header field. + # This indicates, for a partial entity body, where this fragment + # fits inside the full entity body, as range of byte offsets. + def content_range + return nil unless @header['content-range'] + m = %ri.match(self['Content-Range']) or + raise HTTPHeaderSyntaxError, 'wrong Content-Range format' + m[1].to_i .. m[2].to_i + 1 + end + + # The length of the range represented in Content-Range: header. + def range_length + r = content_range() or return nil + r.end - r.begin + end + + # Returns a content type string such as "text/html". + # This method returns nil if Content-Type: header field does not exist. + def content_type + return nil unless main_type() + if sub_type() + then "#{main_type()}/#{sub_type()}" + else main_type() + end + end + + # Returns a content type string such as "text". + # This method returns nil if Content-Type: header field does not exist. + def main_type + return nil unless @header['content-type'] + self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip + end + + # Returns a content type string such as "html". + # This method returns nil if Content-Type: header field does not exist + # or sub-type is not given (e.g. "Content-Type: text"). + def sub_type + return nil unless @header['content-type'] + main, sub = *self['Content-Type'].split(';').first.to_s.split('/') + return nil unless sub + sub.strip + end + + # Returns content type parameters as a Hash as like + # {"charset" => "iso-2022-jp"}. + def type_params + result = {} + list = self['Content-Type'].to_s.split(';') + list.shift + list.each do |param| + k, v = *param.split('=', 2) + result[k.strip] = v.strip + end + result + end + + # Set Content-Type: header field by +type+ and +params+. + # +type+ must be a String, +params+ must be a Hash. + def set_content_type(type, params = {}) + @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')] + end + + alias content_type= set_content_type + + # Set header fields and a body from HTML form data. + # +params+ should be a Hash containing HTML form data. + # Optional argument +sep+ means data record separator. + # + # This method also set Content-Type: header field to + # application/x-www-form-urlencoded. + def set_form_data(params, sep = '&') + self.body = params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join(sep) + self.content_type = 'application/x-www-form-urlencoded' + end + + alias form_data= set_form_data + + def urlencode(str) + str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) } + end + private :urlencode + + # Set the Authorization: header for "Basic" authorization. + def basic_auth(account, password) + @header['authorization'] = [basic_encode(account, password)] + end + + # Set Proxy-Authorization: header for "Basic" authorization. + def proxy_basic_auth(account, password) + @header['proxy-authorization'] = [basic_encode(account, password)] + end + + def basic_encode(account, password) + 'Basic ' + ["#{account}:#{password}"].pack('m').delete("\r\n") + end + private :basic_encode + + end + + + # + # Parent of HTTPRequest class. Do not use this directly; use + # a subclass of HTTPRequest. + # + # Mixes in the HTTPHeader module. + # + class HTTPGenericRequest + + include HTTPHeader + + def initialize(m, reqbody, resbody, path, initheader = nil) + @method = m + @request_has_body = reqbody + @response_has_body = resbody + raise ArgumentError, "HTTP request path is empty" if path.empty? + @path = path + initialize_http_header initheader + self['Accept'] ||= '*/*' + @body = nil + @body_stream = nil + end + + attr_reader :method + attr_reader :path + + def inspect + "\#<#{self.class} #{@method}>" + end + + def request_body_permitted? + @request_has_body + end + + def response_body_permitted? + @response_has_body + end + + def body_exist? + warn "Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?" if $VERBOSE + response_body_permitted? + end + + attr_reader :body + + def body=(str) + @body = str + @body_stream = nil + str + end + + attr_reader :body_stream + + def body_stream=(input) + @body = nil + @body_stream = input + input + end + + def set_body_internal(str) #:nodoc: internal use only + raise ArgumentError, "both of body argument and HTTPRequest#body set" if str and (@body or @body_stream) + self.body = str if str + end + + # + # write + # + + def exec(sock, ver, path) #:nodoc: internal use only + if @body + send_request_with_body sock, ver, path, @body + elsif @body_stream + send_request_with_body_stream sock, ver, path, @body_stream + else + write_header sock, ver, path + end + end + + private + + def send_request_with_body(sock, ver, path, body) + self.content_length = body.length + delete 'Transfer-Encoding' + supply_default_content_type + write_header sock, ver, path + sock.write body + end + + def send_request_with_body_stream(sock, ver, path, f) + unless content_length() or chunked? + raise ArgumentError, + "Content-Length not given and Transfer-Encoding is not `chunked'" + end + supply_default_content_type + write_header sock, ver, path + if chunked? + while s = f.read(1024) + sock.write(sprintf("%x\r\n", s.length) << s << "\r\n") + end + sock.write "0\r\n\r\n" + else + while s = f.read(1024) + sock.write s + end + end + end + + def supply_default_content_type + return if content_type() + warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE + set_content_type 'application/x-www-form-urlencoded' + end + + def write_header(sock, ver, path) + buf = "#{@method} #{path} HTTP/#{ver}\r\n" + each_capitalized do |k,v| + buf << "#{k}: #{v}\r\n" + end + buf << "\r\n" + sock.write buf + end + + end + + + # + # HTTP request class. This class wraps request header and entity path. + # You *must* use its subclass, Net::HTTP::Get, Post, Head. + # + class HTTPRequest < HTTPGenericRequest + + # Creates HTTP request object. + def initialize(path, initheader = nil) + super self.class::METHOD, + self.class::REQUEST_HAS_BODY, + self.class::RESPONSE_HAS_BODY, + path, initheader + end + end + + + class HTTP # reopen + # + # HTTP 1.1 methods --- RFC2616 + # + + class Get < HTTPRequest + METHOD = 'GET' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = true + end + + class Head < HTTPRequest + METHOD = 'HEAD' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = false + end + + class Post < HTTPRequest + METHOD = 'POST' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + + class Put < HTTPRequest + METHOD = 'PUT' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + + class Delete < HTTPRequest + METHOD = 'DELETE' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = true + end + + class Options < HTTPRequest + METHOD = 'OPTIONS' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = false + end + + class Trace < HTTPRequest + METHOD = 'TRACE' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = true + end + + # + # WebDAV methods --- RFC2518 + # + + class Propfind < HTTPRequest + METHOD = 'PROPFIND' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + + class Proppatch < HTTPRequest + METHOD = 'PROPPATCH' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + + class Mkcol < HTTPRequest + METHOD = 'MKCOL' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + + class Copy < HTTPRequest + METHOD = 'COPY' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = true + end + + class Move < HTTPRequest + METHOD = 'MOVE' + REQUEST_HAS_BODY = false + RESPONSE_HAS_BODY = true + end + + class Lock < HTTPRequest + METHOD = 'LOCK' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + + class Unlock < HTTPRequest + METHOD = 'UNLOCK' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + end + + + ### + ### Response + ### + + # HTTP exception class. + # You must use its subclasses. + module HTTPExceptions + def initialize(msg, res) #:nodoc: + super msg + @response = res + end + attr_reader :response + alias data response #:nodoc: obsolete + end + class HTTPError < ProtocolError + include HTTPExceptions + end + class HTTPRetriableError < ProtoRetriableError + include HTTPExceptions + end + class HTTPServerException < ProtoServerError + # We cannot use the name "HTTPServerError", it is the name of the response. + include HTTPExceptions + end + class HTTPFatalError < ProtoFatalError + include HTTPExceptions + end + + + # HTTP response class. This class wraps response header and entity. + # Mixes in the HTTPHeader module, which provides access to response + # header values both via hash-like methods and individual readers. + # Note that each possible HTTP response code defines its own + # HTTPResponse subclass. These are listed below. + # All classes are + # defined under the Net module. Indentation indicates inheritance. + # + # xxx HTTPResponse + # + # 1xx HTTPInformation + # 100 HTTPContinue + # 101 HTTPSwitchProtocol + # + # 2xx HTTPSuccess + # 200 HTTPOK + # 201 HTTPCreated + # 202 HTTPAccepted + # 203 HTTPNonAuthoritativeInformation + # 204 HTTPNoContent + # 205 HTTPResetContent + # 206 HTTPPartialContent + # + # 3xx HTTPRedirection + # 300 HTTPMultipleChoice + # 301 HTTPMovedPermanently + # 302 HTTPFound + # 303 HTTPSeeOther + # 304 HTTPNotModified + # 305 HTTPUseProxy + # 307 HTTPTemporaryRedirect + # + # 4xx HTTPClientError + # 400 HTTPBadRequest + # 401 HTTPUnauthorized + # 402 HTTPPaymentRequired + # 403 HTTPForbidden + # 404 HTTPNotFound + # 405 HTTPMethodNotAllowed + # 406 HTTPNotAcceptable + # 407 HTTPProxyAuthenticationRequired + # 408 HTTPRequestTimeOut + # 409 HTTPConflict + # 410 HTTPGone + # 411 HTTPLengthRequired + # 412 HTTPPreconditionFailed + # 413 HTTPRequestEntityTooLarge + # 414 HTTPRequestURITooLong + # 415 HTTPUnsupportedMediaType + # 416 HTTPRequestedRangeNotSatisfiable + # 417 HTTPExpectationFailed + # + # 5xx HTTPServerError + # 500 HTTPInternalServerError + # 501 HTTPNotImplemented + # 502 HTTPBadGateway + # 503 HTTPServiceUnavailable + # 504 HTTPGatewayTimeOut + # 505 HTTPVersionNotSupported + # + # xxx HTTPUnknownResponse + # + class HTTPResponse + # true if the response has body. + def HTTPResponse.body_permitted? + self::HAS_BODY + end + + def HTTPResponse.exception_type # :nodoc: internal use only + self::EXCEPTION_TYPE + end + end # reopened after + + # :stopdoc: + + class HTTPUnknownResponse < HTTPResponse + HAS_BODY = true + EXCEPTION_TYPE = HTTPError + end + class HTTPInformation < HTTPResponse # 1xx + HAS_BODY = false + EXCEPTION_TYPE = HTTPError + end + class HTTPSuccess < HTTPResponse # 2xx + HAS_BODY = true + EXCEPTION_TYPE = HTTPError + end + class HTTPRedirection < HTTPResponse # 3xx + HAS_BODY = true + EXCEPTION_TYPE = HTTPRetriableError + end + class HTTPClientError < HTTPResponse # 4xx + HAS_BODY = true + EXCEPTION_TYPE = HTTPServerException # for backward compatibility + end + class HTTPServerError < HTTPResponse # 5xx + HAS_BODY = true + EXCEPTION_TYPE = HTTPFatalError # for backward compatibility + end + + class HTTPContinue < HTTPInformation # 100 + HAS_BODY = false + end + class HTTPSwitchProtocol < HTTPInformation # 101 + HAS_BODY = false + end + + class HTTPOK < HTTPSuccess # 200 + HAS_BODY = true + end + class HTTPCreated < HTTPSuccess # 201 + HAS_BODY = true + end + class HTTPAccepted < HTTPSuccess # 202 + HAS_BODY = true + end + class HTTPNonAuthoritativeInformation < HTTPSuccess # 203 + HAS_BODY = true + end + class HTTPNoContent < HTTPSuccess # 204 + HAS_BODY = false + end + class HTTPResetContent < HTTPSuccess # 205 + HAS_BODY = false + end + class HTTPPartialContent < HTTPSuccess # 206 + HAS_BODY = true + end + + class HTTPMultipleChoice < HTTPRedirection # 300 + HAS_BODY = true + end + class HTTPMovedPermanently < HTTPRedirection # 301 + HAS_BODY = true + end + class HTTPFound < HTTPRedirection # 302 + HAS_BODY = true + end + HTTPMovedTemporarily = HTTPFound + class HTTPSeeOther < HTTPRedirection # 303 + HAS_BODY = true + end + class HTTPNotModified < HTTPRedirection # 304 + HAS_BODY = false + end + class HTTPUseProxy < HTTPRedirection # 305 + HAS_BODY = false + end + # 306 unused + class HTTPTemporaryRedirect < HTTPRedirection # 307 + HAS_BODY = true + end + + class HTTPBadRequest < HTTPClientError # 400 + HAS_BODY = true + end + class HTTPUnauthorized < HTTPClientError # 401 + HAS_BODY = true + end + class HTTPPaymentRequired < HTTPClientError # 402 + HAS_BODY = true + end + class HTTPForbidden < HTTPClientError # 403 + HAS_BODY = true + end + class HTTPNotFound < HTTPClientError # 404 + HAS_BODY = true + end + class HTTPMethodNotAllowed < HTTPClientError # 405 + HAS_BODY = true + end + class HTTPNotAcceptable < HTTPClientError # 406 + HAS_BODY = true + end + class HTTPProxyAuthenticationRequired < HTTPClientError # 407 + HAS_BODY = true + end + class HTTPRequestTimeOut < HTTPClientError # 408 + HAS_BODY = true + end + class HTTPConflict < HTTPClientError # 409 + HAS_BODY = true + end + class HTTPGone < HTTPClientError # 410 + HAS_BODY = true + end + class HTTPLengthRequired < HTTPClientError # 411 + HAS_BODY = true + end + class HTTPPreconditionFailed < HTTPClientError # 412 + HAS_BODY = true + end + class HTTPRequestEntityTooLarge < HTTPClientError # 413 + HAS_BODY = true + end + class HTTPRequestURITooLong < HTTPClientError # 414 + HAS_BODY = true + end + HTTPRequestURITooLarge = HTTPRequestURITooLong + class HTTPUnsupportedMediaType < HTTPClientError # 415 + HAS_BODY = true + end + class HTTPRequestedRangeNotSatisfiable < HTTPClientError # 416 + HAS_BODY = true + end + class HTTPExpectationFailed < HTTPClientError # 417 + HAS_BODY = true + end + + class HTTPInternalServerError < HTTPServerError # 500 + HAS_BODY = true + end + class HTTPNotImplemented < HTTPServerError # 501 + HAS_BODY = true + end + class HTTPBadGateway < HTTPServerError # 502 + HAS_BODY = true + end + class HTTPServiceUnavailable < HTTPServerError # 503 + HAS_BODY = true + end + class HTTPGatewayTimeOut < HTTPServerError # 504 + HAS_BODY = true + end + class HTTPVersionNotSupported < HTTPServerError # 505 + HAS_BODY = true + end + + # :startdoc: + + + class HTTPResponse # reopen + + CODE_CLASS_TO_OBJ = { + '1' => HTTPInformation, + '2' => HTTPSuccess, + '3' => HTTPRedirection, + '4' => HTTPClientError, + '5' => HTTPServerError + } + CODE_TO_OBJ = { + '100' => HTTPContinue, + '101' => HTTPSwitchProtocol, + + '200' => HTTPOK, + '201' => HTTPCreated, + '202' => HTTPAccepted, + '203' => HTTPNonAuthoritativeInformation, + '204' => HTTPNoContent, + '205' => HTTPResetContent, + '206' => HTTPPartialContent, + + '300' => HTTPMultipleChoice, + '301' => HTTPMovedPermanently, + '302' => HTTPFound, + '303' => HTTPSeeOther, + '304' => HTTPNotModified, + '305' => HTTPUseProxy, + '307' => HTTPTemporaryRedirect, + + '400' => HTTPBadRequest, + '401' => HTTPUnauthorized, + '402' => HTTPPaymentRequired, + '403' => HTTPForbidden, + '404' => HTTPNotFound, + '405' => HTTPMethodNotAllowed, + '406' => HTTPNotAcceptable, + '407' => HTTPProxyAuthenticationRequired, + '408' => HTTPRequestTimeOut, + '409' => HTTPConflict, + '410' => HTTPGone, + '411' => HTTPLengthRequired, + '412' => HTTPPreconditionFailed, + '413' => HTTPRequestEntityTooLarge, + '414' => HTTPRequestURITooLong, + '415' => HTTPUnsupportedMediaType, + '416' => HTTPRequestedRangeNotSatisfiable, + '417' => HTTPExpectationFailed, + + '500' => HTTPInternalServerError, + '501' => HTTPNotImplemented, + '502' => HTTPBadGateway, + '503' => HTTPServiceUnavailable, + '504' => HTTPGatewayTimeOut, + '505' => HTTPVersionNotSupported + } + + class << HTTPResponse + def read_new(sock) #:nodoc: internal use only + httpv, code, msg = read_status_line(sock) + res = response_class(code).new(httpv, code, msg) + each_response_header(sock) do |k,v| + res.add_field k, v + end + res + end + + private + + def read_status_line(sock) + str = sock.readline + m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or + raise HTTPBadResponse, "wrong status line: #{str.dump}" + m.captures + end + + def response_class(code) + CODE_TO_OBJ[code] or + CODE_CLASS_TO_OBJ[code[0,1]] or + HTTPUnknownResponse + end + + def each_response_header(sock) + while true + line = sock.readuntil("\n", true).sub(/\s+\z/, '') + break if line.empty? + m = /\A([^:]+):\s*/.match(line) or + raise HTTPBadResponse, 'wrong header line format' + yield m[1], m.post_match + end + end + end + + # next is to fix bug in RDoc, where the private inside class << self + # spills out. + public + + include HTTPHeader + + def initialize(httpv, code, msg) #:nodoc: internal use only + @http_version = httpv + @code = code + @message = msg + initialize_http_header nil + @body = nil + @read = false + end + + # The HTTP version supported by the server. + attr_reader :http_version + + # HTTP result code string. For example, '302'. You can also + # determine the response type by which response subclass the + # response object is an instance of. + attr_reader :code + + # HTTP result message. For example, 'Not Found'. + attr_reader :message + alias msg message # :nodoc: obsolete + + def inspect + "#<#{self.class} #{@code} #{@message} readbody=#{@read}>" + end + + # For backward compatibility. + # To allow Net::HTTP 1.1 style assignment + # e.g. + # response, body = Net::HTTP.get(....) + # + def to_ary + warn "net/http.rb: warning: Net::HTTP v1.1 style assignment found at #{caller(1)[0]}; use `response = http.get(...)' instead." if $VERBOSE + res = self.dup + class << res + undef to_ary + end + [res, res.body] + end + + # + # response <-> exception relationship + # + + def code_type #:nodoc: + self.class + end + + def error! #:nodoc: + raise error_type().new(@code + ' ' + @message.dump, self) + end + + def error_type #:nodoc: + self.class::EXCEPTION_TYPE + end + + # Raises HTTP error if the response is not 2xx. + def value + error! unless self.kind_of?(HTTPSuccess) + end + + # + # header (for backward compatibility only; DO NOT USE) + # + + def response #:nodoc: + warn "#{caller(1)[0]}: warning: HTTPResponse#response is obsolete" if $VERBOSE + self + end + + def header #:nodoc: + warn "#{caller(1)[0]}: warning: HTTPResponse#header is obsolete" if $VERBOSE + self + end + + def read_header #:nodoc: + warn "#{caller(1)[0]}: warning: HTTPResponse#read_header is obsolete" if $VERBOSE + self + end + + # + # body + # + + def reading_body(sock, reqmethodallowbody) #:nodoc: internal use only + @socket = sock + @body_exist = reqmethodallowbody && self.class.body_permitted? + begin + yield + self.body # ensure to read body + ensure + @socket = nil + end + end + + # Gets entity body. If the block given, yields it to +block+. + # The body is provided in fragments, as it is read in from the socket. + # + # Calling this method a second or subsequent time will return the + # already read string. + # + # http.request_get('/index.html') {|res| + # puts res.read_body + # } + # + # http.request_get('/index.html') {|res| + # p res.read_body.object_id # 538149362 + # p res.read_body.object_id # 538149362 + # } + # + # # using iterator + # http.request_get('/index.html') {|res| + # res.read_body do |segment| + # print segment + # end + # } + # + def read_body(dest = nil, &block) + if @read + raise IOError, "#{self.class}\#read_body called twice" if dest or block + return @body + end + to = procdest(dest, block) + stream_check + if @body_exist + read_body_0 to + @body = to + else + @body = nil + end + @read = true + + @body + end + + # Returns the entity body. + # + # Calling this method a second or subsequent time will return the + # already read string. + # + # http.request_get('/index.html') {|res| + # puts res.body + # } + # + # http.request_get('/index.html') {|res| + # p res.body.object_id # 538149362 + # p res.body.object_id # 538149362 + # } + # + def body + read_body() + end + + alias entity body #:nodoc: obsolete + + private + + def read_body_0(dest) + if chunked? + read_chunked dest + return + end + clen = content_length() + if clen + @socket.read clen, dest, true # ignore EOF + return + end + clen = range_length() + if clen + @socket.read clen, dest + return + end + @socket.read_all dest + end + + def read_chunked(dest) + len = nil + total = 0 + while true + line = @socket.readline + hexlen = line.slice(/[0-9a-fA-F]+/) or + raise HTTPBadResponse, "wrong chunk size line: #{line}" + len = hexlen.hex + break if len == 0 + @socket.read len, dest; total += len + @socket.read 2 # \r\n + end + until @socket.readline.empty? + # none + end + end + + def stream_check + raise IOError, 'attempt to read body out of block' if @socket.closed? + end + + def procdest(dest, block) + raise ArgumentError, 'both arg and block given for HTTP method' \ + if dest and block + if block + ReadAdapter.new(block) + else + dest || '' + end + end + + end + + + # :enddoc: + + #-- + # for backward compatibility + class HTTP + ProxyMod = ProxyDelta + end + module NetPrivate + HTTPRequest = ::Net::HTTPRequest + end + + HTTPInformationCode = HTTPInformation + HTTPSuccessCode = HTTPSuccess + HTTPRedirectionCode = HTTPRedirection + HTTPRetriableCode = HTTPRedirection + HTTPClientErrorCode = HTTPClientError + HTTPFatalErrorCode = HTTPClientError + HTTPServerErrorCode = HTTPServerError + HTTPResponceReceiver = HTTPResponse + +end # module Net diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/https.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/https.rb new file mode 100644 index 00000000..a9b182be --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/https.rb @@ -0,0 +1,173 @@ +=begin + += $RCSfile$ -- SSL/TLS enhancement for Net::HTTP. + +== Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU Yuuzou + All rights reserved. + +== Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + +== Requirements + This program requires Net 1.2.0 or higher version. + You can get it from RAA or Ruby's CVS repository. + +== Version + $Id: https.rb 11708 2007-02-12 23:01:19Z shyouhei $ + + 2001-11-06: Contiributed to Ruby/OpenSSL project. + 2004-03-06: Some code is merged in to net/http. + +== Example + +Here is a simple HTTP client: + + require 'net/http' + require 'uri' + + uri = URI.parse(ARGV[0] || 'http://localhost/') + http = Net::HTTP.new(uri.host, uri.port) + http.start { + http.request_get(uri.path) {|res| + print res.body + } + } + +It can be replaced by the following code: + + require 'net/https' + require 'uri' + + uri = URI.parse(ARGV[0] || 'https://localhost/') + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true if uri.scheme == "https" # enable SSL/TLS + http.start { + http.request_get(uri.path) {|res| + print res.body + } + } + +== class Net::HTTP + +=== Instance Methods + +: use_ssl? + returns true if use SSL/TLS with HTTP. + +: use_ssl=((|true_or_false|)) + sets use_ssl. + +: peer_cert + return the X.509 certificates the server presented. + +: key, key=((|key|)) + Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object. + (This method is appeared in Michal Rokos's OpenSSL extention.) + +: cert, cert=((|cert|)) + Sets an OpenSSL::X509::Certificate object as client certificate + (This method is appeared in Michal Rokos's OpenSSL extention). + +: ca_file, ca_file=((|path|)) + Sets path of a CA certification file in PEM format. + The file can contrain several CA certificats. + +: ca_path, ca_path=((|path|)) + Sets path of a CA certification directory containing certifications + in PEM format. + +: verify_mode, verify_mode=((|mode|)) + Sets the flags for server the certification verification at + begining of SSL/TLS session. + OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable. + +: verify_callback, verify_callback=((|proc|)) + Sets the verify callback for the server certification verification. + +: verify_depth, verify_depth=((|num|)) + Sets the maximum depth for the certificate chain verification. + +: cert_store, cert_store=((|store|)) + Sets the X509::Store to verify peer certificate. + +: ssl_timeout, ssl_timeout=((|sec|)) + Sets the SSL timeout seconds. + +=end + +require 'net/http' +require 'openssl' + +module Net + + class HTTP + remove_method :use_ssl? + def use_ssl? + @use_ssl + end + + # For backward compatibility. + alias use_ssl use_ssl? + + # Turn on/off SSL. + # This flag must be set before starting session. + # If you change use_ssl value after session started, + # a Net::HTTP object raises IOError. + def use_ssl=(flag) + flag = (flag ? true : false) + raise IOError, "use_ssl value changed, but session already started" \ + if started? and @use_ssl != flag + if flag and not @ssl_context + @ssl_context = OpenSSL::SSL::SSLContext.new + end + @use_ssl = flag + end + + def self.ssl_context_accessor(name) + module_eval(<<-End, __FILE__, __LINE__ + 1) + def #{name} + return nil unless @ssl_context + @ssl_context.#{name} + end + + def #{name}=(val) + @ssl_context ||= OpenSSL::SSL::SSLContext.new + @ssl_context.#{name} = val + end + End + end + + ssl_context_accessor :key + ssl_context_accessor :cert + ssl_context_accessor :ca_file + ssl_context_accessor :ca_path + ssl_context_accessor :verify_mode + ssl_context_accessor :verify_callback + ssl_context_accessor :verify_depth + ssl_context_accessor :cert_store + + def ssl_timeout + return nil unless @ssl_context + @ssl_context.timeout + end + + def ssl_timeout=(sec) + raise ArgumentError, 'Net::HTTP#ssl_timeout= called but use_ssl=false' \ + unless use_ssl? + @ssl_context ||= OpenSSL::SSL::SSLContext.new + @ssl_context.timeout = sec + end + + # For backward compatibility + alias timeout= ssl_timeout= + + def peer_cert + return nil if not use_ssl? or not @socket + @socket.io.peer_cert + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/imap.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/imap.rb new file mode 100644 index 00000000..f8c0d3be --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/imap.rb @@ -0,0 +1,3371 @@ +# +# = net/imap.rb +# +# Copyright (C) 2000 Shugo Maeda +# +# This library is distributed under the terms of the Ruby license. +# You can freely distribute/modify this library. +# +# Documentation: Shugo Maeda, with RDoc conversion and overview by William +# Webber. +# +# See Net::IMAP for documentation. +# + + +require "socket" +require "monitor" +require "digest/md5" +begin + require "openssl" +rescue LoadError +end + +module Net + + # + # Net::IMAP implements Internet Message Access Protocol (IMAP) client + # functionality. The protocol is described in [IMAP]. + # + # == IMAP Overview + # + # An IMAP client connects to a server, and then authenticates + # itself using either #authenticate() or #login(). Having + # authenticated itself, there is a range of commands + # available to it. Most work with mailboxes, which may be + # arranged in an hierarchical namespace, and each of which + # contains zero or more messages. How this is implemented on + # the server is implementation-dependent; on a UNIX server, it + # will frequently be implemented as a files in mailbox format + # within a hierarchy of directories. + # + # To work on the messages within a mailbox, the client must + # first select that mailbox, using either #select() or (for + # read-only access) #examine(). Once the client has successfully + # selected a mailbox, they enter _selected_ state, and that + # mailbox becomes the _current_ mailbox, on which mail-item + # related commands implicitly operate. + # + # Messages have two sorts of identifiers: message sequence + # numbers, and UIDs. + # + # Message sequence numbers number messages within a mail box + # from 1 up to the number of items in the mail box. If new + # message arrives during a session, it receives a sequence + # number equal to the new size of the mail box. If messages + # are expunged from the mailbox, remaining messages have their + # sequence numbers "shuffled down" to fill the gaps. + # + # UIDs, on the other hand, are permanently guaranteed not to + # identify another message within the same mailbox, even if + # the existing message is deleted. UIDs are required to + # be assigned in ascending (but not necessarily sequential) + # order within a mailbox; this means that if a non-IMAP client + # rearranges the order of mailitems within a mailbox, the + # UIDs have to be reassigned. An IMAP client cannot thus + # rearrange message orders. + # + # == Examples of Usage + # + # === List sender and subject of all recent messages in the default mailbox + # + # imap = Net::IMAP.new('mail.example.com') + # imap.authenticate('LOGIN', 'joe_user', 'joes_password') + # imap.examine('INBOX') + # imap.search(["RECENT"]).each do |message_id| + # envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"] + # puts "#{envelope.from[0].name}: \t#{envelope.subject}" + # end + # + # === Move all messages from April 2003 from "Mail/sent-mail" to "Mail/sent-apr03" + # + # imap = Net::IMAP.new('mail.example.com') + # imap.authenticate('LOGIN', 'joe_user', 'joes_password') + # imap.select('Mail/sent-mail') + # if not imap.list('Mail/', 'sent-apr03') + # imap.create('Mail/sent-apr03') + # end + # imap.search(["BEFORE", "30-Apr-2003", "SINCE", "1-Apr-2003"]).each do |message_id| + # imap.copy(message_id, "Mail/sent-apr03") + # imap.store(message_id, "+FLAGS", [:Deleted]) + # end + # imap.expunge + # + # == Thread Safety + # + # Net::IMAP supports concurrent threads. For example, + # + # imap = Net::IMAP.new("imap.foo.net", "imap2") + # imap.authenticate("cram-md5", "bar", "password") + # imap.select("inbox") + # fetch_thread = Thread.start { imap.fetch(1..-1, "UID") } + # search_result = imap.search(["BODY", "hello"]) + # fetch_result = fetch_thread.value + # imap.disconnect + # + # This script invokes the FETCH command and the SEARCH command concurrently. + # + # == Errors + # + # An IMAP server can send three different types of responses to indicate + # failure: + # + # NO:: the attempted command could not be successfully completed. For + # instance, the username/password used for logging in are incorrect; + # the selected mailbox does not exists; etc. + # + # BAD:: the request from the client does not follow the server's + # understanding of the IMAP protocol. This includes attempting + # commands from the wrong client state; for instance, attempting + # to perform a SEARCH command without having SELECTed a current + # mailbox. It can also signal an internal server + # failure (such as a disk crash) has occurred. + # + # BYE:: the server is saying goodbye. This can be part of a normal + # logout sequence, and can be used as part of a login sequence + # to indicate that the server is (for some reason) unwilling + # to accept our connection. As a response to any other command, + # it indicates either that the server is shutting down, or that + # the server is timing out the client connection due to inactivity. + # + # These three error response are represented by the errors + # Net::IMAP::NoResponseError, Net::IMAP::BadResponseError, and + # Net::IMAP::ByeResponseError, all of which are subclasses of + # Net::IMAP::ResponseError. Essentially, all methods that involve + # sending a request to the server can generate one of these errors. + # Only the most pertinent instances have been documented below. + # + # Because the IMAP class uses Sockets for communication, its methods + # are also susceptible to the various errors that can occur when + # working with sockets. These are generally represented as + # Errno errors. For instance, any method that involves sending a + # request to the server and/or receiving a response from it could + # raise an Errno::EPIPE error if the network connection unexpectedly + # goes down. See the socket(7), ip(7), tcp(7), socket(2), connect(2), + # and associated man pages. + # + # Finally, a Net::IMAP::DataFormatError is thrown if low-level data + # is found to be in an incorrect format (for instance, when converting + # between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is + # thrown if a server response is non-parseable. + # + # + # == References + # + # [[IMAP]] + # M. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", + # RFC 2060, December 1996. (Note: since obsoleted by RFC 3501) + # + # [[LANGUAGE-TAGS]] + # Alvestrand, H., "Tags for the Identification of + # Languages", RFC 1766, March 1995. + # + # [[MD5]] + # Myers, J., and M. Rose, "The Content-MD5 Header Field", RFC + # 1864, October 1995. + # + # [[MIME-IMB]] + # Freed, N., and N. Borenstein, "MIME (Multipurpose Internet + # Mail Extensions) Part One: Format of Internet Message Bodies", RFC + # 2045, November 1996. + # + # [[RFC-822]] + # Crocker, D., "Standard for the Format of ARPA Internet Text + # Messages", STD 11, RFC 822, University of Delaware, August 1982. + # + # [[RFC-2087]] + # Myers, J., "IMAP4 QUOTA extension", RFC 2087, January 1997. + # + # [[RFC-2086]] + # Myers, J., "IMAP4 ACL extension", RFC 2086, January 1997. + # + # [[RFC-2195]] + # Klensin, J., Catoe, R., and Krumviede, P., "IMAP/POP AUTHorize Extension + # for Simple Challenge/Response", RFC 2195, September 1997. + # + # [[SORT-THREAD-EXT]] + # Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - SORT and THREAD + # Extensions", draft-ietf-imapext-sort, May 2003. + # + # [[OSSL]] + # http://www.openssl.org + # + # [[RSSL]] + # http://savannah.gnu.org/projects/rubypki + # + # [[UTF7]] + # Goldsmith, D. and Davis, M., "UTF-7: A Mail-Safe Transformation Format of + # Unicode", RFC 2152, May 1997. + # + class IMAP + include MonitorMixin + if defined?(OpenSSL) + include OpenSSL + include SSL + end + + # Returns an initial greeting response from the server. + attr_reader :greeting + + # Returns recorded untagged responses. For example: + # + # imap.select("inbox") + # p imap.responses["EXISTS"][-1] + # #=> 2 + # p imap.responses["UIDVALIDITY"][-1] + # #=> 968263756 + attr_reader :responses + + # Returns all response handlers. + attr_reader :response_handlers + + # The thread to receive exceptions. + attr_accessor :client_thread + + # Flag indicating a message has been seen + SEEN = :Seen + + # Flag indicating a message has been answered + ANSWERED = :Answered + + # Flag indicating a message has been flagged for special or urgent + # attention + FLAGGED = :Flagged + + # Flag indicating a message has been marked for deletion. This + # will occur when the mailbox is closed or expunged. + DELETED = :Deleted + + # Flag indicating a message is only a draft or work-in-progress version. + DRAFT = :Draft + + # Flag indicating that the message is "recent", meaning that this + # session is the first session in which the client has been notified + # of this message. + RECENT = :Recent + + # Flag indicating that a mailbox context name cannot contain + # children. + NOINFERIORS = :Noinferiors + + # Flag indicating that a mailbox is not selected. + NOSELECT = :Noselect + + # Flag indicating that a mailbox has been marked "interesting" by + # the server; this commonly indicates that the mailbox contains + # new messages. + MARKED = :Marked + + # Flag indicating that the mailbox does not contains new messages. + UNMARKED = :Unmarked + + # Returns the debug mode. + def self.debug + return @@debug + end + + # Sets the debug mode. + def self.debug=(val) + return @@debug = val + end + + # Adds an authenticator for Net::IMAP#authenticate. +auth_type+ + # is the type of authentication this authenticator supports + # (for instance, "LOGIN"). The +authenticator+ is an object + # which defines a process() method to handle authentication with + # the server. See Net::IMAP::LoginAuthenticator and + # Net::IMAP::CramMD5Authenticator for examples. + # + # If +auth_type+ refers to an existing authenticator, it will be + # replaced by the new one. + def self.add_authenticator(auth_type, authenticator) + @@authenticators[auth_type] = authenticator + end + + # Disconnects from the server. + def disconnect + if SSL::SSLSocket === @sock + @sock.io.shutdown + else + @sock.shutdown + end + @receiver_thread.join + @sock.close + end + + # Returns true if disconnected from the server. + def disconnected? + return @sock.closed? + end + + # Sends a CAPABILITY command, and returns an array of + # capabilities that the server supports. Each capability + # is a string. See [IMAP] for a list of possible + # capabilities. + # + # Note that the Net::IMAP class does not modify its + # behaviour according to the capabilities of the server; + # it is up to the user of the class to ensure that + # a certain capability is supported by a server before + # using it. + def capability + synchronize do + send_command("CAPABILITY") + return @responses.delete("CAPABILITY")[-1] + end + end + + # Sends a NOOP command to the server. It does nothing. + def noop + send_command("NOOP") + end + + # Sends a LOGOUT command to inform the server that the client is + # done with the connection. + def logout + send_command("LOGOUT") + end + + # Sends an AUTHENTICATE command to authenticate the client. + # The +auth_type+ parameter is a string that represents + # the authentication mechanism to be used. Currently Net::IMAP + # supports authentication mechanisms: + # + # LOGIN:: login using cleartext user and password. + # CRAM-MD5:: login with cleartext user and encrypted password + # (see [RFC-2195] for a full description). This + # mechanism requires that the server have the user's + # password stored in clear-text password. + # + # For both these mechanisms, there should be two +args+: username + # and (cleartext) password. A server may not support one or other + # of these mechanisms; check #capability() for a capability of + # the form "AUTH=LOGIN" or "AUTH=CRAM-MD5". + # + # Authentication is done using the appropriate authenticator object: + # see @@authenticators for more information on plugging in your own + # authenticator. + # + # For example: + # + # imap.authenticate('LOGIN', user, password) + # + # A Net::IMAP::NoResponseError is raised if authentication fails. + def authenticate(auth_type, *args) + auth_type = auth_type.upcase + unless @@authenticators.has_key?(auth_type) + raise ArgumentError, + format('unknown auth type - "%s"', auth_type) + end + authenticator = @@authenticators[auth_type].new(*args) + send_command("AUTHENTICATE", auth_type) do |resp| + if resp.instance_of?(ContinuationRequest) + data = authenticator.process(resp.data.text.unpack("m")[0]) + s = [data].pack("m").gsub(/\n/, "") + send_string_data(s) + put_string(CRLF) + end + end + end + + # Sends a LOGIN command to identify the client and carries + # the plaintext +password+ authenticating this +user+. Note + # that, unlike calling #authenticate() with an +auth_type+ + # of "LOGIN", #login() does *not* use the login authenticator. + # + # A Net::IMAP::NoResponseError is raised if authentication fails. + def login(user, password) + send_command("LOGIN", user, password) + end + + # Sends a SELECT command to select a +mailbox+ so that messages + # in the +mailbox+ can be accessed. + # + # After you have selected a mailbox, you may retrieve the + # number of items in that mailbox from @responses["EXISTS"][-1], + # and the number of recent messages from @responses["RECENT"][-1]. + # Note that these values can change if new messages arrive + # during a session; see #add_response_handler() for a way of + # detecting this event. + # + # A Net::IMAP::NoResponseError is raised if the mailbox does not + # exist or is for some reason non-selectable. + def select(mailbox) + synchronize do + @responses.clear + send_command("SELECT", mailbox) + end + end + + # Sends a EXAMINE command to select a +mailbox+ so that messages + # in the +mailbox+ can be accessed. Behaves the same as #select(), + # except that the selected +mailbox+ is identified as read-only. + # + # A Net::IMAP::NoResponseError is raised if the mailbox does not + # exist or is for some reason non-examinable. + def examine(mailbox) + synchronize do + @responses.clear + send_command("EXAMINE", mailbox) + end + end + + # Sends a CREATE command to create a new +mailbox+. + # + # A Net::IMAP::NoResponseError is raised if a mailbox with that name + # cannot be created. + def create(mailbox) + send_command("CREATE", mailbox) + end + + # Sends a DELETE command to remove the +mailbox+. + # + # A Net::IMAP::NoResponseError is raised if a mailbox with that name + # cannot be deleted, either because it does not exist or because the + # client does not have permission to delete it. + def delete(mailbox) + send_command("DELETE", mailbox) + end + + # Sends a RENAME command to change the name of the +mailbox+ to + # +newname+. + # + # A Net::IMAP::NoResponseError is raised if a mailbox with the + # name +mailbox+ cannot be renamed to +newname+ for whatever + # reason; for instance, because +mailbox+ does not exist, or + # because there is already a mailbox with the name +newname+. + def rename(mailbox, newname) + send_command("RENAME", mailbox, newname) + end + + # Sends a SUBSCRIBE command to add the specified +mailbox+ name to + # the server's set of "active" or "subscribed" mailboxes as returned + # by #lsub(). + # + # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be + # subscribed to, for instance because it does not exist. + def subscribe(mailbox) + send_command("SUBSCRIBE", mailbox) + end + + # Sends a UNSUBSCRIBE command to remove the specified +mailbox+ name + # from the server's set of "active" or "subscribed" mailboxes. + # + # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be + # unsubscribed from, for instance because the client is not currently + # subscribed to it. + def unsubscribe(mailbox) + send_command("UNSUBSCRIBE", mailbox) + end + + # Sends a LIST command, and returns a subset of names from + # the complete set of all names available to the client. + # +refname+ provides a context (for instance, a base directory + # in a directory-based mailbox hierarchy). +mailbox+ specifies + # a mailbox or (via wildcards) mailboxes under that context. + # Two wildcards may be used in +mailbox+: '*', which matches + # all characters *including* the hierarchy delimiter (for instance, + # '/' on a UNIX-hosted directory-based mailbox hierarchy); and '%', + # which matches all characters *except* the hierarchy delimiter. + # + # If +refname+ is empty, +mailbox+ is used directly to determine + # which mailboxes to match. If +mailbox+ is empty, the root + # name of +refname+ and the hierarchy delimiter are returned. + # + # The return value is an array of +Net::IMAP::MailboxList+. For example: + # + # imap.create("foo/bar") + # imap.create("foo/baz") + # p imap.list("", "foo/%") + # #=> [#, \\ + # #, \\ + # #] + def list(refname, mailbox) + synchronize do + send_command("LIST", refname, mailbox) + return @responses.delete("LIST") + end + end + + # Sends the GETQUOTAROOT command along with specified +mailbox+. + # This command is generally available to both admin and user. + # If mailbox exists, returns an array containing objects of + # Net::IMAP::MailboxQuotaRoot and Net::IMAP::MailboxQuota. + def getquotaroot(mailbox) + synchronize do + send_command("GETQUOTAROOT", mailbox) + result = [] + result.concat(@responses.delete("QUOTAROOT")) + result.concat(@responses.delete("QUOTA")) + return result + end + end + + # Sends the GETQUOTA command along with specified +mailbox+. + # If this mailbox exists, then an array containing a + # Net::IMAP::MailboxQuota object is returned. This + # command generally is only available to server admin. + def getquota(mailbox) + synchronize do + send_command("GETQUOTA", mailbox) + return @responses.delete("QUOTA") + end + end + + # Sends a SETQUOTA command along with the specified +mailbox+ and + # +quota+. If +quota+ is nil, then quota will be unset for that + # mailbox. Typically one needs to be logged in as server admin + # for this to work. The IMAP quota commands are described in + # [RFC-2087]. + def setquota(mailbox, quota) + if quota.nil? + data = '()' + else + data = '(STORAGE ' + quota.to_s + ')' + end + send_command("SETQUOTA", mailbox, RawData.new(data)) + end + + # Sends the SETACL command along with +mailbox+, +user+ and the + # +rights+ that user is to have on that mailbox. If +rights+ is nil, + # then that user will be stripped of any rights to that mailbox. + # The IMAP ACL commands are described in [RFC-2086]. + def setacl(mailbox, user, rights) + if rights.nil? + send_command("SETACL", mailbox, user, "") + else + send_command("SETACL", mailbox, user, rights) + end + end + + # Send the GETACL command along with specified +mailbox+. + # If this mailbox exists, an array containing objects of + # Net::IMAP::MailboxACLItem will be returned. + def getacl(mailbox) + synchronize do + send_command("GETACL", mailbox) + return @responses.delete("ACL")[-1] + end + end + + # Sends a LSUB command, and returns a subset of names from the set + # of names that the user has declared as being "active" or + # "subscribed". +refname+ and +mailbox+ are interpreted as + # for #list(). + # The return value is an array of +Net::IMAP::MailboxList+. + def lsub(refname, mailbox) + synchronize do + send_command("LSUB", refname, mailbox) + return @responses.delete("LSUB") + end + end + + # Sends a STATUS command, and returns the status of the indicated + # +mailbox+. +attr+ is a list of one or more attributes that + # we are request the status of. Supported attributes include: + # + # MESSAGES:: the number of messages in the mailbox. + # RECENT:: the number of recent messages in the mailbox. + # UNSEEN:: the number of unseen messages in the mailbox. + # + # The return value is a hash of attributes. For example: + # + # p imap.status("inbox", ["MESSAGES", "RECENT"]) + # #=> {"RECENT"=>0, "MESSAGES"=>44} + # + # A Net::IMAP::NoResponseError is raised if status values + # for +mailbox+ cannot be returned, for instance because it + # does not exist. + def status(mailbox, attr) + synchronize do + send_command("STATUS", mailbox, attr) + return @responses.delete("STATUS")[-1].attr + end + end + + # Sends a APPEND command to append the +message+ to the end of + # the +mailbox+. The optional +flags+ argument is an array of + # flags to initially passing to the new message. The optional + # +date_time+ argument specifies the creation time to assign to the + # new message; it defaults to the current time. + # For example: + # + # imap.append("inbox", <:: a set of message sequence numbers. ',' indicates + # an interval, ':' indicates a range. For instance, + # '2,10:12,15' means "2,10,11,12,15". + # + # BEFORE :: messages with an internal date strictly before + # . The date argument has a format similar + # to 8-Aug-2002. + # + # BODY :: messages that contain within their body. + # + # CC :: messages containing in their CC field. + # + # FROM :: messages that contain in their FROM field. + # + # NEW:: messages with the \Recent, but not the \Seen, flag set. + # + # NOT :: negate the following search key. + # + # OR :: "or" two search keys together. + # + # ON :: messages with an internal date exactly equal to , + # which has a format similar to 8-Aug-2002. + # + # SINCE :: messages with an internal date on or after . + # + # SUBJECT :: messages with in their subject. + # + # TO :: messages with in their TO field. + # + # For example: + # + # p imap.search(["SUBJECT", "hello", "NOT", "NEW"]) + # #=> [1, 6, 7, 8] + def search(keys, charset = nil) + return search_internal("SEARCH", keys, charset) + end + + # As for #search(), but returns unique identifiers. + def uid_search(keys, charset = nil) + return search_internal("UID SEARCH", keys, charset) + end + + # Sends a FETCH command to retrieve data associated with a message + # in the mailbox. The +set+ parameter is a number or an array of + # numbers or a Range object. The number is a message sequence + # number. +attr+ is a list of attributes to fetch; see the + # documentation for Net::IMAP::FetchData for a list of valid + # attributes. + # The return value is an array of Net::IMAP::FetchData. For example: + # + # p imap.fetch(6..8, "UID") + # #=> [#98}>, \\ + # #99}>, \\ + # #100}>] + # p imap.fetch(6, "BODY[HEADER.FIELDS (SUBJECT)]") + # #=> [#"Subject: test\r\n\r\n"}>] + # data = imap.uid_fetch(98, ["RFC822.SIZE", "INTERNALDATE"])[0] + # p data.seqno + # #=> 6 + # p data.attr["RFC822.SIZE"] + # #=> 611 + # p data.attr["INTERNALDATE"] + # #=> "12-Oct-2000 22:40:59 +0900" + # p data.attr["UID"] + # #=> 98 + def fetch(set, attr) + return fetch_internal("FETCH", set, attr) + end + + # As for #fetch(), but +set+ contains unique identifiers. + def uid_fetch(set, attr) + return fetch_internal("UID FETCH", set, attr) + end + + # Sends a STORE command to alter data associated with messages + # in the mailbox, in particular their flags. The +set+ parameter + # is a number or an array of numbers or a Range object. Each number + # is a message sequence number. +attr+ is the name of a data item + # to store: 'FLAGS' means to replace the message's flag list + # with the provided one; '+FLAGS' means to add the provided flags; + # and '-FLAGS' means to remove them. +flags+ is a list of flags. + # + # The return value is an array of Net::IMAP::FetchData. For example: + # + # p imap.store(6..8, "+FLAGS", [:Deleted]) + # #=> [#[:Seen, :Deleted]}>, \\ + # #[:Seen, :Deleted]}>, \\ + # #[:Seen, :Deleted]}>] + def store(set, attr, flags) + return store_internal("STORE", set, attr, flags) + end + + # As for #store(), but +set+ contains unique identifiers. + def uid_store(set, attr, flags) + return store_internal("UID STORE", set, attr, flags) + end + + # Sends a COPY command to copy the specified message(s) to the end + # of the specified destination +mailbox+. The +set+ parameter is + # a number or an array of numbers or a Range object. The number is + # a message sequence number. + def copy(set, mailbox) + copy_internal("COPY", set, mailbox) + end + + # As for #copy(), but +set+ contains unique identifiers. + def uid_copy(set, mailbox) + copy_internal("UID COPY", set, mailbox) + end + + # Sends a SORT command to sort messages in the mailbox. + # Returns an array of message sequence numbers. For example: + # + # p imap.sort(["FROM"], ["ALL"], "US-ASCII") + # #=> [1, 2, 3, 5, 6, 7, 8, 4, 9] + # p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII") + # #=> [6, 7, 8, 1] + # + # See [SORT-THREAD-EXT] for more details. + def sort(sort_keys, search_keys, charset) + return sort_internal("SORT", sort_keys, search_keys, charset) + end + + # As for #sort(), but returns an array of unique identifiers. + def uid_sort(sort_keys, search_keys, charset) + return sort_internal("UID SORT", sort_keys, search_keys, charset) + end + + # Adds a response handler. For example, to detect when + # the server sends us a new EXISTS response (which normally + # indicates new messages being added to the mail box), + # you could add the following handler after selecting the + # mailbox. + # + # imap.add_response_handler { |resp| + # if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS" + # puts "Mailbox now has #{resp.data} messages" + # end + # } + # + def add_response_handler(handler = Proc.new) + @response_handlers.push(handler) + end + + # Removes the response handler. + def remove_response_handler(handler) + @response_handlers.delete(handler) + end + + # As for #search(), but returns message sequence numbers in threaded + # format, as a Net::IMAP::ThreadMember tree. The supported algorithms + # are: + # + # ORDEREDSUBJECT:: split into single-level threads according to subject, + # ordered by date. + # REFERENCES:: split into threads by parent/child relationships determined + # by which message is a reply to which. + # + # Unlike #search(), +charset+ is a required argument. US-ASCII + # and UTF-8 are sample values. + # + # See [SORT-THREAD-EXT] for more details. + def thread(algorithm, search_keys, charset) + return thread_internal("THREAD", algorithm, search_keys, charset) + end + + # As for #thread(), but returns unique identifiers instead of + # message sequence numbers. + def uid_thread(algorithm, search_keys, charset) + return thread_internal("UID THREAD", algorithm, search_keys, charset) + end + + # Decode a string from modified UTF-7 format to UTF-8. + # + # UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a + # slightly modified version of this to encode mailbox names + # containing non-ASCII characters; see [IMAP] section 5.1.3. + # + # Net::IMAP does _not_ automatically encode and decode + # mailbox names to and from utf7. + def self.decode_utf7(s) + return s.gsub(/&(.*?)-/n) { + if $1.empty? + "&" + else + base64 = $1.tr(",", "/") + x = base64.length % 4 + if x > 0 + base64.concat("=" * (4 - x)) + end + u16tou8(base64.unpack("m")[0]) + end + } + end + + # Encode a string from UTF-8 format to modified UTF-7. + def self.encode_utf7(s) + return s.gsub(/(&)|([^\x20-\x25\x27-\x7e]+)/n) { |x| + if $1 + "&-" + else + base64 = [u8tou16(x)].pack("m") + "&" + base64.delete("=\n").tr("/", ",") + "-" + end + } + end + + private + + CRLF = "\r\n" # :nodoc: + PORT = 143 # :nodoc: + + @@debug = false + @@authenticators = {} + + # Creates a new Net::IMAP object and connects it to the specified + # +port+ (143 by default) on the named +host+. If +usessl+ is true, + # then an attempt will + # be made to use SSL (now TLS) to connect to the server. For this + # to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL] + # extensions need to be installed. The +certs+ parameter indicates + # the path or file containing the CA cert of the server, and the + # +verify+ parameter is for the OpenSSL verification callback. + # + # The most common errors are: + # + # Errno::ECONNREFUSED:: connection refused by +host+ or an intervening + # firewall. + # Errno::ETIMEDOUT:: connection timed out (possibly due to packets + # being dropped by an intervening firewall). + # Errno::ENETUNREACH:: there is no route to that network. + # SocketError:: hostname not known or other socket error. + # Net::IMAP::ByeResponseError:: we connected to the host, but they + # immediately said goodbye to us. + def initialize(host, port = PORT, usessl = false, certs = nil, verify = false) + super() + @host = host + @port = port + @tag_prefix = "RUBY" + @tagno = 0 + @parser = ResponseParser.new + @sock = TCPSocket.open(host, port) + if usessl + unless defined?(OpenSSL) + raise "SSL extension not installed" + end + @usessl = true + + # verify the server. + context = SSLContext::new() + context.ca_file = certs if certs && FileTest::file?(certs) + context.ca_path = certs if certs && FileTest::directory?(certs) + context.verify_mode = VERIFY_PEER if verify + if defined?(VerifyCallbackProc) + context.verify_callback = VerifyCallbackProc + end + @sock = SSLSocket.new(@sock, context) + @sock.connect # start ssl session. + @sock.post_connection_check(@host) if verify + else + @usessl = false + end + @responses = Hash.new([].freeze) + @tagged_responses = {} + @response_handlers = [] + @response_arrival = new_cond + @continuation_request = nil + @logout_command_tag = nil + @debug_output_bol = true + + @greeting = get_response + if @greeting.name == "BYE" + @sock.close + raise ByeResponseError, @greeting.raw_data + end + + @client_thread = Thread.current + @receiver_thread = Thread.start { + receive_responses + } + end + + def receive_responses + while true + begin + resp = get_response + rescue Exception + @sock.close + @client_thread.raise($!) + break + end + break unless resp + begin + synchronize do + case resp + when TaggedResponse + @tagged_responses[resp.tag] = resp + @response_arrival.broadcast + if resp.tag == @logout_command_tag + return + end + when UntaggedResponse + record_response(resp.name, resp.data) + if resp.data.instance_of?(ResponseText) && + (code = resp.data.code) + record_response(code.name, code.data) + end + if resp.name == "BYE" && @logout_command_tag.nil? + @sock.close + raise ByeResponseError, resp.raw_data + end + when ContinuationRequest + @continuation_request = resp + @response_arrival.broadcast + end + @response_handlers.each do |handler| + handler.call(resp) + end + end + rescue Exception + @client_thread.raise($!) + end + end + end + + def get_tagged_response(tag) + until @tagged_responses.key?(tag) + @response_arrival.wait + end + return pick_up_tagged_response(tag) + end + + def pick_up_tagged_response(tag) + resp = @tagged_responses.delete(tag) + case resp.name + when /\A(?:NO)\z/ni + raise NoResponseError, resp.data.text + when /\A(?:BAD)\z/ni + raise BadResponseError, resp.data.text + else + return resp + end + end + + def get_response + buff = "" + while true + s = @sock.gets(CRLF) + break unless s + buff.concat(s) + if /\{(\d+)\}\r\n/n =~ s + s = @sock.read($1.to_i) + buff.concat(s) + else + break + end + end + return nil if buff.length == 0 + if @@debug + $stderr.print(buff.gsub(/^/n, "S: ")) + end + return @parser.parse(buff) + end + + def record_response(name, data) + unless @responses.has_key?(name) + @responses[name] = [] + end + @responses[name].push(data) + end + + def send_command(cmd, *args, &block) + synchronize do + tag = Thread.current[:net_imap_tag] = generate_tag + put_string(tag + " " + cmd) + args.each do |i| + put_string(" ") + send_data(i) + end + put_string(CRLF) + if cmd == "LOGOUT" + @logout_command_tag = tag + end + if block + add_response_handler(block) + end + begin + return get_tagged_response(tag) + ensure + if block + remove_response_handler(block) + end + end + end + end + + def generate_tag + @tagno += 1 + return format("%s%04d", @tag_prefix, @tagno) + end + + def put_string(str) + @sock.print(str) + if @@debug + if @debug_output_bol + $stderr.print("C: ") + end + $stderr.print(str.gsub(/\n(?!\z)/n, "\nC: ")) + if /\r\n\z/n.match(str) + @debug_output_bol = true + else + @debug_output_bol = false + end + end + end + + def send_data(data) + case data + when nil + put_string("NIL") + when String + send_string_data(data) + when Integer + send_number_data(data) + when Array + send_list_data(data) + when Time + send_time_data(data) + when Symbol + send_symbol_data(data) + else + data.send_data(self) + end + end + + def send_string_data(str) + case str + when "" + put_string('""') + when /[\x80-\xff\r\n]/n + # literal + send_literal(str) + when /[(){ \x00-\x1f\x7f%*"\\]/n + # quoted string + send_quoted_string(str) + else + put_string(str) + end + end + + def send_quoted_string(str) + put_string('"' + str.gsub(/["\\]/n, "\\\\\\&") + '"') + end + + def send_literal(str) + put_string("{" + str.length.to_s + "}" + CRLF) + while @continuation_request.nil? && + !@tagged_responses.key?(Thread.current[:net_imap_tag]) + @response_arrival.wait + end + if @continuation_request.nil? + pick_up_tagged_response(Thread.current[:net_imap_tag]) + raise ResponseError.new("expected continuation request") + end + @continuation_request = nil + put_string(str) + end + + def send_number_data(num) + if num < 0 || num >= 4294967296 + raise DataFormatError, num.to_s + end + put_string(num.to_s) + end + + def send_list_data(list) + put_string("(") + first = true + list.each do |i| + if first + first = false + else + put_string(" ") + end + send_data(i) + end + put_string(")") + end + + DATE_MONTH = %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) + + def send_time_data(time) + t = time.dup.gmtime + s = format('"%2d-%3s-%4d %02d:%02d:%02d +0000"', + t.day, DATE_MONTH[t.month - 1], t.year, + t.hour, t.min, t.sec) + put_string(s) + end + + def send_symbol_data(symbol) + put_string("\\" + symbol.to_s) + end + + def search_internal(cmd, keys, charset) + if keys.instance_of?(String) + keys = [RawData.new(keys)] + else + normalize_searching_criteria(keys) + end + synchronize do + if charset + send_command(cmd, "CHARSET", charset, *keys) + else + send_command(cmd, *keys) + end + return @responses.delete("SEARCH")[-1] + end + end + + def fetch_internal(cmd, set, attr) + if attr.instance_of?(String) + attr = RawData.new(attr) + end + synchronize do + @responses.delete("FETCH") + send_command(cmd, MessageSet.new(set), attr) + return @responses.delete("FETCH") + end + end + + def store_internal(cmd, set, attr, flags) + if attr.instance_of?(String) + attr = RawData.new(attr) + end + synchronize do + @responses.delete("FETCH") + send_command(cmd, MessageSet.new(set), attr, flags) + return @responses.delete("FETCH") + end + end + + def copy_internal(cmd, set, mailbox) + send_command(cmd, MessageSet.new(set), mailbox) + end + + def sort_internal(cmd, sort_keys, search_keys, charset) + if search_keys.instance_of?(String) + search_keys = [RawData.new(search_keys)] + else + normalize_searching_criteria(search_keys) + end + normalize_searching_criteria(search_keys) + synchronize do + send_command(cmd, sort_keys, charset, *search_keys) + return @responses.delete("SORT")[-1] + end + end + + def thread_internal(cmd, algorithm, search_keys, charset) + if search_keys.instance_of?(String) + search_keys = [RawData.new(search_keys)] + else + normalize_searching_criteria(search_keys) + end + normalize_searching_criteria(search_keys) + send_command(cmd, algorithm, charset, *search_keys) + return @responses.delete("THREAD")[-1] + end + + def normalize_searching_criteria(keys) + keys.collect! do |i| + case i + when -1, Range, Array + MessageSet.new(i) + else + i + end + end + end + + def self.u16tou8(s) + len = s.length + if len < 2 + return "" + end + buf = "" + i = 0 + while i < len + c = s[i] << 8 | s[i + 1] + i += 2 + if c == 0xfeff + next + elsif c < 0x0080 + buf.concat(c) + elsif c < 0x0800 + b2 = c & 0x003f + b1 = c >> 6 + buf.concat(b1 | 0xc0) + buf.concat(b2 | 0x80) + elsif c >= 0xdc00 && c < 0xe000 + raise DataFormatError, "invalid surrogate detected" + elsif c >= 0xd800 && c < 0xdc00 + if i + 2 > len + raise DataFormatError, "invalid surrogate detected" + end + low = s[i] << 8 | s[i + 1] + i += 2 + if low < 0xdc00 || low > 0xdfff + raise DataFormatError, "invalid surrogate detected" + end + c = (((c & 0x03ff)) << 10 | (low & 0x03ff)) + 0x10000 + b4 = c & 0x003f + b3 = (c >> 6) & 0x003f + b2 = (c >> 12) & 0x003f + b1 = c >> 18; + buf.concat(b1 | 0xf0) + buf.concat(b2 | 0x80) + buf.concat(b3 | 0x80) + buf.concat(b4 | 0x80) + else # 0x0800-0xffff + b3 = c & 0x003f + b2 = (c >> 6) & 0x003f + b1 = c >> 12 + buf.concat(b1 | 0xe0) + buf.concat(b2 | 0x80) + buf.concat(b3 | 0x80) + end + end + return buf + end + private_class_method :u16tou8 + + def self.u8tou16(s) + len = s.length + buf = "" + i = 0 + while i < len + c = s[i] + if (c & 0x80) == 0 + buf.concat(0x00) + buf.concat(c) + i += 1 + elsif (c & 0xe0) == 0xc0 && + len >= 2 && + (s[i + 1] & 0xc0) == 0x80 + if c == 0xc0 || c == 0xc1 + raise DataFormatError, format("non-shortest UTF-8 sequence (%02x)", c) + end + u = ((c & 0x1f) << 6) | (s[i + 1] & 0x3f) + buf.concat(u >> 8) + buf.concat(u & 0x00ff) + i += 2 + elsif (c & 0xf0) == 0xe0 && + i + 2 < len && + (s[i + 1] & 0xc0) == 0x80 && + (s[i + 2] & 0xc0) == 0x80 + if c == 0xe0 && s[i + 1] < 0xa0 + raise DataFormatError, format("non-shortest UTF-8 sequence (%02x)", c) + end + u = ((c & 0x0f) << 12) | ((s[i + 1] & 0x3f) << 6) | (s[i + 2] & 0x3f) + # surrogate chars + if u >= 0xd800 && u <= 0xdfff + raise DataFormatError, format("none-UTF-16 char detected (%04x)", u) + end + buf.concat(u >> 8) + buf.concat(u & 0x00ff) + i += 3 + elsif (c & 0xf8) == 0xf0 && + i + 3 < len && + (s[i + 1] & 0xc0) == 0x80 && + (s[i + 2] & 0xc0) == 0x80 && + (s[i + 3] & 0xc0) == 0x80 + if c == 0xf0 && s[i + 1] < 0x90 + raise DataFormatError, format("non-shortest UTF-8 sequence (%02x)", c) + end + u = ((c & 0x07) << 18) | ((s[i + 1] & 0x3f) << 12) | + ((s[i + 2] & 0x3f) << 6) | (s[i + 3] & 0x3f) + if u < 0x10000 + buf.concat(u >> 8) + buf.concat(u & 0x00ff) + elsif u < 0x110000 + high = ((u - 0x10000) >> 10) | 0xd800 + low = (u & 0x03ff) | 0xdc00 + buf.concat(high >> 8) + buf.concat(high & 0x00ff) + buf.concat(low >> 8) + buf.concat(low & 0x00ff) + else + raise DataFormatError, format("none-UTF-16 char detected (%04x)", u) + end + i += 4 + else + raise DataFormatError, format("illegal UTF-8 sequence (%02x)", c) + end + end + return buf + end + private_class_method :u8tou16 + + class RawData # :nodoc: + def send_data(imap) + imap.send(:put_string, @data) + end + + private + + def initialize(data) + @data = data + end + end + + class Atom # :nodoc: + def send_data(imap) + imap.send(:put_string, @data) + end + + private + + def initialize(data) + @data = data + end + end + + class QuotedString # :nodoc: + def send_data(imap) + imap.send(:send_quoted_string, @data) + end + + private + + def initialize(data) + @data = data + end + end + + class Literal # :nodoc: + def send_data(imap) + imap.send(:send_literal, @data) + end + + private + + def initialize(data) + @data = data + end + end + + class MessageSet # :nodoc: + def send_data(imap) + imap.send(:put_string, format_internal(@data)) + end + + private + + def initialize(data) + @data = data + end + + def format_internal(data) + case data + when "*" + return data + when Integer + ensure_nz_number(data) + if data == -1 + return "*" + else + return data.to_s + end + when Range + return format_internal(data.first) + + ":" + format_internal(data.last) + when Array + return data.collect {|i| format_internal(i)}.join(",") + when ThreadMember + return data.seqno.to_s + + ":" + data.children.collect {|i| format_internal(i).join(",")} + else + raise DataFormatError, data.inspect + end + end + + def ensure_nz_number(num) + if num < -1 || num == 0 || num >= 4294967296 + msg = "nz_number must be non-zero unsigned 32-bit integer: " + + num.inspect + raise DataFormatError, msg + end + end + end + + # Net::IMAP::ContinuationRequest represents command continuation requests. + # + # The command continuation request response is indicated by a "+" token + # instead of a tag. This form of response indicates that the server is + # ready to accept the continuation of a command from the client. The + # remainder of this response is a line of text. + # + # continue_req ::= "+" SPACE (resp_text / base64) + # + # ==== Fields: + # + # data:: Returns the data (Net::IMAP::ResponseText). + # + # raw_data:: Returns the raw data string. + ContinuationRequest = Struct.new(:data, :raw_data) + + # Net::IMAP::UntaggedResponse represents untagged responses. + # + # Data transmitted by the server to the client and status responses + # that do not indicate command completion are prefixed with the token + # "*", and are called untagged responses. + # + # response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye / + # mailbox_data / message_data / capability_data) + # + # ==== Fields: + # + # name:: Returns the name such as "FLAGS", "LIST", "FETCH".... + # + # data:: Returns the data such as an array of flag symbols, + # a (()) object.... + # + # raw_data:: Returns the raw data string. + UntaggedResponse = Struct.new(:name, :data, :raw_data) + + # Net::IMAP::TaggedResponse represents tagged responses. + # + # The server completion result response indicates the success or + # failure of the operation. It is tagged with the same tag as the + # client command which began the operation. + # + # response_tagged ::= tag SPACE resp_cond_state CRLF + # + # tag ::= 1* + # + # resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text + # + # ==== Fields: + # + # tag:: Returns the tag. + # + # name:: Returns the name. the name is one of "OK", "NO", "BAD". + # + # data:: Returns the data. See (()). + # + # raw_data:: Returns the raw data string. + # + TaggedResponse = Struct.new(:tag, :name, :data, :raw_data) + + # Net::IMAP::ResponseText represents texts of responses. + # The text may be prefixed by the response code. + # + # resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text) + # ;; text SHOULD NOT begin with "[" or "=" + # + # ==== Fields: + # + # code:: Returns the response code. See (()). + # + # text:: Returns the text. + # + ResponseText = Struct.new(:code, :text) + + # + # Net::IMAP::ResponseCode represents response codes. + # + # resp_text_code ::= "ALERT" / "PARSE" / + # "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" / + # "READ-ONLY" / "READ-WRITE" / "TRYCREATE" / + # "UIDVALIDITY" SPACE nz_number / + # "UNSEEN" SPACE nz_number / + # atom [SPACE 1*] + # + # ==== Fields: + # + # name:: Returns the name such as "ALERT", "PERMANENTFLAGS", "UIDVALIDITY".... + # + # data:: Returns the data if it exists. + # + ResponseCode = Struct.new(:name, :data) + + # Net::IMAP::MailboxList represents contents of the LIST response. + # + # mailbox_list ::= "(" #("\Marked" / "\Noinferiors" / + # "\Noselect" / "\Unmarked" / flag_extension) ")" + # SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox + # + # ==== Fields: + # + # attr:: Returns the name attributes. Each name attribute is a symbol + # capitalized by String#capitalize, such as :Noselect (not :NoSelect). + # + # delim:: Returns the hierarchy delimiter + # + # name:: Returns the mailbox name. + # + MailboxList = Struct.new(:attr, :delim, :name) + + # Net::IMAP::MailboxQuota represents contents of GETQUOTA response. + # This object can also be a response to GETQUOTAROOT. In the syntax + # specification below, the delimiter used with the "#" construct is a + # single space (SPACE). + # + # quota_list ::= "(" #quota_resource ")" + # + # quota_resource ::= atom SPACE number SPACE number + # + # quota_response ::= "QUOTA" SPACE astring SPACE quota_list + # + # ==== Fields: + # + # mailbox:: The mailbox with the associated quota. + # + # usage:: Current storage usage of mailbox. + # + # quota:: Quota limit imposed on mailbox. + # + MailboxQuota = Struct.new(:mailbox, :usage, :quota) + + # Net::IMAP::MailboxQuotaRoot represents part of the GETQUOTAROOT + # response. (GETQUOTAROOT can also return Net::IMAP::MailboxQuota.) + # + # quotaroot_response ::= "QUOTAROOT" SPACE astring *(SPACE astring) + # + # ==== Fields: + # + # mailbox:: The mailbox with the associated quota. + # + # quotaroots:: Zero or more quotaroots that effect the quota on the + # specified mailbox. + # + MailboxQuotaRoot = Struct.new(:mailbox, :quotaroots) + + # Net::IMAP::MailboxACLItem represents response from GETACL. + # + # acl_data ::= "ACL" SPACE mailbox *(SPACE identifier SPACE rights) + # + # identifier ::= astring + # + # rights ::= astring + # + # ==== Fields: + # + # user:: Login name that has certain rights to the mailbox + # that was specified with the getacl command. + # + # rights:: The access rights the indicated user has to the + # mailbox. + # + MailboxACLItem = Struct.new(:user, :rights) + + # Net::IMAP::StatusData represents contents of the STATUS response. + # + # ==== Fields: + # + # mailbox:: Returns the mailbox name. + # + # attr:: Returns a hash. Each key is one of "MESSAGES", "RECENT", "UIDNEXT", + # "UIDVALIDITY", "UNSEEN". Each value is a number. + # + StatusData = Struct.new(:mailbox, :attr) + + # Net::IMAP::FetchData represents contents of the FETCH response. + # + # ==== Fields: + # + # seqno:: Returns the message sequence number. + # (Note: not the unique identifier, even for the UID command response.) + # + # attr:: Returns a hash. Each key is a data item name, and each value is + # its value. + # + # The current data items are: + # + # [BODY] + # A form of BODYSTRUCTURE without extension data. + # [BODY[
]<>] + # A string expressing the body contents of the specified section. + # [BODYSTRUCTURE] + # An object that describes the [MIME-IMB] body structure of a message. + # See Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText, + # Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart. + # [ENVELOPE] + # A Net::IMAP::Envelope object that describes the envelope + # structure of a message. + # [FLAGS] + # A array of flag symbols that are set for this message. flag symbols + # are capitalized by String#capitalize. + # [INTERNALDATE] + # A string representing the internal date of the message. + # [RFC822] + # Equivalent to BODY[]. + # [RFC822.HEADER] + # Equivalent to BODY.PEEK[HEADER]. + # [RFC822.SIZE] + # A number expressing the [RFC-822] size of the message. + # [RFC822.TEXT] + # Equivalent to BODY[TEXT]. + # [UID] + # A number expressing the unique identifier of the message. + # + FetchData = Struct.new(:seqno, :attr) + + # Net::IMAP::Envelope represents envelope structures of messages. + # + # ==== Fields: + # + # date:: Returns a string that represents the date. + # + # subject:: Returns a string that represents the subject. + # + # from:: Returns an array of Net::IMAP::Address that represents the from. + # + # sender:: Returns an array of Net::IMAP::Address that represents the sender. + # + # reply_to:: Returns an array of Net::IMAP::Address that represents the reply-to. + # + # to:: Returns an array of Net::IMAP::Address that represents the to. + # + # cc:: Returns an array of Net::IMAP::Address that represents the cc. + # + # bcc:: Returns an array of Net::IMAP::Address that represents the bcc. + # + # in_reply_to:: Returns a string that represents the in-reply-to. + # + # message_id:: Returns a string that represents the message-id. + # + Envelope = Struct.new(:date, :subject, :from, :sender, :reply_to, + :to, :cc, :bcc, :in_reply_to, :message_id) + + # + # Net::IMAP::Address represents electronic mail addresses. + # + # ==== Fields: + # + # name:: Returns the phrase from [RFC-822] mailbox. + # + # route:: Returns the route from [RFC-822] route-addr. + # + # mailbox:: nil indicates end of [RFC-822] group. + # If non-nil and host is nil, returns [RFC-822] group name. + # Otherwise, returns [RFC-822] local-part + # + # host:: nil indicates [RFC-822] group syntax. + # Otherwise, returns [RFC-822] domain name. + # + Address = Struct.new(:name, :route, :mailbox, :host) + + # + # Net::IMAP::ContentDisposition represents Content-Disposition fields. + # + # ==== Fields: + # + # dsp_type:: Returns the disposition type. + # + # param:: Returns a hash that represents parameters of the Content-Disposition + # field. + # + ContentDisposition = Struct.new(:dsp_type, :param) + + # Net::IMAP::ThreadMember represents a thread-node returned + # by Net::IMAP#thread + # + # ==== Fields: + # + # seqno:: The sequence number of this message. + # + # children:: an array of Net::IMAP::ThreadMember objects for mail + # items that are children of this in the thread. + # + ThreadMember = Struct.new(:seqno, :children) + + # Net::IMAP::BodyTypeBasic represents basic body structures of messages. + # + # ==== Fields: + # + # media_type:: Returns the content media type name as defined in [MIME-IMB]. + # + # subtype:: Returns the content subtype name as defined in [MIME-IMB]. + # + # param:: Returns a hash that represents parameters as defined in [MIME-IMB]. + # + # content_id:: Returns a string giving the content id as defined in [MIME-IMB]. + # + # description:: Returns a string giving the content description as defined in + # [MIME-IMB]. + # + # encoding:: Returns a string giving the content transfer encoding as defined in + # [MIME-IMB]. + # + # size:: Returns a number giving the size of the body in octets. + # + # md5:: Returns a string giving the body MD5 value as defined in [MD5]. + # + # disposition:: Returns a Net::IMAP::ContentDisposition object giving + # the content disposition. + # + # language:: Returns a string or an array of strings giving the body + # language value as defined in [LANGUAGE-TAGS]. + # + # extension:: Returns extension data. + # + # multipart?:: Returns false. + # + class BodyTypeBasic < Struct.new(:media_type, :subtype, + :param, :content_id, + :description, :encoding, :size, + :md5, :disposition, :language, + :extension) + def multipart? + return false + end + + # Obsolete: use +subtype+ instead. Calling this will + # generate a warning message to +stderr+, then return + # the value of +subtype+. + def media_subtype + $stderr.printf("warning: media_subtype is obsolete.\n") + $stderr.printf(" use subtype instead.\n") + return subtype + end + end + + # Net::IMAP::BodyTypeText represents TEXT body structures of messages. + # + # ==== Fields: + # + # lines:: Returns the size of the body in text lines. + # + # And Net::IMAP::BodyTypeText has all fields of Net::IMAP::BodyTypeBasic. + # + class BodyTypeText < Struct.new(:media_type, :subtype, + :param, :content_id, + :description, :encoding, :size, + :lines, + :md5, :disposition, :language, + :extension) + def multipart? + return false + end + + # Obsolete: use +subtype+ instead. Calling this will + # generate a warning message to +stderr+, then return + # the value of +subtype+. + def media_subtype + $stderr.printf("warning: media_subtype is obsolete.\n") + $stderr.printf(" use subtype instead.\n") + return subtype + end + end + + # Net::IMAP::BodyTypeMessage represents MESSAGE/RFC822 body structures of messages. + # + # ==== Fields: + # + # envelope:: Returns a Net::IMAP::Envelope giving the envelope structure. + # + # body:: Returns an object giving the body structure. + # + # And Net::IMAP::BodyTypeMessage has all methods of Net::IMAP::BodyTypeText. + # + class BodyTypeMessage < Struct.new(:media_type, :subtype, + :param, :content_id, + :description, :encoding, :size, + :envelope, :body, :lines, + :md5, :disposition, :language, + :extension) + def multipart? + return false + end + + # Obsolete: use +subtype+ instead. Calling this will + # generate a warning message to +stderr+, then return + # the value of +subtype+. + def media_subtype + $stderr.printf("warning: media_subtype is obsolete.\n") + $stderr.printf(" use subtype instead.\n") + return subtype + end + end + + # Net::IMAP::BodyTypeMultipart represents multipart body structures + # of messages. + # + # ==== Fields: + # + # media_type:: Returns the content media type name as defined in [MIME-IMB]. + # + # subtype:: Returns the content subtype name as defined in [MIME-IMB]. + # + # parts:: Returns multiple parts. + # + # param:: Returns a hash that represents parameters as defined in [MIME-IMB]. + # + # disposition:: Returns a Net::IMAP::ContentDisposition object giving + # the content disposition. + # + # language:: Returns a string or an array of strings giving the body + # language value as defined in [LANGUAGE-TAGS]. + # + # extension:: Returns extension data. + # + # multipart?:: Returns true. + # + class BodyTypeMultipart < Struct.new(:media_type, :subtype, + :parts, + :param, :disposition, :language, + :extension) + def multipart? + return true + end + + # Obsolete: use +subtype+ instead. Calling this will + # generate a warning message to +stderr+, then return + # the value of +subtype+. + def media_subtype + $stderr.printf("warning: media_subtype is obsolete.\n") + $stderr.printf(" use subtype instead.\n") + return subtype + end + end + + class ResponseParser # :nodoc: + def parse(str) + @str = str + @pos = 0 + @lex_state = EXPR_BEG + @token = nil + return response + end + + private + + EXPR_BEG = :EXPR_BEG + EXPR_DATA = :EXPR_DATA + EXPR_TEXT = :EXPR_TEXT + EXPR_RTEXT = :EXPR_RTEXT + EXPR_CTEXT = :EXPR_CTEXT + + T_SPACE = :SPACE + T_NIL = :NIL + T_NUMBER = :NUMBER + T_ATOM = :ATOM + T_QUOTED = :QUOTED + T_LPAR = :LPAR + T_RPAR = :RPAR + T_BSLASH = :BSLASH + T_STAR = :STAR + T_LBRA = :LBRA + T_RBRA = :RBRA + T_LITERAL = :LITERAL + T_PLUS = :PLUS + T_PERCENT = :PERCENT + T_CRLF = :CRLF + T_EOF = :EOF + T_TEXT = :TEXT + + BEG_REGEXP = /\G(?:\ +(?# 1: SPACE )( +)|\ +(?# 2: NIL )(NIL)(?=[\x80-\xff(){ \x00-\x1f\x7f%*"\\\[\]+])|\ +(?# 3: NUMBER )(\d+)(?=[\x80-\xff(){ \x00-\x1f\x7f%*"\\\[\]+])|\ +(?# 4: ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\\[\]+]+)|\ +(?# 5: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\ +(?# 6: LPAR )(\()|\ +(?# 7: RPAR )(\))|\ +(?# 8: BSLASH )(\\)|\ +(?# 9: STAR )(\*)|\ +(?# 10: LBRA )(\[)|\ +(?# 11: RBRA )(\])|\ +(?# 12: LITERAL )\{(\d+)\}\r\n|\ +(?# 13: PLUS )(\+)|\ +(?# 14: PERCENT )(%)|\ +(?# 15: CRLF )(\r\n)|\ +(?# 16: EOF )(\z))/ni + + DATA_REGEXP = /\G(?:\ +(?# 1: SPACE )( )|\ +(?# 2: NIL )(NIL)|\ +(?# 3: NUMBER )(\d+)|\ +(?# 4: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\ +(?# 5: LITERAL )\{(\d+)\}\r\n|\ +(?# 6: LPAR )(\()|\ +(?# 7: RPAR )(\)))/ni + + TEXT_REGEXP = /\G(?:\ +(?# 1: TEXT )([^\x00\r\n]*))/ni + + RTEXT_REGEXP = /\G(?:\ +(?# 1: LBRA )(\[)|\ +(?# 2: TEXT )([^\x00\r\n]*))/ni + + CTEXT_REGEXP = /\G(?:\ +(?# 1: TEXT )([^\x00\r\n\]]*))/ni + + Token = Struct.new(:symbol, :value) + + def response + token = lookahead + case token.symbol + when T_PLUS + result = continue_req + when T_STAR + result = response_untagged + else + result = response_tagged + end + match(T_CRLF) + match(T_EOF) + return result + end + + def continue_req + match(T_PLUS) + match(T_SPACE) + return ContinuationRequest.new(resp_text, @str) + end + + def response_untagged + match(T_STAR) + match(T_SPACE) + token = lookahead + if token.symbol == T_NUMBER + return numeric_response + elsif token.symbol == T_ATOM + case token.value + when /\A(?:OK|NO|BAD|BYE|PREAUTH)\z/ni + return response_cond + when /\A(?:FLAGS)\z/ni + return flags_response + when /\A(?:LIST|LSUB)\z/ni + return list_response + when /\A(?:QUOTA)\z/ni + return getquota_response + when /\A(?:QUOTAROOT)\z/ni + return getquotaroot_response + when /\A(?:ACL)\z/ni + return getacl_response + when /\A(?:SEARCH|SORT)\z/ni + return search_response + when /\A(?:THREAD)\z/ni + return thread_response + when /\A(?:STATUS)\z/ni + return status_response + when /\A(?:CAPABILITY)\z/ni + return capability_response + else + return text_response + end + else + parse_error("unexpected token %s", token.symbol) + end + end + + def response_tagged + tag = atom + match(T_SPACE) + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return TaggedResponse.new(tag, name, resp_text, @str) + end + + def response_cond + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return UntaggedResponse.new(name, resp_text, @str) + end + + def numeric_response + n = number + match(T_SPACE) + token = match(T_ATOM) + name = token.value.upcase + case name + when "EXISTS", "RECENT", "EXPUNGE" + return UntaggedResponse.new(name, n, @str) + when "FETCH" + shift_token + match(T_SPACE) + data = FetchData.new(n, msg_att) + return UntaggedResponse.new(name, data, @str) + end + end + + def msg_att + match(T_LPAR) + attr = {} + while true + token = lookahead + case token.symbol + when T_RPAR + shift_token + break + when T_SPACE + shift_token + token = lookahead + end + case token.value + when /\A(?:ENVELOPE)\z/ni + name, val = envelope_data + when /\A(?:FLAGS)\z/ni + name, val = flags_data + when /\A(?:INTERNALDATE)\z/ni + name, val = internaldate_data + when /\A(?:RFC822(?:\.HEADER|\.TEXT)?)\z/ni + name, val = rfc822_text + when /\A(?:RFC822\.SIZE)\z/ni + name, val = rfc822_size + when /\A(?:BODY(?:STRUCTURE)?)\z/ni + name, val = body_data + when /\A(?:UID)\z/ni + name, val = uid_data + else + parse_error("unknown attribute `%s'", token.value) + end + attr[name] = val + end + return attr + end + + def envelope_data + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return name, envelope + end + + def envelope + @lex_state = EXPR_DATA + token = lookahead + if token.symbol == T_NIL + shift_token + result = nil + else + match(T_LPAR) + date = nstring + match(T_SPACE) + subject = nstring + match(T_SPACE) + from = address_list + match(T_SPACE) + sender = address_list + match(T_SPACE) + reply_to = address_list + match(T_SPACE) + to = address_list + match(T_SPACE) + cc = address_list + match(T_SPACE) + bcc = address_list + match(T_SPACE) + in_reply_to = nstring + match(T_SPACE) + message_id = nstring + match(T_RPAR) + result = Envelope.new(date, subject, from, sender, reply_to, + to, cc, bcc, in_reply_to, message_id) + end + @lex_state = EXPR_BEG + return result + end + + def flags_data + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return name, flag_list + end + + def internaldate_data + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + token = match(T_QUOTED) + return name, token.value + end + + def rfc822_text + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return name, nstring + end + + def rfc822_size + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return name, number + end + + def body_data + token = match(T_ATOM) + name = token.value.upcase + token = lookahead + if token.symbol == T_SPACE + shift_token + return name, body + end + name.concat(section) + token = lookahead + if token.symbol == T_ATOM + name.concat(token.value) + shift_token + end + match(T_SPACE) + data = nstring + return name, data + end + + def body + @lex_state = EXPR_DATA + token = lookahead + if token.symbol == T_NIL + shift_token + result = nil + else + match(T_LPAR) + token = lookahead + if token.symbol == T_LPAR + result = body_type_mpart + else + result = body_type_1part + end + match(T_RPAR) + end + @lex_state = EXPR_BEG + return result + end + + def body_type_1part + token = lookahead + case token.value + when /\A(?:TEXT)\z/ni + return body_type_text + when /\A(?:MESSAGE)\z/ni + return body_type_msg + else + return body_type_basic + end + end + + def body_type_basic + mtype, msubtype = media_type + token = lookahead + if token.symbol == T_RPAR + return BodyTypeBasic.new(mtype, msubtype) + end + match(T_SPACE) + param, content_id, desc, enc, size = body_fields + md5, disposition, language, extension = body_ext_1part + return BodyTypeBasic.new(mtype, msubtype, + param, content_id, + desc, enc, size, + md5, disposition, language, extension) + end + + def body_type_text + mtype, msubtype = media_type + match(T_SPACE) + param, content_id, desc, enc, size = body_fields + match(T_SPACE) + lines = number + md5, disposition, language, extension = body_ext_1part + return BodyTypeText.new(mtype, msubtype, + param, content_id, + desc, enc, size, + lines, + md5, disposition, language, extension) + end + + def body_type_msg + mtype, msubtype = media_type + match(T_SPACE) + param, content_id, desc, enc, size = body_fields + match(T_SPACE) + env = envelope + match(T_SPACE) + b = body + match(T_SPACE) + lines = number + md5, disposition, language, extension = body_ext_1part + return BodyTypeMessage.new(mtype, msubtype, + param, content_id, + desc, enc, size, + env, b, lines, + md5, disposition, language, extension) + end + + def body_type_mpart + parts = [] + while true + token = lookahead + if token.symbol == T_SPACE + shift_token + break + end + parts.push(body) + end + mtype = "MULTIPART" + msubtype = case_insensitive_string + param, disposition, language, extension = body_ext_mpart + return BodyTypeMultipart.new(mtype, msubtype, parts, + param, disposition, language, + extension) + end + + def media_type + mtype = case_insensitive_string + match(T_SPACE) + msubtype = case_insensitive_string + return mtype, msubtype + end + + def body_fields + param = body_fld_param + match(T_SPACE) + content_id = nstring + match(T_SPACE) + desc = nstring + match(T_SPACE) + enc = case_insensitive_string + match(T_SPACE) + size = number + return param, content_id, desc, enc, size + end + + def body_fld_param + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + end + match(T_LPAR) + param = {} + while true + token = lookahead + case token.symbol + when T_RPAR + shift_token + break + when T_SPACE + shift_token + end + name = case_insensitive_string + match(T_SPACE) + val = string + param[name] = val + end + return param + end + + def body_ext_1part + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return nil + end + md5 = nstring + + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return md5 + end + disposition = body_fld_dsp + + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return md5, disposition + end + language = body_fld_lang + + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return md5, disposition, language + end + + extension = body_extensions + return md5, disposition, language, extension + end + + def body_ext_mpart + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return nil + end + param = body_fld_param + + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return param + end + disposition = body_fld_dsp + match(T_SPACE) + language = body_fld_lang + + token = lookahead + if token.symbol == T_SPACE + shift_token + else + return param, disposition, language + end + + extension = body_extensions + return param, disposition, language, extension + end + + def body_fld_dsp + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + end + match(T_LPAR) + dsp_type = case_insensitive_string + match(T_SPACE) + param = body_fld_param + match(T_RPAR) + return ContentDisposition.new(dsp_type, param) + end + + def body_fld_lang + token = lookahead + if token.symbol == T_LPAR + shift_token + result = [] + while true + token = lookahead + case token.symbol + when T_RPAR + shift_token + return result + when T_SPACE + shift_token + end + result.push(case_insensitive_string) + end + else + lang = nstring + if lang + return lang.upcase + else + return lang + end + end + end + + def body_extensions + result = [] + while true + token = lookahead + case token.symbol + when T_RPAR + return result + when T_SPACE + shift_token + end + result.push(body_extension) + end + end + + def body_extension + token = lookahead + case token.symbol + when T_LPAR + shift_token + result = body_extensions + match(T_RPAR) + return result + when T_NUMBER + return number + else + return nstring + end + end + + def section + str = "" + token = match(T_LBRA) + str.concat(token.value) + token = match(T_ATOM, T_NUMBER, T_RBRA) + if token.symbol == T_RBRA + str.concat(token.value) + return str + end + str.concat(token.value) + token = lookahead + if token.symbol == T_SPACE + shift_token + str.concat(token.value) + token = match(T_LPAR) + str.concat(token.value) + while true + token = lookahead + case token.symbol + when T_RPAR + str.concat(token.value) + shift_token + break + when T_SPACE + shift_token + str.concat(token.value) + end + str.concat(format_string(astring)) + end + end + token = match(T_RBRA) + str.concat(token.value) + return str + end + + def format_string(str) + case str + when "" + return '""' + when /[\x80-\xff\r\n]/n + # literal + return "{" + str.length.to_s + "}" + CRLF + str + when /[(){ \x00-\x1f\x7f%*"\\]/n + # quoted string + return '"' + str.gsub(/["\\]/n, "\\\\\\&") + '"' + else + # atom + return str + end + end + + def uid_data + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return name, number + end + + def text_response + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + @lex_state = EXPR_TEXT + token = match(T_TEXT) + @lex_state = EXPR_BEG + return UntaggedResponse.new(name, token.value) + end + + def flags_response + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return UntaggedResponse.new(name, flag_list, @str) + end + + def list_response + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + return UntaggedResponse.new(name, mailbox_list, @str) + end + + def mailbox_list + attr = flag_list + match(T_SPACE) + token = match(T_QUOTED, T_NIL) + if token.symbol == T_NIL + delim = nil + else + delim = token.value + end + match(T_SPACE) + name = astring + return MailboxList.new(attr, delim, name) + end + + def getquota_response + # If quota never established, get back + # `NO Quota root does not exist'. + # If quota removed, get `()' after the + # folder spec with no mention of `STORAGE'. + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + mailbox = astring + match(T_SPACE) + match(T_LPAR) + token = lookahead + case token.symbol + when T_RPAR + shift_token + data = MailboxQuota.new(mailbox, nil, nil) + return UntaggedResponse.new(name, data, @str) + when T_ATOM + shift_token + match(T_SPACE) + token = match(T_NUMBER) + usage = token.value + match(T_SPACE) + token = match(T_NUMBER) + quota = token.value + match(T_RPAR) + data = MailboxQuota.new(mailbox, usage, quota) + return UntaggedResponse.new(name, data, @str) + else + parse_error("unexpected token %s", token.symbol) + end + end + + def getquotaroot_response + # Similar to getquota, but only admin can use getquota. + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + mailbox = astring + quotaroots = [] + while true + token = lookahead + break unless token.symbol == T_SPACE + shift_token + quotaroots.push(astring) + end + data = MailboxQuotaRoot.new(mailbox, quotaroots) + return UntaggedResponse.new(name, data, @str) + end + + def getacl_response + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + mailbox = astring + data = [] + token = lookahead + if token.symbol == T_SPACE + shift_token + while true + token = lookahead + case token.symbol + when T_CRLF + break + when T_SPACE + shift_token + end + user = astring + match(T_SPACE) + rights = astring + ##XXX data.push([user, rights]) + data.push(MailboxACLItem.new(user, rights)) + end + end + return UntaggedResponse.new(name, data, @str) + end + + def search_response + token = match(T_ATOM) + name = token.value.upcase + token = lookahead + if token.symbol == T_SPACE + shift_token + data = [] + while true + token = lookahead + case token.symbol + when T_CRLF + break + when T_SPACE + shift_token + end + data.push(number) + end + else + data = [] + end + return UntaggedResponse.new(name, data, @str) + end + + def thread_response + token = match(T_ATOM) + name = token.value.upcase + token = lookahead + + if token.symbol == T_SPACE + threads = [] + + while true + shift_token + token = lookahead + + case token.symbol + when T_LPAR + threads << thread_branch(token) + when T_CRLF + break + end + end + else + # no member + threads = [] + end + + return UntaggedResponse.new(name, threads, @str) + end + + def thread_branch(token) + rootmember = nil + lastmember = nil + + while true + shift_token # ignore first T_LPAR + token = lookahead + + case token.symbol + when T_NUMBER + # new member + newmember = ThreadMember.new(number, []) + if rootmember.nil? + rootmember = newmember + else + lastmember.children << newmember + end + lastmember = newmember + when T_SPACE + # do nothing + when T_LPAR + if rootmember.nil? + # dummy member + lastmember = rootmember = ThreadMember.new(nil, []) + end + + lastmember.children << thread_branch(token) + when T_RPAR + break + end + end + + return rootmember + end + + def status_response + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + mailbox = astring + match(T_SPACE) + match(T_LPAR) + attr = {} + while true + token = lookahead + case token.symbol + when T_RPAR + shift_token + break + when T_SPACE + shift_token + end + token = match(T_ATOM) + key = token.value.upcase + match(T_SPACE) + val = number + attr[key] = val + end + data = StatusData.new(mailbox, attr) + return UntaggedResponse.new(name, data, @str) + end + + def capability_response + token = match(T_ATOM) + name = token.value.upcase + match(T_SPACE) + data = [] + while true + token = lookahead + case token.symbol + when T_CRLF + break + when T_SPACE + shift_token + end + data.push(atom.upcase) + end + return UntaggedResponse.new(name, data, @str) + end + + def resp_text + @lex_state = EXPR_RTEXT + token = lookahead + if token.symbol == T_LBRA + code = resp_text_code + else + code = nil + end + token = match(T_TEXT) + @lex_state = EXPR_BEG + return ResponseText.new(code, token.value) + end + + def resp_text_code + @lex_state = EXPR_BEG + match(T_LBRA) + token = match(T_ATOM) + name = token.value.upcase + case name + when /\A(?:ALERT|PARSE|READ-ONLY|READ-WRITE|TRYCREATE|NOMODSEQ)\z/n + result = ResponseCode.new(name, nil) + when /\A(?:PERMANENTFLAGS)\z/n + match(T_SPACE) + result = ResponseCode.new(name, flag_list) + when /\A(?:UIDVALIDITY|UIDNEXT|UNSEEN)\z/n + match(T_SPACE) + result = ResponseCode.new(name, number) + else + match(T_SPACE) + @lex_state = EXPR_CTEXT + token = match(T_TEXT) + @lex_state = EXPR_BEG + result = ResponseCode.new(name, token.value) + end + match(T_RBRA) + @lex_state = EXPR_RTEXT + return result + end + + def address_list + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + else + result = [] + match(T_LPAR) + while true + token = lookahead + case token.symbol + when T_RPAR + shift_token + break + when T_SPACE + shift_token + end + result.push(address) + end + return result + end + end + + ADDRESS_REGEXP = /\G\ +(?# 1: NAME )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \ +(?# 2: ROUTE )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \ +(?# 3: MAILBOX )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \ +(?# 4: HOST )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)")\ +\)/ni + + def address + match(T_LPAR) + if @str.index(ADDRESS_REGEXP, @pos) + # address does not include literal. + @pos = $~.end(0) + name = $1 + route = $2 + mailbox = $3 + host = $4 + for s in [name, route, mailbox, host] + if s + s.gsub!(/\\(["\\])/n, "\\1") + end + end + else + name = nstring + match(T_SPACE) + route = nstring + match(T_SPACE) + mailbox = nstring + match(T_SPACE) + host = nstring + match(T_RPAR) + end + return Address.new(name, route, mailbox, host) + end + +# def flag_list +# result = [] +# match(T_LPAR) +# while true +# token = lookahead +# case token.symbol +# when T_RPAR +# shift_token +# break +# when T_SPACE +# shift_token +# end +# result.push(flag) +# end +# return result +# end + +# def flag +# token = lookahead +# if token.symbol == T_BSLASH +# shift_token +# token = lookahead +# if token.symbol == T_STAR +# shift_token +# return token.value.intern +# else +# return atom.intern +# end +# else +# return atom +# end +# end + + FLAG_REGEXP = /\ +(?# FLAG )\\([^\x80-\xff(){ \x00-\x1f\x7f%"\\]+)|\ +(?# ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\]+)/n + + def flag_list + if @str.index(/\(([^)]*)\)/ni, @pos) + @pos = $~.end(0) + return $1.scan(FLAG_REGEXP).collect { |flag, atom| + atom || flag.capitalize.intern + } + else + parse_error("invalid flag list") + end + end + + def nstring + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + else + return string + end + end + + def astring + token = lookahead + if string_token?(token) + return string + else + return atom + end + end + + def string + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + end + token = match(T_QUOTED, T_LITERAL) + return token.value + end + + STRING_TOKENS = [T_QUOTED, T_LITERAL, T_NIL] + + def string_token?(token) + return STRING_TOKENS.include?(token.symbol) + end + + def case_insensitive_string + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + end + token = match(T_QUOTED, T_LITERAL) + return token.value.upcase + end + + def atom + result = "" + while true + token = lookahead + if atom_token?(token) + result.concat(token.value) + shift_token + else + if result.empty? + parse_error("unexpected token %s", token.symbol) + else + return result + end + end + end + end + + ATOM_TOKENS = [ + T_ATOM, + T_NUMBER, + T_NIL, + T_LBRA, + T_RBRA, + T_PLUS + ] + + def atom_token?(token) + return ATOM_TOKENS.include?(token.symbol) + end + + def number + token = lookahead + if token.symbol == T_NIL + shift_token + return nil + end + token = match(T_NUMBER) + return token.value.to_i + end + + def nil_atom + match(T_NIL) + return nil + end + + def match(*args) + token = lookahead + unless args.include?(token.symbol) + parse_error('unexpected token %s (expected %s)', + token.symbol.id2name, + args.collect {|i| i.id2name}.join(" or ")) + end + shift_token + return token + end + + def lookahead + unless @token + @token = next_token + end + return @token + end + + def shift_token + @token = nil + end + + def next_token + case @lex_state + when EXPR_BEG + if @str.index(BEG_REGEXP, @pos) + @pos = $~.end(0) + if $1 + return Token.new(T_SPACE, $+) + elsif $2 + return Token.new(T_NIL, $+) + elsif $3 + return Token.new(T_NUMBER, $+) + elsif $4 + return Token.new(T_ATOM, $+) + elsif $5 + return Token.new(T_QUOTED, + $+.gsub(/\\(["\\])/n, "\\1")) + elsif $6 + return Token.new(T_LPAR, $+) + elsif $7 + return Token.new(T_RPAR, $+) + elsif $8 + return Token.new(T_BSLASH, $+) + elsif $9 + return Token.new(T_STAR, $+) + elsif $10 + return Token.new(T_LBRA, $+) + elsif $11 + return Token.new(T_RBRA, $+) + elsif $12 + len = $+.to_i + val = @str[@pos, len] + @pos += len + return Token.new(T_LITERAL, val) + elsif $13 + return Token.new(T_PLUS, $+) + elsif $14 + return Token.new(T_PERCENT, $+) + elsif $15 + return Token.new(T_CRLF, $+) + elsif $16 + return Token.new(T_EOF, $+) + else + parse_error("[Net::IMAP BUG] BEG_REGEXP is invalid") + end + else + @str.index(/\S*/n, @pos) + parse_error("unknown token - %s", $&.dump) + end + when EXPR_DATA + if @str.index(DATA_REGEXP, @pos) + @pos = $~.end(0) + if $1 + return Token.new(T_SPACE, $+) + elsif $2 + return Token.new(T_NIL, $+) + elsif $3 + return Token.new(T_NUMBER, $+) + elsif $4 + return Token.new(T_QUOTED, + $+.gsub(/\\(["\\])/n, "\\1")) + elsif $5 + len = $+.to_i + val = @str[@pos, len] + @pos += len + return Token.new(T_LITERAL, val) + elsif $6 + return Token.new(T_LPAR, $+) + elsif $7 + return Token.new(T_RPAR, $+) + else + parse_error("[Net::IMAP BUG] DATA_REGEXP is invalid") + end + else + @str.index(/\S*/n, @pos) + parse_error("unknown token - %s", $&.dump) + end + when EXPR_TEXT + if @str.index(TEXT_REGEXP, @pos) + @pos = $~.end(0) + if $1 + return Token.new(T_TEXT, $+) + else + parse_error("[Net::IMAP BUG] TEXT_REGEXP is invalid") + end + else + @str.index(/\S*/n, @pos) + parse_error("unknown token - %s", $&.dump) + end + when EXPR_RTEXT + if @str.index(RTEXT_REGEXP, @pos) + @pos = $~.end(0) + if $1 + return Token.new(T_LBRA, $+) + elsif $2 + return Token.new(T_TEXT, $+) + else + parse_error("[Net::IMAP BUG] RTEXT_REGEXP is invalid") + end + else + @str.index(/\S*/n, @pos) + parse_error("unknown token - %s", $&.dump) + end + when EXPR_CTEXT + if @str.index(CTEXT_REGEXP, @pos) + @pos = $~.end(0) + if $1 + return Token.new(T_TEXT, $+) + else + parse_error("[Net::IMAP BUG] CTEXT_REGEXP is invalid") + end + else + @str.index(/\S*/n, @pos) #/ + parse_error("unknown token - %s", $&.dump) + end + else + parse_error("illegal @lex_state - %s", @lex_state.inspect) + end + end + + def parse_error(fmt, *args) + if IMAP.debug + $stderr.printf("@str: %s\n", @str.dump) + $stderr.printf("@pos: %d\n", @pos) + $stderr.printf("@lex_state: %s\n", @lex_state) + if @token + $stderr.printf("@token.symbol: %s\n", @token.symbol) + $stderr.printf("@token.value: %s\n", @token.value.inspect) + end + end + raise ResponseParseError, format(fmt, *args) + end + end + + # Authenticator for the "LOGIN" authentication type. See + # #authenticate(). + class LoginAuthenticator + def process(data) + case @state + when STATE_USER + @state = STATE_PASSWORD + return @user + when STATE_PASSWORD + return @password + end + end + + private + + STATE_USER = :USER + STATE_PASSWORD = :PASSWORD + + def initialize(user, password) + @user = user + @password = password + @state = STATE_USER + end + end + add_authenticator "LOGIN", LoginAuthenticator + + # Authenticator for the "CRAM-MD5" authentication type. See + # #authenticate(). + class CramMD5Authenticator + def process(challenge) + digest = hmac_md5(challenge, @password) + return @user + " " + digest + end + + private + + def initialize(user, password) + @user = user + @password = password + end + + def hmac_md5(text, key) + if key.length > 64 + key = Digest::MD5.digest(key) + end + + k_ipad = key + "\0" * (64 - key.length) + k_opad = key + "\0" * (64 - key.length) + for i in 0..63 + k_ipad[i] ^= 0x36 + k_opad[i] ^= 0x5c + end + + digest = Digest::MD5.digest(k_ipad + text) + + return Digest::MD5.hexdigest(k_opad + digest) + end + end + add_authenticator "CRAM-MD5", CramMD5Authenticator + + # Superclass of IMAP errors. + class Error < StandardError + end + + # Error raised when data is in the incorrect format. + class DataFormatError < Error + end + + # Error raised when a response from the server is non-parseable. + class ResponseParseError < Error + end + + # Superclass of all errors used to encapsulate "fail" responses + # from the server. + class ResponseError < Error + end + + # Error raised upon a "NO" response from the server, indicating + # that the client command could not be completed successfully. + class NoResponseError < ResponseError + end + + # Error raised upon a "BAD" response from the server, indicating + # that the client command violated the IMAP protocol, or an internal + # server failure has occurred. + class BadResponseError < ResponseError + end + + # Error raised upon a "BYE" response from the server, indicating + # that the client is not being allowed to login, or has been timed + # out due to inactivity. + class ByeResponseError < ResponseError + end + end +end + +if __FILE__ == $0 + # :enddoc: + require "getoptlong" + + $stdout.sync = true + $port = nil + $user = ENV["USER"] || ENV["LOGNAME"] + $auth = "login" + $ssl = false + + def usage + $stderr.print < + + --help print this message + --port=PORT specifies port + --user=USER specifies user + --auth=AUTH specifies auth type + --ssl use ssl +EOF + end + + def get_password + print "password: " + system("stty", "-echo") + begin + return gets.chop + ensure + system("stty", "echo") + print "\n" + end + end + + def get_command + printf("%s@%s> ", $user, $host) + if line = gets + return line.strip.split(/\s+/) + else + return nil + end + end + + parser = GetoptLong.new + parser.set_options(['--debug', GetoptLong::NO_ARGUMENT], + ['--help', GetoptLong::NO_ARGUMENT], + ['--port', GetoptLong::REQUIRED_ARGUMENT], + ['--user', GetoptLong::REQUIRED_ARGUMENT], + ['--auth', GetoptLong::REQUIRED_ARGUMENT], + ['--ssl', GetoptLong::NO_ARGUMENT]) + begin + parser.each_option do |name, arg| + case name + when "--port" + $port = arg + when "--user" + $user = arg + when "--auth" + $auth = arg + when "--ssl" + $ssl = true + when "--debug" + Net::IMAP.debug = true + when "--help" + usage + exit(1) + end + end + rescue + usage + exit(1) + end + + $host = ARGV.shift + unless $host + usage + exit(1) + end + $port ||= $ssl ? 993 : 143 + + imap = Net::IMAP.new($host, $port, $ssl) + begin + password = get_password + imap.authenticate($auth, $user, password) + while true + cmd, *args = get_command + break unless cmd + begin + case cmd + when "list" + for mbox in imap.list("", args[0] || "*") + if mbox.attr.include?(Net::IMAP::NOSELECT) + prefix = "!" + elsif mbox.attr.include?(Net::IMAP::MARKED) + prefix = "*" + else + prefix = " " + end + print prefix, mbox.name, "\n" + end + when "select" + imap.select(args[0] || "inbox") + print "ok\n" + when "close" + imap.close + print "ok\n" + when "summary" + unless messages = imap.responses["EXISTS"][-1] + puts "not selected" + next + end + if messages > 0 + for data in imap.fetch(1..-1, ["ENVELOPE"]) + print data.seqno, ": ", data.attr["ENVELOPE"].subject, "\n" + end + else + puts "no message" + end + when "fetch" + if args[0] + data = imap.fetch(args[0].to_i, ["RFC822.HEADER", "RFC822.TEXT"])[0] + puts data.attr["RFC822.HEADER"] + puts data.attr["RFC822.TEXT"] + else + puts "missing argument" + end + when "logout", "exit", "quit" + break + when "help", "?" + print <. +# +# Documented by William Webber and Minero Aoki. +# +# This program is free software. You can re-distribute and/or +# modify this program under the same terms as Ruby itself, +# Ruby Distribute License or GNU General Public License. +# +# NOTE: You can find Japanese version of this document in +# the doc/net directory of the standard ruby interpreter package. +# +# $Id: pop.rb 17230 2008-06-15 12:27:56Z shyouhei $ +# +# See Net::POP3 for documentation. +# + +require 'net/protocol' +require 'digest/md5' + +module Net + + # Non-authentication POP3 protocol error + # (reply code "-ERR", except authentication). + class POPError < ProtocolError; end + + # POP3 authentication error. + class POPAuthenticationError < ProtoAuthError; end + + # Unexpected response from the server. + class POPBadResponse < POPError; end + + # + # = Net::POP3 + # + # == What is This Library? + # + # This library provides functionality for retrieving + # email via POP3, the Post Office Protocol version 3. For details + # of POP3, see [RFC1939] (http://www.ietf.org/rfc/rfc1939.txt). + # + # == Examples + # + # === Retrieving Messages + # + # This example retrieves messages from the server and deletes them + # on the server. + # + # Messages are written to files named 'inbox/1', 'inbox/2', .... + # Replace 'pop.example.com' with your POP3 server address, and + # 'YourAccount' and 'YourPassword' with the appropriate account + # details. + # + # require 'net/pop' + # + # pop = Net::POP3.new('pop.example.com') + # pop.start('YourAccount', 'YourPassword') # (1) + # if pop.mails.empty? + # puts 'No mail.' + # else + # i = 0 + # pop.each_mail do |m| # or "pop.mails.each ..." # (2) + # File.open("inbox/#{i}", 'w') do |f| + # f.write m.pop + # end + # m.delete + # i += 1 + # end + # puts "#{pop.mails.size} mails popped." + # end + # pop.finish # (3) + # + # 1. Call Net::POP3#start and start POP session. + # 2. Access messages by using POP3#each_mail and/or POP3#mails. + # 3. Close POP session by calling POP3#finish or use the block form of #start. + # + # === Shortened Code + # + # The example above is very verbose. You can shorten the code by using + # some utility methods. First, the block form of Net::POP3.start can + # be used instead of POP3.new, POP3#start and POP3#finish. + # + # require 'net/pop' + # + # Net::POP3.start('pop.example.com', 110, + # 'YourAccount', 'YourPassword') do |pop| + # if pop.mails.empty? + # puts 'No mail.' + # else + # i = 0 + # pop.each_mail do |m| # or "pop.mails.each ..." + # File.open("inbox/#{i}", 'w') do |f| + # f.write m.pop + # end + # m.delete + # i += 1 + # end + # puts "#{pop.mails.size} mails popped." + # end + # end + # + # POP3#delete_all is an alternative for #each_mail and #delete. + # + # require 'net/pop' + # + # Net::POP3.start('pop.example.com', 110, + # 'YourAccount', 'YourPassword') do |pop| + # if pop.mails.empty? + # puts 'No mail.' + # else + # i = 1 + # pop.delete_all do |m| + # File.open("inbox/#{i}", 'w') do |f| + # f.write m.pop + # end + # i += 1 + # end + # end + # end + # + # And here is an even shorter example. + # + # require 'net/pop' + # + # i = 0 + # Net::POP3.delete_all('pop.example.com', 110, + # 'YourAccount', 'YourPassword') do |m| + # File.open("inbox/#{i}", 'w') do |f| + # f.write m.pop + # end + # i += 1 + # end + # + # === Memory Space Issues + # + # All the examples above get each message as one big string. + # This example avoids this. + # + # require 'net/pop' + # + # i = 1 + # Net::POP3.delete_all('pop.example.com', 110, + # 'YourAccount', 'YourPassword') do |m| + # File.open("inbox/#{i}", 'w') do |f| + # m.pop do |chunk| # get a message little by little. + # f.write chunk + # end + # i += 1 + # end + # end + # + # === Using APOP + # + # The net/pop library supports APOP authentication. + # To use APOP, use the Net::APOP class instead of the Net::POP3 class. + # You can use the utility method, Net::POP3.APOP(). For example: + # + # require 'net/pop' + # + # # Use APOP authentication if $isapop == true + # pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110) + # pop.start(YourAccount', 'YourPassword') do |pop| + # # Rest of the code is the same. + # end + # + # === Fetch Only Selected Mail Using 'UIDL' POP Command + # + # If your POP server provides UIDL functionality, + # you can grab only selected mails from the POP server. + # e.g. + # + # def need_pop?( id ) + # # determine if we need pop this mail... + # end + # + # Net::POP3.start('pop.example.com', 110, + # 'Your account', 'Your password') do |pop| + # pop.mails.select { |m| need_pop?(m.unique_id) }.each do |m| + # do_something(m.pop) + # end + # end + # + # The POPMail#unique_id() method returns the unique-id of the message as a + # String. Normally the unique-id is a hash of the message. + # + class POP3 < Protocol + + Revision = %q$Revision: 17230 $.split[1] + + # + # Class Parameters + # + + # The default port for POP3 connections, port 110 + def POP3.default_port + 110 + end + + def POP3.socket_type #:nodoc: obsolete + Net::InternetMessageIO + end + + # + # Utilities + # + + # Returns the APOP class if +isapop+ is true; otherwise, returns + # the POP class. For example: + # + # # Example 1 + # pop = Net::POP3::APOP($is_apop).new(addr, port) + # + # # Example 2 + # Net::POP3::APOP($is_apop).start(addr, port) do |pop| + # .... + # end + # + def POP3.APOP( isapop ) + isapop ? APOP : POP3 + end + + # Starts a POP3 session and iterates over each POPMail object, + # yielding it to the +block+. + # This method is equivalent to: + # + # Net::POP3.start(address, port, account, password) do |pop| + # pop.each_mail do |m| + # yield m + # end + # end + # + # This method raises a POPAuthenticationError if authentication fails. + # + # === Example + # + # Net::POP3.foreach('pop.example.com', 110, + # 'YourAccount', 'YourPassword') do |m| + # file.write m.pop + # m.delete if $DELETE + # end + # + def POP3.foreach( address, port = nil, + account = nil, password = nil, + isapop = false, &block ) # :yields: message + start(address, port, account, password, isapop) {|pop| + pop.each_mail(&block) + } + end + + # Starts a POP3 session and deletes all messages on the server. + # If a block is given, each POPMail object is yielded to it before + # being deleted. + # + # This method raises a POPAuthenticationError if authentication fails. + # + # === Example + # + # Net::POP3.delete_all('pop.example.com', 110, + # 'YourAccount', 'YourPassword') do |m| + # file.write m.pop + # end + # + def POP3.delete_all( address, port = nil, + account = nil, password = nil, + isapop = false, &block ) + start(address, port, account, password, isapop) {|pop| + pop.delete_all(&block) + } + end + + # Opens a POP3 session, attempts authentication, and quits. + # + # This method raises POPAuthenticationError if authentication fails. + # + # === Example: normal POP3 + # + # Net::POP3.auth_only('pop.example.com', 110, + # 'YourAccount', 'YourPassword') + # + # === Example: APOP + # + # Net::POP3.auth_only('pop.example.com', 110, + # 'YourAccount', 'YourPassword', true) + # + def POP3.auth_only( address, port = nil, + account = nil, password = nil, + isapop = false ) + new(address, port, isapop).auth_only account, password + end + + # Starts a pop3 session, attempts authentication, and quits. + # This method must not be called while POP3 session is opened. + # This method raises POPAuthenticationError if authentication fails. + def auth_only( account, password ) + raise IOError, 'opening previously opened POP session' if started? + start(account, password) { + ; + } + end + + # + # Session management + # + + # Creates a new POP3 object and open the connection. Equivalent to + # + # Net::POP3.new(address, port, isapop).start(account, password) + # + # If +block+ is provided, yields the newly-opened POP3 object to it, + # and automatically closes it at the end of the session. + # + # === Example + # + # Net::POP3.start(addr, port, account, password) do |pop| + # pop.each_mail do |m| + # file.write m.pop + # m.delete + # end + # end + # + def POP3.start( address, port = nil, + account = nil, password = nil, + isapop = false, &block ) # :yield: pop + new(address, port, isapop).start(account, password, &block) + end + + # Creates a new POP3 object. + # + # +address+ is the hostname or ip address of your POP3 server. + # + # The optional +port+ is the port to connect to; it defaults to 110. + # + # The optional +isapop+ specifies whether this connection is going + # to use APOP authentication; it defaults to +false+. + # + # This method does *not* open the TCP connection. + def initialize( addr, port = nil, isapop = false ) + @address = addr + @port = port || self.class.default_port + @apop = isapop + + @command = nil + @socket = nil + @started = false + @open_timeout = 30 + @read_timeout = 60 + @debug_output = nil + + @mails = nil + @n_mails = nil + @n_bytes = nil + end + + # Does this instance use APOP authentication? + def apop? + @apop + end + + # Provide human-readable stringification of class state. + def inspect + "#<#{self.class} #{@address}:#{@port} open=#{@started}>" + end + + # *WARNING*: This method causes a serious security hole. + # Use this method only for debugging. + # + # Set an output stream for debugging. + # + # === Example + # + # pop = Net::POP.new(addr, port) + # pop.set_debug_output $stderr + # pop.start(account, passwd) do |pop| + # .... + # end + # + def set_debug_output( arg ) + @debug_output = arg + end + + # The address to connect to. + attr_reader :address + + # The port number to connect to. + attr_reader :port + + # Seconds to wait until a connection is opened. + # If the POP3 object cannot open a connection within this time, + # it raises a TimeoutError exception. + attr_accessor :open_timeout + + # Seconds to wait until reading one block (by one read(1) call). + # If the POP3 object cannot complete a read() within this time, + # it raises a TimeoutError exception. + attr_reader :read_timeout + + # Set the read timeout. + def read_timeout=( sec ) + @command.socket.read_timeout = sec if @command + @read_timeout = sec + end + + # +true+ if the POP3 session has started. + def started? + @started + end + + alias active? started? #:nodoc: obsolete + + # Starts a POP3 session. + # + # When called with block, gives a POP3 object to the block and + # closes the session after block call finishes. + # + # This method raises a POPAuthenticationError if authentication fails. + def start( account, password ) # :yield: pop + raise IOError, 'POP session already started' if @started + + if block_given? + begin + do_start account, password + return yield(self) + ensure + do_finish + end + else + do_start account, password + return self + end + end + + def do_start( account, password ) + @socket = self.class.socket_type.old_open(@address, @port, + @open_timeout, @read_timeout, @debug_output) + on_connect + @command = POP3Command.new(@socket) + if apop? + @command.apop account, password + else + @command.auth account, password + end + @started = true + ensure + do_finish if not @started + end + private :do_start + + def on_connect + end + private :on_connect + + # Finishes a POP3 session and closes TCP connection. + def finish + raise IOError, 'POP session not yet started' unless started? + do_finish + end + + def do_finish + @mails = nil + @n_mails = nil + @n_bytes = nil + @command.quit if @command + ensure + @started = false + @command = nil + @socket.close if @socket and not @socket.closed? + @socket = nil + end + private :do_finish + + def command + raise IOError, 'POP session not opened yet' \ + if not @socket or @socket.closed? + @command + end + private :command + + # + # POP protocol wrapper + # + + # Returns the number of messages on the POP server. + def n_mails + return @n_mails if @n_mails + @n_mails, @n_bytes = command().stat + @n_mails + end + + # Returns the total size in bytes of all the messages on the POP server. + def n_bytes + return @n_bytes if @n_bytes + @n_mails, @n_bytes = command().stat + @n_bytes + end + + # Returns an array of Net::POPMail objects, representing all the + # messages on the server. This array is renewed when the session + # restarts; otherwise, it is fetched from the server the first time + # this method is called (directly or indirectly) and cached. + # + # This method raises a POPError if an error occurs. + def mails + return @mails.dup if @mails + if n_mails() == 0 + # some popd raises error for LIST on the empty mailbox. + @mails = [] + return [] + end + + @mails = command().list.map {|num, size| + POPMail.new(num, size, self, command()) + } + @mails.dup + end + + # Yields each message to the passed-in block in turn. + # Equivalent to: + # + # pop3.mails.each do |popmail| + # .... + # end + # + # This method raises a POPError if an error occurs. + def each_mail( &block ) # :yield: message + mails().each(&block) + end + + alias each each_mail + + # Deletes all messages on the server. + # + # If called with a block, yields each message in turn before deleting it. + # + # === Example + # + # n = 1 + # pop.delete_all do |m| + # File.open("inbox/#{n}") do |f| + # f.write m.pop + # end + # n += 1 + # end + # + # This method raises a POPError if an error occurs. + # + def delete_all # :yield: message + mails().each do |m| + yield m if block_given? + m.delete unless m.deleted? + end + end + + # Resets the session. This clears all "deleted" marks from messages. + # + # This method raises a POPError if an error occurs. + def reset + command().rset + mails().each do |m| + m.instance_eval { + @deleted = false + } + end + end + + def set_all_uids #:nodoc: internal use only (called from POPMail#uidl) + command().uidl.each do |num, uid| + @mails.find {|m| m.number == num }.uid = uid + end + end + + end # class POP3 + + # class aliases + POP = POP3 + POPSession = POP3 + POP3Session = POP3 + + # + # This class is equivalent to POP3, except that it uses APOP authentication. + # + class APOP < POP3 + # Always returns true. + def apop? + true + end + end + + # class aliases + APOPSession = APOP + + # + # This class represents a message which exists on the POP server. + # Instances of this class are created by the POP3 class; they should + # not be directly created by the user. + # + class POPMail + + def initialize( num, len, pop, cmd ) #:nodoc: + @number = num + @length = len + @pop = pop + @command = cmd + @deleted = false + @uid = nil + end + + # The sequence number of the message on the server. + attr_reader :number + + # The length of the message in octets. + attr_reader :length + alias size length + + # Provide human-readable stringification of class state. + def inspect + "#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>" + end + + # + # This method fetches the message. If called with a block, the + # message is yielded to the block one chunk at a time. If called + # without a block, the message is returned as a String. The optional + # +dest+ argument will be prepended to the returned String; this + # argument is essentially obsolete. + # + # === Example without block + # + # POP3.start('pop.example.com', 110, + # 'YourAccount, 'YourPassword') do |pop| + # n = 1 + # pop.mails.each do |popmail| + # File.open("inbox/#{n}", 'w') do |f| + # f.write popmail.pop + # end + # popmail.delete + # n += 1 + # end + # end + # + # === Example with block + # + # POP3.start('pop.example.com', 110, + # 'YourAccount, 'YourPassword') do |pop| + # n = 1 + # pop.mails.each do |popmail| + # File.open("inbox/#{n}", 'w') do |f| + # popmail.pop do |chunk| #### + # f.write chunk + # end + # end + # n += 1 + # end + # end + # + # This method raises a POPError if an error occurs. + # + def pop( dest = '', &block ) # :yield: message_chunk + if block_given? + @command.retr(@number, &block) + nil + else + @command.retr(@number) do |chunk| + dest << chunk + end + dest + end + end + + alias all pop #:nodoc: obsolete + alias mail pop #:nodoc: obsolete + + # Fetches the message header and +lines+ lines of body. + # + # The optional +dest+ argument is obsolete. + # + # This method raises a POPError if an error occurs. + def top( lines, dest = '' ) + @command.top(@number, lines) do |chunk| + dest << chunk + end + dest + end + + # Fetches the message header. + # + # The optional +dest+ argument is obsolete. + # + # This method raises a POPError if an error occurs. + def header( dest = '' ) + top(0, dest) + end + + # Marks a message for deletion on the server. Deletion does not + # actually occur until the end of the session; deletion may be + # cancelled for _all_ marked messages by calling POP3#reset(). + # + # This method raises a POPError if an error occurs. + # + # === Example + # + # POP3.start('pop.example.com', 110, + # 'YourAccount, 'YourPassword') do |pop| + # n = 1 + # pop.mails.each do |popmail| + # File.open("inbox/#{n}", 'w') do |f| + # f.write popmail.pop + # end + # popmail.delete #### + # n += 1 + # end + # end + # + def delete + @command.dele @number + @deleted = true + end + + alias delete! delete #:nodoc: obsolete + + # True if the mail has been deleted. + def deleted? + @deleted + end + + # Returns the unique-id of the message. + # Normally the unique-id is a hash string of the message. + # + # This method raises a POPError if an error occurs. + def unique_id + return @uid if @uid + @pop.set_all_uids + @uid + end + + alias uidl unique_id + + def uid=( uid ) #:nodoc: internal use only (used from POP3#set_all_uids) + @uid = uid + end + + end # class POPMail + + + class POP3Command #:nodoc: internal use only + + def initialize( sock ) + @socket = sock + @error_occured = false + res = check_response(critical { recv_response() }) + @apop_stamp = res.slice(/<.+>/) + end + + def inspect + "#<#{self.class} socket=#{@socket}>" + end + + def auth( account, password ) + check_response_auth(critical { + check_response_auth(get_response('USER %s', account)) + get_response('PASS %s', password) + }) + end + + def apop( account, password ) + raise POPAuthenticationError, 'not APOP server; cannot login' \ + unless @apop_stamp + check_response_auth(critical { + get_response('APOP %s %s', + account, + Digest::MD5.hexdigest(@apop_stamp + password)) + }) + end + + def list + critical { + getok 'LIST' + list = [] + @socket.each_list_item do |line| + m = /\A(\d+)[ \t]+(\d+)/.match(line) or + raise POPBadResponse, "bad response: #{line}" + list.push [m[1].to_i, m[2].to_i] + end + return list + } + end + + def stat + res = check_response(critical { get_response('STAT') }) + m = /\A\+OK\s+(\d+)\s+(\d+)/.match(res) or + raise POPBadResponse, "wrong response format: #{res}" + [m[1].to_i, m[2].to_i] + end + + def rset + check_response(critical { get_response 'RSET' }) + end + + def top( num, lines = 0, &block ) + critical { + getok('TOP %d %d', num, lines) + @socket.each_message_chunk(&block) + } + end + + def retr( num, &block ) + critical { + getok('RETR %d', num) + @socket.each_message_chunk(&block) + } + end + + def dele( num ) + check_response(critical { get_response('DELE %d', num) }) + end + + def uidl( num = nil ) + if num + res = check_response(critical { get_response('UIDL %d', num) }) + return res.split(/ /)[1] + else + critical { + getok('UIDL') + table = {} + @socket.each_list_item do |line| + num, uid = line.split + table[num.to_i] = uid + end + return table + } + end + end + + def quit + check_response(critical { get_response('QUIT') }) + end + + private + + def getok( fmt, *fargs ) + @socket.writeline sprintf(fmt, *fargs) + check_response(recv_response()) + end + + def get_response( fmt, *fargs ) + @socket.writeline sprintf(fmt, *fargs) + recv_response() + end + + def recv_response + @socket.readline + end + + def check_response( res ) + raise POPError, res unless /\A\+OK/i === res + res + end + + def check_response_auth( res ) + raise POPAuthenticationError, res unless /\A\+OK/i === res + res + end + + def critical + return '+OK dummy ok response' if @error_occured + begin + return yield() + rescue Exception + @error_occured = true + raise + end + end + + end # class POP3Command + +end # module Net + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/protocol.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/protocol.rb new file mode 100644 index 00000000..b8980300 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/protocol.rb @@ -0,0 +1,390 @@ +# +# = net/protocol.rb +# +#-- +# Copyright (c) 1999-2005 Yukihiro Matsumoto +# Copyright (c) 1999-2005 Minero Aoki +# +# written and maintained by Minero Aoki +# +# This program is free software. You can re-distribute and/or +# modify this program under the same terms as Ruby itself, +# Ruby Distribute License or GNU General Public License. +# +# $Id: protocol.rb 11708 2007-02-12 23:01:19Z shyouhei $ +#++ +# +# WARNING: This file is going to remove. +# Do not rely on the implementation written in this file. +# + +require 'socket' +require 'timeout' + +module Net # :nodoc: + + class Protocol #:nodoc: internal use only + private + def Protocol.protocol_param(name, val) + module_eval(<<-End, __FILE__, __LINE__ + 1) + def #{name} + #{val} + end + End + end + end + + + class ProtocolError < StandardError; end + class ProtoSyntaxError < ProtocolError; end + class ProtoFatalError < ProtocolError; end + class ProtoUnknownError < ProtocolError; end + class ProtoServerError < ProtocolError; end + class ProtoAuthError < ProtocolError; end + class ProtoCommandError < ProtocolError; end + class ProtoRetriableError < ProtocolError; end + ProtocRetryError = ProtoRetriableError + + + class BufferedIO #:nodoc: internal use only + def initialize(io) + @io = io + @read_timeout = 60 + @debug_output = nil + @rbuf = '' + end + + attr_reader :io + attr_accessor :read_timeout + attr_accessor :debug_output + + def inspect + "#<#{self.class} io=#{@io}>" + end + + def closed? + @io.closed? + end + + def close + @io.close + end + + # + # Read + # + + public + + def read(len, dest = '', ignore_eof = false) + LOG "reading #{len} bytes..." + read_bytes = 0 + begin + while read_bytes + @rbuf.size < len + dest << (s = rbuf_consume(@rbuf.size)) + read_bytes += s.size + rbuf_fill + end + dest << (s = rbuf_consume(len - read_bytes)) + read_bytes += s.size + rescue EOFError + raise unless ignore_eof + end + LOG "read #{read_bytes} bytes" + dest + end + + def read_all(dest = '') + LOG 'reading all...' + read_bytes = 0 + begin + while true + dest << (s = rbuf_consume(@rbuf.size)) + read_bytes += s.size + rbuf_fill + end + rescue EOFError + ; + end + LOG "read #{read_bytes} bytes" + dest + end + + def readuntil(terminator, ignore_eof = false) + begin + until idx = @rbuf.index(terminator) + rbuf_fill + end + return rbuf_consume(idx + terminator.size) + rescue EOFError + raise unless ignore_eof + return rbuf_consume(@rbuf.size) + end + end + + def readline + readuntil("\n").chop + end + + private + + def rbuf_fill + timeout(@read_timeout) { + @rbuf << @io.sysread(1024) + } + end + + def rbuf_consume(len) + s = @rbuf.slice!(0, len) + @debug_output << %Q[-> #{s.dump}\n] if @debug_output + s + end + + # + # Write + # + + public + + def write(str) + writing { + write0 str + } + end + + def writeline(str) + writing { + write0 str + "\r\n" + } + end + + private + + def writing + @written_bytes = 0 + @debug_output << '<- ' if @debug_output + yield + @debug_output << "\n" if @debug_output + bytes = @written_bytes + @written_bytes = nil + bytes + end + + def write0(str) + @debug_output << str.dump if @debug_output + len = @io.write(str) + @written_bytes += len + len + end + + # + # Logging + # + + private + + def LOG_off + @save_debug_out = @debug_output + @debug_output = nil + end + + def LOG_on + @debug_output = @save_debug_out + end + + def LOG(msg) + return unless @debug_output + @debug_output << msg + "\n" + end + end + + + class InternetMessageIO < BufferedIO #:nodoc: internal use only + def InternetMessageIO.old_open(addr, port, + open_timeout = nil, read_timeout = nil, debug_output = nil) + debug_output << "opening connection to #{addr}...\n" if debug_output + s = timeout(open_timeout) { TCPsocket.new(addr, port) } + io = new(s) + io.read_timeout = read_timeout + io.debug_output = debug_output + io + end + + def initialize(io) + super + @wbuf = nil + end + + # + # Read + # + + def each_message_chunk + LOG 'reading message...' + LOG_off() + read_bytes = 0 + while (line = readuntil("\r\n")) != ".\r\n" + read_bytes += line.size + yield line.sub(/\A\./, '') + end + LOG_on() + LOG "read message (#{read_bytes} bytes)" + end + + # *library private* (cannot handle 'break') + def each_list_item + while (str = readuntil("\r\n")) != ".\r\n" + yield str.chop + end + end + + def write_message_0(src) + prev = @written_bytes + each_crlf_line(src) do |line| + write0 line.sub(/\A\./, '..') + end + @written_bytes - prev + end + + # + # Write + # + + def write_message(src) + LOG "writing message from #{src.class}" + LOG_off() + len = writing { + using_each_crlf_line { + write_message_0 src + } + } + LOG_on() + LOG "wrote #{len} bytes" + len + end + + def write_message_by_block(&block) + LOG 'writing message from block' + LOG_off() + len = writing { + using_each_crlf_line { + begin + block.call(WriteAdapter.new(self, :write_message_0)) + rescue LocalJumpError + # allow `break' from writer block + end + } + } + LOG_on() + LOG "wrote #{len} bytes" + len + end + + private + + def using_each_crlf_line + @wbuf = '' + yield + if not @wbuf.empty? # unterminated last line + write0 @wbuf.chomp + "\r\n" + elsif @written_bytes == 0 # empty src + write0 "\r\n" + end + write0 ".\r\n" + @wbuf = nil + end + + def each_crlf_line(src) + buffer_filling(@wbuf, src) do + while line = @wbuf.slice!(/\A.*(?:\n|\r\n|\r(?!\z))/n) + yield line.chomp("\n") + "\r\n" + end + end + end + + def buffer_filling(buf, src) + case src + when String # for speeding up. + 0.step(src.size - 1, 1024) do |i| + buf << src[i, 1024] + yield + end + when File # for speeding up. + while s = src.read(1024) + buf << s + yield + end + else # generic reader + src.each do |s| + buf << s + yield if buf.size > 1024 + end + yield unless buf.empty? + end + end + end + + + # + # The writer adapter class + # + class WriteAdapter + def initialize(socket, method) + @socket = socket + @method_id = method + end + + def inspect + "#<#{self.class} socket=#{@socket.inspect}>" + end + + def write(str) + @socket.__send__(@method_id, str) + end + + alias print write + + def <<(str) + write str + self + end + + def puts(str = '') + write str.chomp("\n") + "\n" + end + + def printf(*args) + write sprintf(*args) + end + end + + + class ReadAdapter #:nodoc: internal use only + def initialize(block) + @block = block + end + + def inspect + "#<#{self.class}>" + end + + def <<(str) + call_block(str, &@block) if @block + end + + private + + # This method is needed because @block must be called by yield, + # not Proc#call. You can see difference when using `break' in + # the block. + def call_block(str) + yield str + end + end + + + module NetPrivate #:nodoc: obsolete + Socket = ::Net::InternetMessageIO + end + +end # module Net diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/smtp.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/smtp.rb new file mode 100644 index 00000000..b667af3e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/smtp.rb @@ -0,0 +1,696 @@ +# = net/smtp.rb +# +# Copyright (c) 1999-2003 Yukihiro Matsumoto. +# +# Copyright (c) 1999-2003 Minero Aoki. +# +# Written & maintained by Minero Aoki . +# +# Documented by William Webber and Minero Aoki. +# +# This program is free software. You can re-distribute and/or +# modify this program under the same terms as Ruby itself, +# Ruby Distribute License or GNU General Public License. +# +# NOTE: You can find Japanese version of this document in +# the doc/net directory of the standard ruby interpreter package. +# +# $Id: smtp.rb 18116 2008-07-17 12:40:40Z shyouhei $ +# +# See Net::SMTP for documentation. +# + +require 'net/protocol' +require 'digest/md5' + +module Net + + # Module mixed in to all SMTP error classes + module SMTPError + # This *class* is module for some reason. + # In ruby 1.9.x, this module becomes a class. + end + + # Represents an SMTP authentication error. + class SMTPAuthenticationError < ProtoAuthError + include SMTPError + end + + # Represents SMTP error code 420 or 450, a temporary error. + class SMTPServerBusy < ProtoServerError + include SMTPError + end + + # Represents an SMTP command syntax error (error code 500) + class SMTPSyntaxError < ProtoSyntaxError + include SMTPError + end + + # Represents a fatal SMTP error (error code 5xx, except for 500) + class SMTPFatalError < ProtoFatalError + include SMTPError + end + + # Unexpected reply code returned from server. + class SMTPUnknownError < ProtoUnknownError + include SMTPError + end + + # + # = Net::SMTP + # + # == What is This Library? + # + # This library provides functionality to send internet + # mail via SMTP, the Simple Mail Transfer Protocol. For details of + # SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt). + # + # == What is This Library NOT? + # + # This library does NOT provide functions to compose internet mails. + # You must create them by yourself. If you want better mail support, + # try RubyMail or TMail. You can get both libraries from RAA. + # (http://www.ruby-lang.org/en/raa.html) + # + # FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt). + # + # == Examples + # + # === Sending Messages + # + # You must open a connection to an SMTP server before sending messages. + # The first argument is the address of your SMTP server, and the second + # argument is the port number. Using SMTP.start with a block is the simplest + # way to do this. This way, the SMTP connection is closed automatically + # after the block is executed. + # + # require 'net/smtp' + # Net::SMTP.start('your.smtp.server', 25) do |smtp| + # # Use the SMTP object smtp only in this block. + # end + # + # Replace 'your.smtp.server' with your SMTP server. Normally + # your system manager or internet provider supplies a server + # for you. + # + # Then you can send messages. + # + # msgstr = < + # To: Destination Address + # Subject: test message + # Date: Sat, 23 Jun 2001 16:26:43 +0900 + # Message-Id: + # + # This is a test message. + # END_OF_MESSAGE + # + # require 'net/smtp' + # Net::SMTP.start('your.smtp.server', 25) do |smtp| + # smtp.send_message msgstr, + # 'your@mail.address', + # 'his_addess@example.com' + # end + # + # === Closing the Session + # + # You MUST close the SMTP session after sending messages, by calling + # the #finish method: + # + # # using SMTP#finish + # smtp = Net::SMTP.start('your.smtp.server', 25) + # smtp.send_message msgstr, 'from@address', 'to@address' + # smtp.finish + # + # You can also use the block form of SMTP.start/SMTP#start. This closes + # the SMTP session automatically: + # + # # using block form of SMTP.start + # Net::SMTP.start('your.smtp.server', 25) do |smtp| + # smtp.send_message msgstr, 'from@address', 'to@address' + # end + # + # I strongly recommend this scheme. This form is simpler and more robust. + # + # === HELO domain + # + # In almost all situations, you must provide a third argument + # to SMTP.start/SMTP#start. This is the domain name which you are on + # (the host to send mail from). It is called the "HELO domain". + # The SMTP server will judge whether it should send or reject + # the SMTP session by inspecting the HELO domain. + # + # Net::SMTP.start('your.smtp.server', 25, + # 'mail.from.domain') { |smtp| ... } + # + # === SMTP Authentication + # + # The Net::SMTP class supports three authentication schemes; + # PLAIN, LOGIN and CRAM MD5. (SMTP Authentication: [RFC2554]) + # To use SMTP authentication, pass extra arguments to + # SMTP.start/SMTP#start. + # + # # PLAIN + # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain', + # 'Your Account', 'Your Password', :plain) + # # LOGIN + # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain', + # 'Your Account', 'Your Password', :login) + # + # # CRAM MD5 + # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain', + # 'Your Account', 'Your Password', :cram_md5) + # + class SMTP + + Revision = %q$Revision: 18116 $.split[1] + + # The default SMTP port, port 25. + def SMTP.default_port + 25 + end + + # + # Creates a new Net::SMTP object. + # + # +address+ is the hostname or ip address of your SMTP + # server. +port+ is the port to connect to; it defaults to + # port 25. + # + # This method does not open the TCP connection. You can use + # SMTP.start instead of SMTP.new if you want to do everything + # at once. Otherwise, follow SMTP.new with SMTP#start. + # + def initialize( address, port = nil ) + @address = address + @port = (port || SMTP.default_port) + @esmtp = true + @socket = nil + @started = false + @open_timeout = 30 + @read_timeout = 60 + @error_occured = false + @debug_output = nil + end + + # Provide human-readable stringification of class state. + def inspect + "#<#{self.class} #{@address}:#{@port} started=#{@started}>" + end + + # +true+ if the SMTP object uses ESMTP (which it does by default). + def esmtp? + @esmtp + end + + # + # Set whether to use ESMTP or not. This should be done before + # calling #start. Note that if #start is called in ESMTP mode, + # and the connection fails due to a ProtocolError, the SMTP + # object will automatically switch to plain SMTP mode and + # retry (but not vice versa). + # + def esmtp=( bool ) + @esmtp = bool + end + + alias esmtp esmtp? + + # The address of the SMTP server to connect to. + attr_reader :address + + # The port number of the SMTP server to connect to. + attr_reader :port + + # Seconds to wait while attempting to open a connection. + # If the connection cannot be opened within this time, a + # TimeoutError is raised. + attr_accessor :open_timeout + + # Seconds to wait while reading one block (by one read(2) call). + # If the read(2) call does not complete within this time, a + # TimeoutError is raised. + attr_reader :read_timeout + + # Set the number of seconds to wait until timing-out a read(2) + # call. + def read_timeout=( sec ) + @socket.read_timeout = sec if @socket + @read_timeout = sec + end + + # + # WARNING: This method causes serious security holes. + # Use this method for only debugging. + # + # Set an output stream for debug logging. + # You must call this before #start. + # + # # example + # smtp = Net::SMTP.new(addr, port) + # smtp.set_debug_output $stderr + # smtp.start do |smtp| + # .... + # end + # + def set_debug_output( arg ) + @debug_output = arg + end + + # + # SMTP session control + # + + # + # Creates a new Net::SMTP object and connects to the server. + # + # This method is equivalent to: + # + # Net::SMTP.new(address, port).start(helo_domain, account, password, authtype) + # + # === Example + # + # Net::SMTP.start('your.smtp.server') do |smtp| + # smtp.send_message msgstr, 'from@example.com', ['dest@example.com'] + # end + # + # === Block Usage + # + # If called with a block, the newly-opened Net::SMTP object is yielded + # to the block, and automatically closed when the block finishes. If called + # without a block, the newly-opened Net::SMTP object is returned to + # the caller, and it is the caller's responsibility to close it when + # finished. + # + # === Parameters + # + # +address+ is the hostname or ip address of your smtp server. + # + # +port+ is the port to connect to; it defaults to port 25. + # + # +helo+ is the _HELO_ _domain_ provided by the client to the + # server (see overview comments); it defaults to 'localhost.localdomain'. + # + # The remaining arguments are used for SMTP authentication, if required + # or desired. +user+ is the account name; +secret+ is your password + # or other authentication token; and +authtype+ is the authentication + # type, one of :plain, :login, or :cram_md5. See the discussion of + # SMTP Authentication in the overview notes. + # + # === Errors + # + # This method may raise: + # + # * Net::SMTPAuthenticationError + # * Net::SMTPServerBusy + # * Net::SMTPSyntaxError + # * Net::SMTPFatalError + # * Net::SMTPUnknownError + # * IOError + # * TimeoutError + # + def SMTP.start(address, port = nil, helo = 'localhost.localdomain', + user = nil, secret = nil, authtype = nil, + &block) # :yield: smtp + new(address, port).start(helo, user, secret, authtype, &block) + end + + # +true+ if the SMTP session has been started. + def started? + @started + end + + # + # Opens a TCP connection and starts the SMTP session. + # + # === Parameters + # + # +helo+ is the _HELO_ _domain_ that you'll dispatch mails from; see + # the discussion in the overview notes. + # + # If both of +user+ and +secret+ are given, SMTP authentication + # will be attempted using the AUTH command. +authtype+ specifies + # the type of authentication to attempt; it must be one of + # :login, :plain, and :cram_md5. See the notes on SMTP Authentication + # in the overview. + # + # === Block Usage + # + # When this methods is called with a block, the newly-started SMTP + # object is yielded to the block, and automatically closed after + # the block call finishes. Otherwise, it is the caller's + # responsibility to close the session when finished. + # + # === Example + # + # This is very similar to the class method SMTP.start. + # + # require 'net/smtp' + # smtp = Net::SMTP.new('smtp.mail.server', 25) + # smtp.start(helo_domain, account, password, authtype) do |smtp| + # smtp.send_message msgstr, 'from@example.com', ['dest@example.com'] + # end + # + # The primary use of this method (as opposed to SMTP.start) + # is probably to set debugging (#set_debug_output) or ESMTP + # (#esmtp=), which must be done before the session is + # started. + # + # === Errors + # + # If session has already been started, an IOError will be raised. + # + # This method may raise: + # + # * Net::SMTPAuthenticationError + # * Net::SMTPServerBusy + # * Net::SMTPSyntaxError + # * Net::SMTPFatalError + # * Net::SMTPUnknownError + # * IOError + # * TimeoutError + # + def start(helo = 'localhost.localdomain', + user = nil, secret = nil, authtype = nil) # :yield: smtp + if block_given? + begin + do_start(helo, user, secret, authtype) + return yield(self) + ensure + do_finish + end + else + do_start(helo, user, secret, authtype) + return self + end + end + + def do_start( helodomain, user, secret, authtype ) + raise IOError, 'SMTP session already started' if @started + check_auth_args user, secret, authtype if user or secret + + @socket = InternetMessageIO.old_open(@address, @port, + @open_timeout, @read_timeout, + @debug_output) + check_response(critical { recv_response() }) + begin + if @esmtp + ehlo helodomain + else + helo helodomain + end + rescue ProtocolError + if @esmtp + @esmtp = false + @error_occured = false + retry + end + raise + end + authenticate user, secret, authtype if user + @started = true + ensure + @socket.close if not @started and @socket and not @socket.closed? + end + private :do_start + + # Finishes the SMTP session and closes TCP connection. + # Raises IOError if not started. + def finish + raise IOError, 'not yet started' unless started? + do_finish + end + + def do_finish + quit if @socket and not @socket.closed? and not @error_occured + ensure + @started = false + @error_occured = false + @socket.close if @socket and not @socket.closed? + @socket = nil + end + private :do_finish + + # + # message send + # + + public + + # + # Sends +msgstr+ as a message. Single CR ("\r") and LF ("\n") found + # in the +msgstr+, are converted into the CR LF pair. You cannot send a + # binary message with this method. +msgstr+ should include both + # the message headers and body. + # + # +from_addr+ is a String representing the source mail address. + # + # +to_addr+ is a String or Strings or Array of Strings, representing + # the destination mail address or addresses. + # + # === Example + # + # Net::SMTP.start('smtp.example.com') do |smtp| + # smtp.send_message msgstr, + # 'from@example.com', + # ['dest@example.com', 'dest2@example.com'] + # end + # + # === Errors + # + # This method may raise: + # + # * Net::SMTPServerBusy + # * Net::SMTPSyntaxError + # * Net::SMTPFatalError + # * Net::SMTPUnknownError + # * IOError + # * TimeoutError + # + def send_message( msgstr, from_addr, *to_addrs ) + send0(from_addr, to_addrs.flatten) { + @socket.write_message msgstr + } + end + + alias send_mail send_message + alias sendmail send_message # obsolete + + # + # Opens a message writer stream and gives it to the block. + # The stream is valid only in the block, and has these methods: + # + # puts(str = ''):: outputs STR and CR LF. + # print(str):: outputs STR. + # printf(fmt, *args):: outputs sprintf(fmt,*args). + # write(str):: outputs STR and returns the length of written bytes. + # <<(str):: outputs STR and returns self. + # + # If a single CR ("\r") or LF ("\n") is found in the message, + # it is converted to the CR LF pair. You cannot send a binary + # message with this method. + # + # === Parameters + # + # +from_addr+ is a String representing the source mail address. + # + # +to_addr+ is a String or Strings or Array of Strings, representing + # the destination mail address or addresses. + # + # === Example + # + # Net::SMTP.start('smtp.example.com', 25) do |smtp| + # smtp.open_message_stream('from@example.com', ['dest@example.com']) do |f| + # f.puts 'From: from@example.com' + # f.puts 'To: dest@example.com' + # f.puts 'Subject: test message' + # f.puts + # f.puts 'This is a test message.' + # end + # end + # + # === Errors + # + # This method may raise: + # + # * Net::SMTPServerBusy + # * Net::SMTPSyntaxError + # * Net::SMTPFatalError + # * Net::SMTPUnknownError + # * IOError + # * TimeoutError + # + def open_message_stream( from_addr, *to_addrs, &block ) # :yield: stream + send0(from_addr, to_addrs.flatten) { + @socket.write_message_by_block(&block) + } + end + + alias ready open_message_stream # obsolete + + private + + def send0( from_addr, to_addrs ) + raise IOError, 'closed session' unless @socket + raise ArgumentError, 'mail destination not given' if to_addrs.empty? + if $SAFE > 0 + raise SecurityError, 'tainted from_addr' if from_addr.tainted? + to_addrs.each do |to| + raise SecurityError, 'tainted to_addr' if to.tainted? + end + end + + mailfrom from_addr + to_addrs.each do |to| + rcptto to + end + res = critical { + check_response(get_response('DATA'), true) + yield + recv_response() + } + check_response(res) + end + + # + # auth + # + + private + + def check_auth_args( user, secret, authtype ) + raise ArgumentError, 'both user and secret are required'\ + unless user and secret + auth_method = "auth_#{authtype || 'cram_md5'}" + raise ArgumentError, "wrong auth type #{authtype}"\ + unless respond_to?(auth_method, true) + end + + def authenticate( user, secret, authtype ) + __send__("auth_#{authtype || 'cram_md5'}", user, secret) + end + + def auth_plain( user, secret ) + res = critical { get_response('AUTH PLAIN %s', + base64_encode("\0#{user}\0#{secret}")) } + raise SMTPAuthenticationError, res unless /\A2../ === res + end + + def auth_login( user, secret ) + res = critical { + check_response(get_response('AUTH LOGIN'), true) + check_response(get_response(base64_encode(user)), true) + get_response(base64_encode(secret)) + } + raise SMTPAuthenticationError, res unless /\A2../ === res + end + + def auth_cram_md5( user, secret ) + # CRAM-MD5: [RFC2195] + res = nil + critical { + res = check_response(get_response('AUTH CRAM-MD5'), true) + challenge = res.split(/ /)[1].unpack('m')[0] + secret = Digest::MD5.digest(secret) if secret.size > 64 + + isecret = secret + "\0" * (64 - secret.size) + osecret = isecret.dup + 0.upto(63) do |i| + isecret[i] ^= 0x36 + osecret[i] ^= 0x5c + end + tmp = Digest::MD5.digest(isecret + challenge) + tmp = Digest::MD5.hexdigest(osecret + tmp) + + res = get_response(base64_encode(user + ' ' + tmp)) + } + raise SMTPAuthenticationError, res unless /\A2../ === res + end + + def base64_encode( str ) + # expects "str" may not become too long + [str].pack('m').gsub(/\s+/, '') + end + + # + # SMTP command dispatcher + # + + private + + def helo( domain ) + getok('HELO %s', domain) + end + + def ehlo( domain ) + getok('EHLO %s', domain) + end + + def mailfrom( fromaddr ) + getok('MAIL FROM:<%s>', fromaddr) + end + + def rcptto( to ) + getok('RCPT TO:<%s>', to) + end + + def quit + getok('QUIT') + end + + # + # row level library + # + + private + + def getok( fmt, *args ) + res = critical { + @socket.writeline sprintf(fmt, *args) + recv_response() + } + return check_response(res) + end + + def get_response( fmt, *args ) + @socket.writeline sprintf(fmt, *args) + recv_response() + end + + def recv_response + res = '' + while true + line = @socket.readline + res << line << "\n" + break unless line[3] == ?- # "210-PIPELINING" + end + res + end + + def check_response( res, allow_continue = false ) + return res if /\A2/ === res + return res if allow_continue and /\A3/ === res + err = case res + when /\A4/ then SMTPServerBusy + when /\A50/ then SMTPSyntaxError + when /\A55/ then SMTPFatalError + else SMTPUnknownError + end + raise err, res + end + + def critical( &block ) + return '200 dummy reply code' if @error_occured + begin + return yield() + rescue Exception + @error_occured = true + raise + end + end + + end # class SMTP + + SMTPSession = SMTP + +end # module Net diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/telnet.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/telnet.rb new file mode 100644 index 00000000..1fe464c2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/telnet.rb @@ -0,0 +1,749 @@ +# = net/telnet.rb - Simple Telnet Client Library +# +# Author:: Wakou Aoyama +# Documentation:: William Webber and Wakou Aoyama +# +# This file holds the class Net::Telnet, which provides client-side +# telnet functionality. +# +# For documentation, see Net::Telnet. +# + +require "socket" +require "delegate" +require "timeout" +require "English" + +module Net + + # + # == Net::Telnet + # + # Provides telnet client functionality. + # + # This class also has, through delegation, all the methods of a + # socket object (by default, a +TCPSocket+, but can be set by the + # +Proxy+ option to new()). This provides methods such as + # close() to end the session and sysread() to read + # data directly from the host, instead of via the waitfor() + # mechanism. Note that if you do use sysread() directly + # when in telnet mode, you should probably pass the output through + # preprocess() to extract telnet command sequences. + # + # == Overview + # + # The telnet protocol allows a client to login remotely to a user + # account on a server and execute commands via a shell. The equivalent + # is done by creating a Net::Telnet class with the +Host+ option + # set to your host, calling #login() with your user and password, + # issuing one or more #cmd() calls, and then calling #close() + # to end the session. The #waitfor(), #print(), #puts(), and + # #write() methods, which #cmd() is implemented on top of, are + # only needed if you are doing something more complicated. + # + # A Net::Telnet object can also be used to connect to non-telnet + # services, such as SMTP or HTTP. In this case, you normally + # want to provide the +Port+ option to specify the port to + # connect to, and set the +Telnetmode+ option to false to prevent + # the client from attempting to interpret telnet command sequences. + # Generally, #login() will not work with other protocols, and you + # have to handle authentication yourself. + # + # For some protocols, it will be possible to specify the +Prompt+ + # option once when you create the Telnet object and use #cmd() calls; + # for others, you will have to specify the response sequence to + # look for as the Match option to every #cmd() call, or call + # #puts() and #waitfor() directly; for yet others, you will have + # to use #sysread() instead of #waitfor() and parse server + # responses yourself. + # + # It is worth noting that when you create a new Net::Telnet object, + # you can supply a proxy IO channel via the Proxy option. This + # can be used to attach the Telnet object to other Telnet objects, + # to already open sockets, or to any read-write IO object. This + # can be useful, for instance, for setting up a test fixture for + # unit testing. + # + # == Examples + # + # === Log in and send a command, echoing all output to stdout + # + # localhost = Net::Telnet::new("Host" => "localhost", + # "Timeout" => 10, + # "Prompt" => /[$%#>] \z/n) + # localhost.login("username", "password") { |c| print c } + # localhost.cmd("command") { |c| print c } + # localhost.close + # + # + # === Check a POP server to see if you have mail + # + # pop = Net::Telnet::new("Host" => "your_destination_host_here", + # "Port" => 110, + # "Telnetmode" => false, + # "Prompt" => /^\+OK/n) + # pop.cmd("user " + "your_username_here") { |c| print c } + # pop.cmd("pass " + "your_password_here") { |c| print c } + # pop.cmd("list") { |c| print c } + # + # == References + # + # There are a large number of RFCs relevant to the Telnet protocol. + # RFCs 854-861 define the base protocol. For a complete listing + # of relevant RFCs, see + # http://www.omnifarious.org/~hopper/technical/telnet-rfc.html + # + class Telnet < SimpleDelegator + + # :stopdoc: + IAC = 255.chr # "\377" # "\xff" # interpret as command + DONT = 254.chr # "\376" # "\xfe" # you are not to use option + DO = 253.chr # "\375" # "\xfd" # please, you use option + WONT = 252.chr # "\374" # "\xfc" # I won't use option + WILL = 251.chr # "\373" # "\xfb" # I will use option + SB = 250.chr # "\372" # "\xfa" # interpret as subnegotiation + GA = 249.chr # "\371" # "\xf9" # you may reverse the line + EL = 248.chr # "\370" # "\xf8" # erase the current line + EC = 247.chr # "\367" # "\xf7" # erase the current character + AYT = 246.chr # "\366" # "\xf6" # are you there + AO = 245.chr # "\365" # "\xf5" # abort output--but let prog finish + IP = 244.chr # "\364" # "\xf4" # interrupt process--permanently + BREAK = 243.chr # "\363" # "\xf3" # break + DM = 242.chr # "\362" # "\xf2" # data mark--for connect. cleaning + NOP = 241.chr # "\361" # "\xf1" # nop + SE = 240.chr # "\360" # "\xf0" # end sub negotiation + EOR = 239.chr # "\357" # "\xef" # end of record (transparent mode) + ABORT = 238.chr # "\356" # "\xee" # Abort process + SUSP = 237.chr # "\355" # "\xed" # Suspend process + EOF = 236.chr # "\354" # "\xec" # End of file + SYNCH = 242.chr # "\362" # "\xf2" # for telfunc calls + + OPT_BINARY = 0.chr # "\000" # "\x00" # Binary Transmission + OPT_ECHO = 1.chr # "\001" # "\x01" # Echo + OPT_RCP = 2.chr # "\002" # "\x02" # Reconnection + OPT_SGA = 3.chr # "\003" # "\x03" # Suppress Go Ahead + OPT_NAMS = 4.chr # "\004" # "\x04" # Approx Message Size Negotiation + OPT_STATUS = 5.chr # "\005" # "\x05" # Status + OPT_TM = 6.chr # "\006" # "\x06" # Timing Mark + OPT_RCTE = 7.chr # "\a" # "\x07" # Remote Controlled Trans and Echo + OPT_NAOL = 8.chr # "\010" # "\x08" # Output Line Width + OPT_NAOP = 9.chr # "\t" # "\x09" # Output Page Size + OPT_NAOCRD = 10.chr # "\n" # "\x0a" # Output Carriage-Return Disposition + OPT_NAOHTS = 11.chr # "\v" # "\x0b" # Output Horizontal Tab Stops + OPT_NAOHTD = 12.chr # "\f" # "\x0c" # Output Horizontal Tab Disposition + OPT_NAOFFD = 13.chr # "\r" # "\x0d" # Output Formfeed Disposition + OPT_NAOVTS = 14.chr # "\016" # "\x0e" # Output Vertical Tabstops + OPT_NAOVTD = 15.chr # "\017" # "\x0f" # Output Vertical Tab Disposition + OPT_NAOLFD = 16.chr # "\020" # "\x10" # Output Linefeed Disposition + OPT_XASCII = 17.chr # "\021" # "\x11" # Extended ASCII + OPT_LOGOUT = 18.chr # "\022" # "\x12" # Logout + OPT_BM = 19.chr # "\023" # "\x13" # Byte Macro + OPT_DET = 20.chr # "\024" # "\x14" # Data Entry Terminal + OPT_SUPDUP = 21.chr # "\025" # "\x15" # SUPDUP + OPT_SUPDUPOUTPUT = 22.chr # "\026" # "\x16" # SUPDUP Output + OPT_SNDLOC = 23.chr # "\027" # "\x17" # Send Location + OPT_TTYPE = 24.chr # "\030" # "\x18" # Terminal Type + OPT_EOR = 25.chr # "\031" # "\x19" # End of Record + OPT_TUID = 26.chr # "\032" # "\x1a" # TACACS User Identification + OPT_OUTMRK = 27.chr # "\e" # "\x1b" # Output Marking + OPT_TTYLOC = 28.chr # "\034" # "\x1c" # Terminal Location Number + OPT_3270REGIME = 29.chr # "\035" # "\x1d" # Telnet 3270 Regime + OPT_X3PAD = 30.chr # "\036" # "\x1e" # X.3 PAD + OPT_NAWS = 31.chr # "\037" # "\x1f" # Negotiate About Window Size + OPT_TSPEED = 32.chr # " " # "\x20" # Terminal Speed + OPT_LFLOW = 33.chr # "!" # "\x21" # Remote Flow Control + OPT_LINEMODE = 34.chr # "\"" # "\x22" # Linemode + OPT_XDISPLOC = 35.chr # "#" # "\x23" # X Display Location + OPT_OLD_ENVIRON = 36.chr # "$" # "\x24" # Environment Option + OPT_AUTHENTICATION = 37.chr # "%" # "\x25" # Authentication Option + OPT_ENCRYPT = 38.chr # "&" # "\x26" # Encryption Option + OPT_NEW_ENVIRON = 39.chr # "'" # "\x27" # New Environment Option + OPT_EXOPL = 255.chr # "\377" # "\xff" # Extended-Options-List + + NULL = "\000" + CR = "\015" + LF = "\012" + EOL = CR + LF + REVISION = '$Id: telnet.rb 17270 2008-06-15 13:34:40Z shyouhei $' + # :startdoc: + + # + # Creates a new Net::Telnet object. + # + # Attempts to connect to the host (unless the Proxy option is + # provided: see below). If a block is provided, it is yielded + # status messages on the attempt to connect to the server, of + # the form: + # + # Trying localhost... + # Connected to localhost. + # + # +options+ is a hash of options. The following example lists + # all options and their default values. + # + # host = Net::Telnet::new( + # "Host" => "localhost", # default: "localhost" + # "Port" => 23, # default: 23 + # "Binmode" => false, # default: false + # "Output_log" => "output_log", # default: nil (no output) + # "Dump_log" => "dump_log", # default: nil (no output) + # "Prompt" => /[$%#>] \z/n, # default: /[$%#>] \z/n + # "Telnetmode" => true, # default: true + # "Timeout" => 10, # default: 10 + # # if ignore timeout then set "Timeout" to false. + # "Waittime" => 0, # default: 0 + # "Proxy" => proxy # default: nil + # # proxy is Net::Telnet or IO object + # ) + # + # The options have the following meanings: + # + # Host:: the hostname or IP address of the host to connect to, as a String. + # Defaults to "localhost". + # + # Port:: the port to connect to. Defaults to 23. + # + # Binmode:: if false (the default), newline substitution is performed. + # Outgoing LF is + # converted to CRLF, and incoming CRLF is converted to LF. If + # true, this substitution is not performed. This value can + # also be set with the #binmode() method. The + # outgoing conversion only applies to the #puts() and #print() + # methods, not the #write() method. The precise nature of + # the newline conversion is also affected by the telnet options + # SGA and BIN. + # + # Output_log:: the name of the file to write connection status messages + # and all received traffic to. In the case of a proper + # Telnet session, this will include the client input as + # echoed by the host; otherwise, it only includes server + # responses. Output is appended verbatim to this file. + # By default, no output log is kept. + # + # Dump_log:: as for Output_log, except that output is written in hexdump + # format (16 bytes per line as hex pairs, followed by their + # printable equivalent), with connection status messages + # preceded by '#', sent traffic preceded by '>', and + # received traffic preceded by '<'. By default, not dump log + # is kept. + # + # Prompt:: a regular expression matching the host's command-line prompt + # sequence. This is needed by the Telnet class to determine + # when the output from a command has finished and the host is + # ready to receive a new command. By default, this regular + # expression is /[$%#>] \z/n. + # + # Telnetmode:: a boolean value, true by default. In telnet mode, + # traffic received from the host is parsed for special + # command sequences, and these sequences are escaped + # in outgoing traffic sent using #puts() or #print() + # (but not #write()). If you are using the Net::Telnet + # object to connect to a non-telnet service (such as + # SMTP or POP), this should be set to "false" to prevent + # undesired data corruption. This value can also be set + # by the #telnetmode() method. + # + # Timeout:: the number of seconds to wait before timing out both the + # initial attempt to connect to host (in this constructor), + # and all attempts to read data from the host (in #waitfor(), + # #cmd(), and #login()). Exceeding this timeout causes a + # TimeoutError to be raised. The default value is 10 seconds. + # You can disable the timeout by setting this value to false. + # In this case, the connect attempt will eventually timeout + # on the underlying connect(2) socket call with an + # Errno::ETIMEDOUT error (but generally only after a few + # minutes), but other attempts to read data from the host + # will hand indefinitely if no data is forthcoming. + # + # Waittime:: the amount of time to wait after seeing what looks like a + # prompt (that is, received data that matches the Prompt + # option regular expression) to see if more data arrives. + # If more data does arrive in this time, Net::Telnet assumes + # that what it saw was not really a prompt. This is to try to + # avoid false matches, but it can also lead to missing real + # prompts (if, for instance, a background process writes to + # the terminal soon after the prompt is displayed). By + # default, set to 0, meaning not to wait for more data. + # + # Proxy:: a proxy object to used instead of opening a direct connection + # to the host. Must be either another Net::Telnet object or + # an IO object. If it is another Net::Telnet object, this + # instance will use that one's socket for communication. If an + # IO object, it is used directly for communication. Any other + # kind of object will cause an error to be raised. + # + def initialize(options) # :yield: mesg + @options = options + @options["Host"] = "localhost" unless @options.has_key?("Host") + @options["Port"] = 23 unless @options.has_key?("Port") + @options["Prompt"] = /[$%#>] \z/n unless @options.has_key?("Prompt") + @options["Timeout"] = 10 unless @options.has_key?("Timeout") + @options["Waittime"] = 0 unless @options.has_key?("Waittime") + unless @options.has_key?("Binmode") + @options["Binmode"] = false + else + unless (true == @options["Binmode"] or false == @options["Binmode"]) + raise ArgumentError, "Binmode option must be true or false" + end + end + + unless @options.has_key?("Telnetmode") + @options["Telnetmode"] = true + else + unless (true == @options["Telnetmode"] or false == @options["Telnetmode"]) + raise ArgumentError, "Telnetmode option must be true or false" + end + end + + @telnet_option = { "SGA" => false, "BINARY" => false } + + if @options.has_key?("Output_log") + @log = File.open(@options["Output_log"], 'a+') + @log.sync = true + @log.binmode + end + + if @options.has_key?("Dump_log") + @dumplog = File.open(@options["Dump_log"], 'a+') + @dumplog.sync = true + @dumplog.binmode + def @dumplog.log_dump(dir, x) # :nodoc: + len = x.length + addr = 0 + offset = 0 + while 0 < len + if len < 16 + line = x[offset, len] + else + line = x[offset, 16] + end + hexvals = line.unpack('H*')[0] + hexvals += ' ' * (32 - hexvals.length) + hexvals = format("%s %s %s %s " * 4, *hexvals.unpack('a2' * 16)) + line = line.gsub(/[\000-\037\177-\377]/n, '.') + printf "%s 0x%5.5x: %s%s\n", dir, addr, hexvals, line + addr += 16 + offset += 16 + len -= 16 + end + print "\n" + end + end + + if @options.has_key?("Proxy") + if @options["Proxy"].kind_of?(Net::Telnet) + @sock = @options["Proxy"].sock + elsif @options["Proxy"].kind_of?(IO) + @sock = @options["Proxy"] + else + raise "Error: Proxy must be an instance of Net::Telnet or IO." + end + else + message = "Trying " + @options["Host"] + "...\n" + yield(message) if block_given? + @log.write(message) if @options.has_key?("Output_log") + @dumplog.log_dump('#', message) if @options.has_key?("Dump_log") + + begin + if @options["Timeout"] == false + @sock = TCPSocket.open(@options["Host"], @options["Port"]) + else + timeout(@options["Timeout"]) do + @sock = TCPSocket.open(@options["Host"], @options["Port"]) + end + end + rescue TimeoutError + raise TimeoutError, "timed out while opening a connection to the host" + rescue + @log.write($ERROR_INFO.to_s + "\n") if @options.has_key?("Output_log") + @dumplog.log_dump('#', $ERROR_INFO.to_s + "\n") if @options.has_key?("Dump_log") + raise + end + @sock.sync = true + @sock.binmode + + message = "Connected to " + @options["Host"] + ".\n" + yield(message) if block_given? + @log.write(message) if @options.has_key?("Output_log") + @dumplog.log_dump('#', message) if @options.has_key?("Dump_log") + end + + super(@sock) + end # initialize + + # The socket the Telnet object is using. Note that this object becomes + # a delegate of the Telnet object, so normally you invoke its methods + # directly on the Telnet object. + attr :sock + + # Set telnet command interpretation on (+mode+ == true) or off + # (+mode+ == false), or return the current value (+mode+ not + # provided). It should be on for true telnet sessions, off if + # using Net::Telnet to connect to a non-telnet service such + # as SMTP. + def telnetmode(mode = nil) + case mode + when nil + @options["Telnetmode"] + when true, false + @options["Telnetmode"] = mode + else + raise ArgumentError, "argument must be true or false, or missing" + end + end + + # Turn telnet command interpretation on (true) or off (false). It + # should be on for true telnet sessions, off if using Net::Telnet + # to connect to a non-telnet service such as SMTP. + def telnetmode=(mode) + if (true == mode or false == mode) + @options["Telnetmode"] = mode + else + raise ArgumentError, "argument must be true or false" + end + end + + # Turn newline conversion on (+mode+ == false) or off (+mode+ == true), + # or return the current value (+mode+ is not specified). + def binmode(mode = nil) + case mode + when nil + @options["Binmode"] + when true, false + @options["Binmode"] = mode + else + raise ArgumentError, "argument must be true or false" + end + end + + # Turn newline conversion on (false) or off (true). + def binmode=(mode) + if (true == mode or false == mode) + @options["Binmode"] = mode + else + raise ArgumentError, "argument must be true or false" + end + end + + # Preprocess received data from the host. + # + # Performs newline conversion and detects telnet command sequences. + # Called automatically by #waitfor(). You should only use this + # method yourself if you have read input directly using sysread() + # or similar, and even then only if in telnet mode. + def preprocess(string) + # combine CR+NULL into CR + string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"] + + # combine EOL into "\n" + string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"] + + string.gsub(/#{IAC}( + [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]| + [#{DO}#{DONT}#{WILL}#{WONT}] + [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]| + #{SB}[^#{IAC}]*#{IAC}#{SE} + )/xno) do + if IAC == $1 # handle escaped IAC characters + IAC + elsif AYT == $1 # respond to "IAC AYT" (are you there) + self.write("nobody here but us pigeons" + EOL) + '' + elsif DO[0] == $1[0] # respond to "IAC DO x" + if OPT_BINARY[0] == $1[1] + @telnet_option["BINARY"] = true + self.write(IAC + WILL + OPT_BINARY) + else + self.write(IAC + WONT + $1[1..1]) + end + '' + elsif DONT[0] == $1[0] # respond to "IAC DON'T x" with "IAC WON'T x" + self.write(IAC + WONT + $1[1..1]) + '' + elsif WILL[0] == $1[0] # respond to "IAC WILL x" + if OPT_BINARY[0] == $1[1] + self.write(IAC + DO + OPT_BINARY) + elsif OPT_ECHO[0] == $1[1] + self.write(IAC + DO + OPT_ECHO) + elsif OPT_SGA[0] == $1[1] + @telnet_option["SGA"] = true + self.write(IAC + DO + OPT_SGA) + else + self.write(IAC + DONT + $1[1..1]) + end + '' + elsif WONT[0] == $1[0] # respond to "IAC WON'T x" + if OPT_ECHO[0] == $1[1] + self.write(IAC + DONT + OPT_ECHO) + elsif OPT_SGA[0] == $1[1] + @telnet_option["SGA"] = false + self.write(IAC + DONT + OPT_SGA) + else + self.write(IAC + DONT + $1[1..1]) + end + '' + else + '' + end + end + end # preprocess + + # Read data from the host until a certain sequence is matched. + # + # If a block is given, the received data will be yielded as it + # is read in (not necessarily all in one go), or nil if EOF + # occurs before any data is received. Whether a block is given + # or not, all data read will be returned in a single string, or again + # nil if EOF occurs before any data is received. Note that + # received data includes the matched sequence we were looking for. + # + # +options+ can be either a regular expression or a hash of options. + # If a regular expression, this specifies the data to wait for. + # If a hash, this can specify the following options: + # + # Match:: a regular expression, specifying the data to wait for. + # Prompt:: as for Match; used only if Match is not specified. + # String:: as for Match, except a string that will be converted + # into a regular expression. Used only if Match and + # Prompt are not specified. + # Timeout:: the number of seconds to wait for data from the host + # before raising a TimeoutError. If set to false, + # no timeout will occur. If not specified, the + # Timeout option value specified when this instance + # was created will be used, or, failing that, the + # default value of 10 seconds. + # Waittime:: the number of seconds to wait after matching against + # the input data to see if more data arrives. If more + # data arrives within this time, we will judge ourselves + # not to have matched successfully, and will continue + # trying to match. If not specified, the Waittime option + # value specified when this instance was created will be + # used, or, failing that, the default value of 0 seconds, + # which means not to wait for more input. + # + def waitfor(options) # :yield: recvdata + time_out = @options["Timeout"] + waittime = @options["Waittime"] + + if options.kind_of?(Hash) + prompt = if options.has_key?("Match") + options["Match"] + elsif options.has_key?("Prompt") + options["Prompt"] + elsif options.has_key?("String") + Regexp.new( Regexp.quote(options["String"]) ) + end + time_out = options["Timeout"] if options.has_key?("Timeout") + waittime = options["Waittime"] if options.has_key?("Waittime") + else + prompt = options + end + + if time_out == false + time_out = nil + end + + line = '' + buf = '' + rest = '' + until(prompt === line and not IO::select([@sock], nil, nil, waittime)) + unless IO::select([@sock], nil, nil, time_out) + raise TimeoutError, "timed out while waiting for more data" + end + begin + c = @sock.readpartial(1024 * 1024) + @dumplog.log_dump('<', c) if @options.has_key?("Dump_log") + if @options["Telnetmode"] + c = rest + c + if Integer(c.rindex(/#{IAC}#{SE}/no)) < + Integer(c.rindex(/#{IAC}#{SB}/no)) + buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)]) + rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1] + elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) || + c.rindex(/\r\z/no) + buf = preprocess(c[0 ... pt]) + rest = c[pt .. -1] + else + buf = preprocess(c) + rest = '' + end + else + # Not Telnetmode. + # + # We cannot use preprocess() on this data, because that + # method makes some Telnetmode-specific assumptions. + buf = rest + c + rest = '' + unless @options["Binmode"] + if pt = buf.rindex(/\r\z/no) + buf = buf[0 ... pt] + rest = buf[pt .. -1] + end + buf.gsub!(/#{EOL}/no, "\n") + end + end + @log.print(buf) if @options.has_key?("Output_log") + line += buf + yield buf if block_given? + rescue EOFError # End of file reached + if line == '' + line = nil + yield nil if block_given? + end + break + end + end + line + end + + # Write +string+ to the host. + # + # Does not perform any conversions on +string+. Will log +string+ to the + # dumplog, if the Dump_log option is set. + def write(string) + length = string.length + while 0 < length + IO::select(nil, [@sock]) + @dumplog.log_dump('>', string[-length..-1]) if @options.has_key?("Dump_log") + length -= @sock.syswrite(string[-length..-1]) + end + end + + # Sends a string to the host. + # + # This does _not_ automatically append a newline to the string. Embedded + # newlines may be converted and telnet command sequences escaped + # depending upon the values of telnetmode, binmode, and telnet options + # set by the host. + def print(string) + string = string.gsub(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"] + + if @options["Binmode"] + self.write(string) + else + if @telnet_option["BINARY"] and @telnet_option["SGA"] + # IAC WILL SGA IAC DO BIN send EOL --> CR + self.write(string.gsub(/\n/n, CR)) + elsif @telnet_option["SGA"] + # IAC WILL SGA send EOL --> CR+NULL + self.write(string.gsub(/\n/n, CR + NULL)) + else + # NONE send EOL --> CR+LF + self.write(string.gsub(/\n/n, EOL)) + end + end + end + + # Sends a string to the host. + # + # Same as #print(), but appends a newline to the string. + def puts(string) + self.print(string + "\n") + end + + # Send a command to the host. + # + # More exactly, sends a string to the host, and reads in all received + # data until is sees the prompt or other matched sequence. + # + # If a block is given, the received data will be yielded to it as + # it is read in. Whether a block is given or not, the received data + # will be return as a string. Note that the received data includes + # the prompt and in most cases the host's echo of our command. + # + # +options+ is either a String, specified the string or command to + # send to the host; or it is a hash of options. If a hash, the + # following options can be specified: + # + # String:: the command or other string to send to the host. + # Match:: a regular expression, the sequence to look for in + # the received data before returning. If not specified, + # the Prompt option value specified when this instance + # was created will be used, or, failing that, the default + # prompt of /[$%#>] \z/n. + # Timeout:: the seconds to wait for data from the host before raising + # a Timeout error. If not specified, the Timeout option + # value specified when this instance was created will be + # used, or, failing that, the default value of 10 seconds. + # + # The command or other string will have the newline sequence appended + # to it. + def cmd(options) # :yield: recvdata + match = @options["Prompt"] + time_out = @options["Timeout"] + + if options.kind_of?(Hash) + string = options["String"] + match = options["Match"] if options.has_key?("Match") + time_out = options["Timeout"] if options.has_key?("Timeout") + else + string = options + end + + self.puts(string) + if block_given? + waitfor({"Prompt" => match, "Timeout" => time_out}){|c| yield c } + else + waitfor({"Prompt" => match, "Timeout" => time_out}) + end + end + + # Login to the host with a given username and password. + # + # The username and password can either be provided as two string + # arguments in that order, or as a hash with keys "Name" and + # "Password". + # + # This method looks for the strings "login" and "Password" from the + # host to determine when to send the username and password. If the + # login sequence does not follow this pattern (for instance, you + # are connecting to a service other than telnet), you will need + # to handle login yourself. + # + # The password can be omitted, either by only + # provided one String argument, which will be used as the username, + # or by providing a has that has no "Password" key. In this case, + # the method will not look for the "Password:" prompt; if it is + # sent, it will have to be dealt with by later calls. + # + # The method returns all data received during the login process from + # the host, including the echoed username but not the password (which + # the host should not echo). If a block is passed in, this received + # data is also yielded to the block as it is received. + def login(options, password = nil) # :yield: recvdata + login_prompt = /[Ll]ogin[: ]*\z/n + password_prompt = /[Pp]ass(?:word|phrase)[: ]*\z/n + if options.kind_of?(Hash) + username = options["Name"] + password = options["Password"] + login_prompt = options["LoginPrompt"] if options["LoginPrompt"] + password_prompt = options["PasswordPrompt"] if options["PasswordPrompt"] + else + username = options + end + + if block_given? + line = waitfor(login_prompt){|c| yield c } + if password + line += cmd({"String" => username, + "Match" => password_prompt}){|c| yield c } + line += cmd(password){|c| yield c } + else + line += cmd(username){|c| yield c } + end + else + line = waitfor(login_prompt) + if password + line += cmd({"String" => username, + "Match" => password_prompt}) + line += cmd(password) + else + line += cmd(username) + end + end + line + end + + end # class Telnet +end # module Net + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/telnets.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/telnets.rb new file mode 100644 index 00000000..694f45c7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/net/telnets.rb @@ -0,0 +1,251 @@ +=begin += $RCSfile$ -- SSL/TLS enhancement for Net::Telnet. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: telnets.rb 16878 2008-06-07 16:16:46Z shyouhei $ + + 2001/11/06: Contiributed to Ruby/OpenSSL project. + +== class Net::Telnet + +This class will initiate SSL/TLS session automaticaly if the server +sent OPT_STARTTLS. Some options are added for SSL/TLS. + + host = Net::Telnet::new({ + "Host" => "localhost", + "Port" => "telnets", + ## follows are new options. + 'CertFile' => "user.crt", + 'KeyFile' => "user.key", + 'CAFile' => "/some/where/certs/casert.pem", + 'CAPath' => "/some/where/caserts", + 'VerifyMode' => SSL::VERIFY_PEER, + 'VerifyCallback' => verify_proc + }) + +Or, the new options ('Cert', 'Key' and 'CACert') are available from +Michal Rokos's OpenSSL module. + + cert_data = File.open("user.crt"){|io| io.read } + pkey_data = File.open("user.key"){|io| io.read } + cacert_data = File.open("your_ca.pem"){|io| io.read } + host = Net::Telnet::new({ + "Host" => "localhost", + "Port" => "telnets", + 'Cert' => OpenSSL::X509::Certificate.new(cert_data) + 'Key' => OpenSSL::PKey::RSA.new(pkey_data) + 'CACert' => OpenSSL::X509::Certificate.new(cacert_data) + 'CAFile' => "/some/where/certs/casert.pem", + 'CAPath' => "/some/where/caserts", + 'VerifyMode' => SSL::VERIFY_PEER, + 'VerifyCallback' => verify_proc + }) + +This class is expected to be a superset of usual Net::Telnet. +=end + +require "net/telnet" +require "openssl" + +module Net + class Telnet + attr_reader :ssl + + OPT_STARTTLS = 46.chr # "\056" # "\x2e" # Start TLS + TLS_FOLLOWS = 1.chr # "\001" # "\x01" # FOLLOWS (for STARTTLS) + + alias preprocess_orig preprocess + + def ssl?; @ssl; end + + def preprocess(string) + # combine CR+NULL into CR + string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"] + + # combine EOL into "\n" + string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"] + + string.gsub(/#{IAC}( + [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]| + [#{DO}#{DONT}#{WILL}#{WONT}][#{OPT_BINARY}-#{OPT_EXOPL}]| + #{SB}[#{OPT_BINARY}-#{OPT_EXOPL}] + (#{IAC}#{IAC}|[^#{IAC}])+#{IAC}#{SE} + )/xno) do + if IAC == $1 # handle escaped IAC characters + IAC + elsif AYT == $1 # respond to "IAC AYT" (are you there) + self.write("nobody here but us pigeons" + EOL) + '' + elsif DO[0] == $1[0] # respond to "IAC DO x" + if OPT_BINARY[0] == $1[1] + @telnet_option["BINARY"] = true + self.write(IAC + WILL + OPT_BINARY) + elsif OPT_STARTTLS[0] == $1[1] + self.write(IAC + WILL + OPT_STARTTLS) + self.write(IAC + SB + OPT_STARTTLS + TLS_FOLLOWS + IAC + SE) + else + self.write(IAC + WONT + $1[1..1]) + end + '' + elsif DONT[0] == $1[0] # respond to "IAC DON'T x" with "IAC WON'T x" + self.write(IAC + WONT + $1[1..1]) + '' + elsif WILL[0] == $1[0] # respond to "IAC WILL x" + if OPT_BINARY[0] == $1[1] + self.write(IAC + DO + OPT_BINARY) + elsif OPT_ECHO[0] == $1[1] + self.write(IAC + DO + OPT_ECHO) + elsif OPT_SGA[0] == $1[1] + @telnet_option["SGA"] = true + self.write(IAC + DO + OPT_SGA) + else + self.write(IAC + DONT + $1[1..1]) + end + '' + elsif WONT[0] == $1[0] # respond to "IAC WON'T x" + if OPT_ECHO[0] == $1[1] + self.write(IAC + DONT + OPT_ECHO) + elsif OPT_SGA[0] == $1[1] + @telnet_option["SGA"] = false + self.write(IAC + DONT + OPT_SGA) + else + self.write(IAC + DONT + $1[1..1]) + end + '' + elsif SB[0] == $1[0] # respond to "IAC SB xxx IAC SE" + if OPT_STARTTLS[0] == $1[1] && TLS_FOLLOWS[0] == $2[0] + @sock = OpenSSL::SSL::SSLSocket.new(@sock) + @sock.cert = @options['Cert'] unless @sock.cert + @sock.key = @options['Key'] unless @sock.key + @sock.ca_cert = @options['CACert'] + @sock.ca_file = @options['CAFile'] + @sock.ca_path = @options['CAPath'] + @sock.timeout = @options['Timeout'] + @sock.verify_mode = @options['VerifyMode'] + @sock.verify_callback = @options['VerifyCallback'] + @sock.verify_depth = @options['VerifyDepth'] + @sock.connect + if @options['VerifyMode'] != OpenSSL::SSL::VERIFY_NONE + @sock.post_connection_check(@options['Host']) + end + @ssl = true + end + '' + else + '' + end + end + end # preprocess + + alias waitfor_org waitfor + + def waitfor(options) + time_out = @options["Timeout"] + waittime = @options["Waittime"] + + if options.kind_of?(Hash) + prompt = if options.has_key?("Match") + options["Match"] + elsif options.has_key?("Prompt") + options["Prompt"] + elsif options.has_key?("String") + Regexp.new( Regexp.quote(options["String"]) ) + end + time_out = options["Timeout"] if options.has_key?("Timeout") + waittime = options["Waittime"] if options.has_key?("Waittime") + else + prompt = options + end + + if time_out == false + time_out = nil + end + + line = '' + buf = '' + @rest = '' unless @rest + + until(prompt === line and not IO::select([@sock], nil, nil, waittime)) + unless IO::select([@sock], nil, nil, time_out) + raise TimeoutError, "timed-out; wait for the next data" + end + begin + c = @rest + @sock.sysread(1024 * 1024) + @dumplog.log_dump('<', c) if @options.has_key?("Dump_log") + if @options["Telnetmode"] + pos = 0 + catch(:next){ + while true + case c[pos] + when IAC[0] + case c[pos+1] + when DO[0], DONT[0], WILL[0], WONT[0] + throw :next unless c[pos+2] + pos += 3 + when SB[0] + ret = detect_sub_negotiation(c, pos) + throw :next unless ret + pos = ret + when nil + throw :next + else + pos += 2 + end + when nil + throw :next + else + pos += 1 + end + end + } + + buf = preprocess(c[0...pos]) + @rest = c[pos..-1] + end + @log.print(buf) if @options.has_key?("Output_log") + line.concat(buf) + yield buf if block_given? + rescue EOFError # End of file reached + if line == '' + line = nil + yield nil if block_given? + end + break + end + end + line + end + + private + + def detect_sub_negotiation(data, pos) + return nil if data.length < pos+6 # IAC SB x param IAC SE + pos += 3 + while true + case data[pos] + when IAC[0] + if data[pos+1] == SE[0] + pos += 2 + return pos + else + pos += 2 + end + when nil + return nil + else + pos += 1 + end + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/observer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/observer.rb new file mode 100644 index 00000000..64c7d813 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/observer.rb @@ -0,0 +1,192 @@ +# +# observer.rb implements the _Observer_ object-oriented design pattern. The +# following documentation is copied, with modifications, from "Programming +# Ruby", by Hunt and Thomas; http://www.rubycentral.com/book/lib_patterns.html. +# +# == About +# +# The Observer pattern, also known as Publish/Subscribe, provides a simple +# mechanism for one object to inform a set of interested third-party objects +# when its state changes. +# +# == Mechanism +# +# In the Ruby implementation, the notifying class mixes in the +Observable+ +# module, which provides the methods for managing the associated observer +# objects. +# +# The observers must implement the +update+ method to receive notifications. +# +# The observable object must: +# * assert that it has +changed+ +# * call +notify_observers+ +# +# == Example +# +# The following example demonstrates this nicely. A +Ticker+, when run, +# continually receives the stock +Price+ for its +@symbol+. A +Warner+ is a +# general observer of the price, and two warners are demonstrated, a +WarnLow+ +# and a +WarnHigh+, which print a warning if the price is below or above their +# set limits, respectively. +# +# The +update+ callback allows the warners to run without being explicitly +# called. The system is set up with the +Ticker+ and several observers, and the +# observers do their duty without the top-level code having to interfere. +# +# Note that the contract between publisher and subscriber (observable and +# observer) is not declared or enforced. The +Ticker+ publishes a time and a +# price, and the warners receive that. But if you don't ensure that your +# contracts are correct, nothing else can warn you. +# +# require "observer" +# +# class Ticker ### Periodically fetch a stock price. +# include Observable +# +# def initialize(symbol) +# @symbol = symbol +# end +# +# def run +# lastPrice = nil +# loop do +# price = Price.fetch(@symbol) +# print "Current price: #{price}\n" +# if price != lastPrice +# changed # notify observers +# lastPrice = price +# notify_observers(Time.now, price) +# end +# sleep 1 +# end +# end +# end +# +# class Price ### A mock class to fetch a stock price (60 - 140). +# def Price.fetch(symbol) +# 60 + rand(80) +# end +# end +# +# class Warner ### An abstract observer of Ticker objects. +# def initialize(ticker, limit) +# @limit = limit +# ticker.add_observer(self) +# end +# end +# +# class WarnLow < Warner +# def update(time, price) # callback for observer +# if price < @limit +# print "--- #{time.to_s}: Price below #@limit: #{price}\n" +# end +# end +# end +# +# class WarnHigh < Warner +# def update(time, price) # callback for observer +# if price > @limit +# print "+++ #{time.to_s}: Price above #@limit: #{price}\n" +# end +# end +# end +# +# ticker = Ticker.new("MSFT") +# WarnLow.new(ticker, 80) +# WarnHigh.new(ticker, 120) +# ticker.run +# +# Produces: +# +# Current price: 83 +# Current price: 75 +# --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75 +# Current price: 90 +# Current price: 134 +# +++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134 +# Current price: 134 +# Current price: 112 +# Current price: 79 +# --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79 + + +# +# Implements the Observable design pattern as a mixin so that other objects can +# be notified of changes in state. See observer.rb for details and an example. +# +module Observable + + # + # Add +observer+ as an observer on this object. +observer+ will now receive + # notifications. + # + def add_observer(observer) + @observer_peers = [] unless defined? @observer_peers + unless observer.respond_to? :update + raise NoMethodError, "observer needs to respond to `update'" + end + @observer_peers.push observer + end + + # + # Delete +observer+ as an observer on this object. It will no longer receive + # notifications. + # + def delete_observer(observer) + @observer_peers.delete observer if defined? @observer_peers + end + + # + # Delete all observers associated with this object. + # + def delete_observers + @observer_peers.clear if defined? @observer_peers + end + + # + # Return the number of observers associated with this object. + # + def count_observers + if defined? @observer_peers + @observer_peers.size + else + 0 + end + end + + # + # Set the changed state of this object. Notifications will be sent only if + # the changed +state+ is +true+. + # + def changed(state=true) + @observer_state = state + end + + # + # Query the changed state of this object. + # + def changed? + if defined? @observer_state and @observer_state + true + else + false + end + end + + # + # If this object's changed state is +true+, invoke the update method in each + # currently associated observer in turn, passing it the given arguments. The + # changed state is then set to +false+. + # + def notify_observers(*arg) + if defined? @observer_state and @observer_state + if defined? @observer_peers + for i in @observer_peers.dup + i.update(*arg) + end + end + @observer_state = false + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/open-uri.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/open-uri.rb new file mode 100644 index 00000000..0dae95b6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/open-uri.rb @@ -0,0 +1,678 @@ +require 'uri' +require 'stringio' +require 'time' + +module Kernel + private + alias open_uri_original_open open # :nodoc: + + # makes possible to open various resources including URIs. + # If the first argument respond to `open' method, + # the method is called with the rest arguments. + # + # If the first argument is a string which begins with xxx://, + # it is parsed by URI.parse. If the parsed object respond to `open' method, + # the method is called with the rest arguments. + # + # Otherwise original open is called. + # + # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and + # URI::FTP#open, + # Kernel[#.]open can accepts such URIs and strings which begins with + # http://, https:// and ftp://. + # In these case, the opened file object is extended by OpenURI::Meta. + def open(name, *rest, &block) # :doc: + if name.respond_to?(:open) + name.open(*rest, &block) + elsif name.respond_to?(:to_str) && + %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name && + (uri = URI.parse(name)).respond_to?(:open) + uri.open(*rest, &block) + else + open_uri_original_open(name, *rest, &block) + end + end + module_function :open +end + +# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp. +# +#== Example +# +# It is possible to open http/https/ftp URL as usual like opening a file: +# +# open("http://www.ruby-lang.org/") {|f| +# f.each_line {|line| p line} +# } +# +# The opened file has several methods for meta information as follows since +# it is extended by OpenURI::Meta. +# +# open("http://www.ruby-lang.org/en") {|f| +# f.each_line {|line| p line} +# p f.base_uri # +# p f.content_type # "text/html" +# p f.charset # "iso-8859-1" +# p f.content_encoding # [] +# p f.last_modified # Thu Dec 05 02:45:02 UTC 2002 +# } +# +# Additional header fields can be specified by an optional hash argument. +# +# open("http://www.ruby-lang.org/en/", +# "User-Agent" => "Ruby/#{RUBY_VERSION}", +# "From" => "foo@bar.invalid", +# "Referer" => "http://www.ruby-lang.org/") {|f| +# # ... +# } +# +# The environment variables such as http_proxy, https_proxy and ftp_proxy +# are in effect by default. :proxy => nil disables proxy. +# +# open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f| +# # ... +# } +# +# URI objects can be opened in a similar way. +# +# uri = URI.parse("http://www.ruby-lang.org/en/") +# uri.open {|f| +# # ... +# } +# +# URI objects can be read directly. The returned string is also extended by +# OpenURI::Meta. +# +# str = uri.read +# p str.base_uri +# +# Author:: Tanaka Akira + +module OpenURI + Options = { + :proxy => true, + :progress_proc => true, + :content_length_proc => true, + :http_basic_authentication => true, + } + + def OpenURI.check_options(options) # :nodoc: + options.each {|k, v| + next unless Symbol === k + unless Options.include? k + raise ArgumentError, "unrecognized option: #{k}" + end + } + end + + def OpenURI.scan_open_optional_arguments(*rest) # :nodoc: + if !rest.empty? && (String === rest.first || Integer === rest.first) + mode = rest.shift + if !rest.empty? && Integer === rest.first + perm = rest.shift + end + end + return mode, perm, rest + end + + def OpenURI.open_uri(name, *rest) # :nodoc: + uri = URI::Generic === name ? name : URI.parse(name) + mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest) + options = rest.shift if !rest.empty? && Hash === rest.first + raise ArgumentError.new("extra arguments") if !rest.empty? + options ||= {} + OpenURI.check_options(options) + + unless mode == nil || + mode == 'r' || mode == 'rb' || + mode == File::RDONLY + raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)") + end + + io = open_loop(uri, options) + if block_given? + begin + yield io + ensure + io.close + end + else + io + end + end + + def OpenURI.open_loop(uri, options) # :nodoc: + case opt_proxy = options.fetch(:proxy, true) + when true + find_proxy = lambda {|u| u.find_proxy} + when nil, false + find_proxy = lambda {|u| nil} + when String + opt_proxy = URI.parse(opt_proxy) + find_proxy = lambda {|u| opt_proxy} + when URI::Generic + find_proxy = lambda {|u| opt_proxy} + else + raise ArgumentError.new("Invalid proxy option: #{opt_proxy}") + end + + uri_set = {} + buf = nil + while true + redirect = catch(:open_uri_redirect) { + buf = Buffer.new + uri.buffer_open(buf, find_proxy.call(uri), options) + nil + } + if redirect + if redirect.relative? + # Although it violates RFC2616, Location: field may have relative + # URI. It is converted to absolute URI using uri as a base URI. + redirect = uri + redirect + end + unless OpenURI.redirectable?(uri, redirect) + raise "redirection forbidden: #{uri} -> #{redirect}" + end + if options.include? :http_basic_authentication + # send authentication only for the URI directly specified. + options = options.dup + options.delete :http_basic_authentication + end + uri = redirect + raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s + uri_set[uri.to_s] = true + else + break + end + end + io = buf.io + io.base_uri = uri + io + end + + def OpenURI.redirectable?(uri1, uri2) # :nodoc: + # This test is intended to forbid a redirection from http://... to + # file:///etc/passwd. + # However this is ad hoc. It should be extensible/configurable. + uri1.scheme.downcase == uri2.scheme.downcase || + (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme) + end + + def OpenURI.open_http(buf, target, proxy, options) # :nodoc: + if proxy + raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP + end + + if target.userinfo && "1.9.0" <= RUBY_VERSION + # don't raise for 1.8 because compatibility. + raise ArgumentError, "userinfo not supported. [RFC3986]" + end + + require 'net/http' + klass = Net::HTTP + if URI::HTTP === target + # HTTP or HTTPS + if proxy + klass = Net::HTTP::Proxy(proxy.host, proxy.port) + end + target_host = target.host + target_port = target.port + request_uri = target.request_uri + else + # FTP over HTTP proxy + target_host = proxy.host + target_port = proxy.port + request_uri = target.to_s + end + + http = klass.new(target_host, target_port) + if target.class == URI::HTTPS + require 'net/https' + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + store = OpenSSL::X509::Store.new + store.set_default_paths + http.cert_store = store + end + + header = {} + options.each {|k, v| header[k] = v if String === k } + + resp = nil + http.start { + req = Net::HTTP::Get.new(request_uri, header) + if options.include? :http_basic_authentication + user, pass = options[:http_basic_authentication] + req.basic_auth user, pass + end + http.request(req) {|response| + resp = response + if options[:content_length_proc] && Net::HTTPSuccess === resp + if resp.key?('Content-Length') + options[:content_length_proc].call(resp['Content-Length'].to_i) + else + options[:content_length_proc].call(nil) + end + end + resp.read_body {|str| + buf << str + if options[:progress_proc] && Net::HTTPSuccess === resp + options[:progress_proc].call(buf.size) + end + } + } + } + io = buf.io + io.rewind + io.status = [resp.code, resp.message] + resp.each {|name,value| buf.io.meta_add_field name, value } + case resp + when Net::HTTPSuccess + when Net::HTTPMovedPermanently, # 301 + Net::HTTPFound, # 302 + Net::HTTPSeeOther, # 303 + Net::HTTPTemporaryRedirect # 307 + throw :open_uri_redirect, URI.parse(resp['location']) + else + raise OpenURI::HTTPError.new(io.status.join(' '), io) + end + end + + class HTTPError < StandardError + def initialize(message, io) + super(message) + @io = io + end + attr_reader :io + end + + class Buffer # :nodoc: + def initialize + @io = StringIO.new + @size = 0 + end + attr_reader :size + + StringMax = 10240 + def <<(str) + @io << str + @size += str.length + if StringIO === @io && StringMax < @size + require 'tempfile' + io = Tempfile.new('open-uri') + io.binmode + Meta.init io, @io if @io.respond_to? :meta + io << @io.string + @io = io + end + end + + def io + Meta.init @io unless @io.respond_to? :meta + @io + end + end + + # Mixin for holding meta-information. + module Meta + def Meta.init(obj, src=nil) # :nodoc: + obj.extend Meta + obj.instance_eval { + @base_uri = nil + @meta = {} + } + if src + obj.status = src.status + obj.base_uri = src.base_uri + src.meta.each {|name, value| + obj.meta_add_field(name, value) + } + end + end + + # returns an Array which consists status code and message. + attr_accessor :status + + # returns a URI which is base of relative URIs in the data. + # It may differ from the URI supplied by a user because redirection. + attr_accessor :base_uri + + # returns a Hash which represents header fields. + # The Hash keys are downcased for canonicalization. + attr_reader :meta + + def meta_add_field(name, value) # :nodoc: + @meta[name.downcase] = value + end + + # returns a Time which represents Last-Modified field. + def last_modified + if v = @meta['last-modified'] + Time.httpdate(v) + else + nil + end + end + + RE_LWS = /[\r\n\t ]+/n + RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n + RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n + RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n + + def content_type_parse # :nodoc: + v = @meta['content-type'] + # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045. + if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v + type = $1.downcase + subtype = $2.downcase + parameters = [] + $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval| + val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/) { $1 ? $1[1,1] : $& } if qval + parameters << [att.downcase, val] + } + ["#{type}/#{subtype}", *parameters] + else + nil + end + end + + # returns "type/subtype" which is MIME Content-Type. + # It is downcased for canonicalization. + # Content-Type parameters are stripped. + def content_type + type, *parameters = content_type_parse + type || 'application/octet-stream' + end + + # returns a charset parameter in Content-Type field. + # It is downcased for canonicalization. + # + # If charset parameter is not given but a block is given, + # the block is called and its result is returned. + # It can be used to guess charset. + # + # If charset parameter and block is not given, + # nil is returned except text type in HTTP. + # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1. + def charset + type, *parameters = content_type_parse + if pair = parameters.assoc('charset') + pair.last.downcase + elsif block_given? + yield + elsif type && %r{\Atext/} =~ type && + @base_uri && /\Ahttp\z/i =~ @base_uri.scheme + "iso-8859-1" # RFC2616 3.7.1 + else + nil + end + end + + # returns a list of encodings in Content-Encoding field + # as an Array of String. + # The encodings are downcased for canonicalization. + def content_encoding + v = @meta['content-encoding'] + if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v + v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase} + else + [] + end + end + end + + # Mixin for HTTP and FTP URIs. + module OpenRead + # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP. + # + # OpenURI::OpenRead#open takes optional 3 arguments as: + # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }] + # + # `mode', `perm' is same as Kernel#open. + # + # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't + # support write mode (yet). + # Also `perm' is just ignored because it is meaningful only for file + # creation. + # + # `options' must be a hash. + # + # Each pairs which key is a string in the hash specify a extra header + # field for HTTP. + # I.e. it is ignored for FTP without HTTP proxy. + # + # The hash may include other options which key is a symbol: + # + # [:proxy] + # Synopsis: + # :proxy => "http://proxy.foo.com:8000/" + # :proxy => URI.parse("http://proxy.foo.com:8000/") + # :proxy => true + # :proxy => false + # :proxy => nil + # + # If :proxy option is specified, the value should be String, URI, + # boolean or nil. + # When String or URI is given, it is treated as proxy URI. + # When true is given or the option itself is not specified, + # environment variable `scheme_proxy' is examined. + # `scheme' is replaced by `http', `https' or `ftp'. + # When false or nil is given, the environment variables are ignored and + # connection will be made to a server directly. + # + # [:http_basic_authentication] + # Synopsis: + # :http_basic_authentication=>[user, password] + # + # If :http_basic_authentication is specified, + # the value should be an array which contains 2 strings: + # username and password. + # It is used for HTTP Basic authentication defined by RFC 2617. + # + # [:content_length_proc] + # Synopsis: + # :content_length_proc => lambda {|content_length| ... } + # + # If :content_length_proc option is specified, the option value procedure + # is called before actual transfer is started. + # It takes one argument which is expected content length in bytes. + # + # If two or more transfer is done by HTTP redirection, the procedure + # is called only one for a last transfer. + # + # When expected content length is unknown, the procedure is called with + # nil. + # It is happen when HTTP response has no Content-Length header. + # + # [:progress_proc] + # Synopsis: + # :progress_proc => lambda {|size| ...} + # + # If :progress_proc option is specified, the proc is called with one + # argument each time when `open' gets content fragment from network. + # The argument `size' `size' is a accumulated transfered size in bytes. + # + # If two or more transfer is done by HTTP redirection, the procedure + # is called only one for a last transfer. + # + # :progress_proc and :content_length_proc are intended to be used for + # progress bar. + # For example, it can be implemented as follows using Ruby/ProgressBar. + # + # pbar = nil + # open("http://...", + # :content_length_proc => lambda {|t| + # if t && 0 < t + # pbar = ProgressBar.new("...", t) + # pbar.file_transfer_mode + # end + # }, + # :progress_proc => lambda {|s| + # pbar.set s if pbar + # }) {|f| ... } + # + # OpenURI::OpenRead#open returns an IO like object if block is not given. + # Otherwise it yields the IO object and return the value of the block. + # The IO object is extended with OpenURI::Meta. + def open(*rest, &block) + OpenURI.open_uri(self, *rest, &block) + end + + # OpenURI::OpenRead#read([options]) reads a content referenced by self and + # returns the content as string. + # The string is extended with OpenURI::Meta. + # The argument `options' is same as OpenURI::OpenRead#open. + def read(options={}) + self.open(options) {|f| + str = f.read + Meta.init str, f + str + } + end + end +end + +module URI + class Generic + # returns a proxy URI. + # The proxy URI is obtained from environment variables such as http_proxy, + # ftp_proxy, no_proxy, etc. + # If there is no proper proxy, nil is returned. + # + # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) + # are examined too. + # + # But http_proxy and HTTP_PROXY is treated specially under CGI environment. + # It's because HTTP_PROXY may be set by Proxy: header. + # So HTTP_PROXY is not used. + # http_proxy is not used too if the variable is case insensitive. + # CGI_HTTP_PROXY can be used instead. + def find_proxy + name = self.scheme.downcase + '_proxy' + proxy_uri = nil + if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI? + # HTTP_PROXY conflicts with *_proxy for proxy settings and + # HTTP_* for header information in CGI. + # So it should be careful to use it. + pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k } + case pairs.length + when 0 # no proxy setting anyway. + proxy_uri = nil + when 1 + k, v = pairs.shift + if k == 'http_proxy' && ENV[k.upcase] == nil + # http_proxy is safe to use because ENV is case sensitive. + proxy_uri = ENV[name] + else + proxy_uri = nil + end + else # http_proxy is safe to use because ENV is case sensitive. + proxy_uri = ENV[name] + end + if !proxy_uri + # Use CGI_HTTP_PROXY. cf. libwww-perl. + proxy_uri = ENV["CGI_#{name.upcase}"] + end + elsif name == 'http_proxy' + unless proxy_uri = ENV[name] + if proxy_uri = ENV[name.upcase] + warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.' + end + end + else + proxy_uri = ENV[name] || ENV[name.upcase] + end + + if proxy_uri && self.host + require 'socket' + begin + addr = IPSocket.getaddress(self.host) + proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr + rescue SocketError + end + end + + if proxy_uri + proxy_uri = URI.parse(proxy_uri) + name = 'no_proxy' + if no_proxy = ENV[name] || ENV[name.upcase] + no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port| + if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host && + (!port || self.port == port.to_i) + proxy_uri = nil + break + end + } + end + proxy_uri + else + nil + end + end + end + + class HTTP + def buffer_open(buf, proxy, options) # :nodoc: + OpenURI.open_http(buf, self, proxy, options) + end + + include OpenURI::OpenRead + end + + class FTP + def buffer_open(buf, proxy, options) # :nodoc: + if proxy + OpenURI.open_http(buf, self, proxy, options) + return + end + require 'net/ftp' + + directories = self.path.split(%r{/}, -1) + directories.shift if directories[0] == '' # strip a field before leading slash + directories.each {|d| + d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") } + } + unless filename = directories.pop + raise ArgumentError, "no filename: #{self.inspect}" + end + directories.each {|d| + if /[\r\n]/ =~ d + raise ArgumentError, "invalid directory: #{d.inspect}" + end + } + if /[\r\n]/ =~ filename + raise ArgumentError, "invalid filename: #{filename.inspect}" + end + typecode = self.typecode + if typecode && /\A[aid]\z/ !~ typecode + raise ArgumentError, "invalid typecode: #{typecode.inspect}" + end + + # The access sequence is defined by RFC 1738 + ftp = Net::FTP.open(self.host) + # todo: extract user/passwd from .netrc. + user = 'anonymous' + passwd = nil + user, passwd = self.userinfo.split(/:/) if self.userinfo + ftp.login(user, passwd) + directories.each {|cwd| + ftp.voidcmd("CWD #{cwd}") + } + if typecode + # xxx: typecode D is not handled. + ftp.voidcmd("TYPE #{typecode.upcase}") + end + if options[:content_length_proc] + options[:content_length_proc].call(ftp.size(filename)) + end + ftp.retrbinary("RETR #{filename}", 4096) { |str| + buf << str + options[:progress_proc].call(buf.size) if options[:progress_proc] + } + ftp.close + buf.io.rewind + end + + include OpenURI::OpenRead + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/open3.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/open3.rb new file mode 100644 index 00000000..c4dacc94 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/open3.rb @@ -0,0 +1,101 @@ +# +# = open3.rb: Popen, but with stderr, too +# +# Author:: Yukihiro Matsumoto +# Documentation:: Konrad Meyer +# +# Open3 gives you access to stdin, stdout, and stderr when running other +# programs. +# + +# +# Open3 grants you access to stdin, stdout, and stderr when running another +# program. Example: +# +# require "open3" +# include Open3 +# +# stdin, stdout, stderr = popen3('nroff -man') +# +# Open3.popen3 can also take a block which will receive stdin, stdout and +# stderr as parameters. This ensures stdin, stdout and stderr are closed +# once the block exits. Example: +# +# require "open3" +# +# Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... } +# + +module Open3 + # + # Open stdin, stdout, and stderr streams and start external executable. + # Non-block form: + # + # require 'open3' + # + # [stdin, stdout, stderr] = Open3.popen3(cmd) + # + # Block form: + # + # require 'open3' + # + # Open3.popen3(cmd) { |stdin, stdout, stderr| ... } + # + # The parameter +cmd+ is passed directly to Kernel#exec. + # + def popen3(*cmd) + pw = IO::pipe # pipe[0] for read, pipe[1] for write + pr = IO::pipe + pe = IO::pipe + + pid = fork{ + # child + fork{ + # grandchild + pw[1].close + STDIN.reopen(pw[0]) + pw[0].close + + pr[0].close + STDOUT.reopen(pr[1]) + pr[1].close + + pe[0].close + STDERR.reopen(pe[1]) + pe[1].close + + exec(*cmd) + } + exit!(0) + } + + pw[0].close + pr[1].close + pe[1].close + Process.waitpid(pid) + pi = [pw[1], pr[0], pe[0]] + pw[1].sync = true + if defined? yield + begin + return yield(*pi) + ensure + pi.each{|p| p.close unless p.closed?} + end + end + pi + end + module_function :popen3 +end + +if $0 == __FILE__ + a = Open3.popen3("nroff -man") + Thread.start do + while line = gets + a[0].print line + end + a[0].close + end + while line = a[1].gets + print ":", line + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl.rb new file mode 100644 index 00000000..411c0db7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl.rb @@ -0,0 +1,24 @@ +=begin += $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: openssl.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +require 'openssl.so' + +require 'openssl/bn' +require 'openssl/cipher' +require 'openssl/digest' +require 'openssl/ssl' +require 'openssl/x509' + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/bn.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/bn.rb new file mode 100644 index 00000000..cf44a094 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/bn.rb @@ -0,0 +1,35 @@ +=begin += $RCSfile$ -- Ruby-space definitions that completes C-space funcs for BN + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: bn.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + class BN + include Comparable + end # BN +end # OpenSSL + +## +# Add double dispatch to Integer +# +class Integer + def to_bn + OpenSSL::BN::new(self) + end +end # Integer + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/buffering.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/buffering.rb new file mode 100644 index 00000000..2c66a75e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/buffering.rb @@ -0,0 +1,239 @@ +=begin += $RCSfile$ -- Buffering mix-in module. + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: buffering.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +module Buffering + include Enumerable + attr_accessor :sync + BLOCK_SIZE = 1024*16 + + def initialize(*args) + @eof = false + @rbuffer = "" + @sync = @io.sync + end + + # + # for reading. + # + private + + def fill_rbuff + begin + @rbuffer << self.sysread(BLOCK_SIZE) + rescue Errno::EAGAIN + retry + rescue EOFError + @eof = true + end + end + + def consume_rbuff(size=nil) + if @rbuffer.empty? + nil + else + size = @rbuffer.size unless size + ret = @rbuffer[0, size] + @rbuffer[0, size] = "" + ret + end + end + + public + + def read(size=nil, buf=nil) + if size == 0 + if buf + buf.clear + else + buf = "" + end + return @eof ? nil : buf + end + until @eof + break if size && size <= @rbuffer.size + fill_rbuff + end + ret = consume_rbuff(size) || "" + if buf + buf.replace(ret) + ret = buf + end + (size && ret.empty?) ? nil : ret + end + + def readpartial(maxlen, buf=nil) + if maxlen == 0 + if buf + buf.clear + else + buf = "" + end + return @eof ? nil : buf + end + if @rbuffer.empty? + begin + return sysread(maxlen, buf) + rescue Errno::EAGAIN + retry + end + end + ret = consume_rbuff(maxlen) + if buf + buf.replace(ret) + ret = buf + end + raise EOFError if ret.empty? + ret + end + + def gets(eol=$/) + idx = @rbuffer.index(eol) + until @eof + break if idx + fill_rbuff + idx = @rbuffer.index(eol) + end + if eol.is_a?(Regexp) + size = idx ? idx+$&.size : nil + else + size = idx ? idx+eol.size : nil + end + consume_rbuff(size) + end + + def each(eol=$/) + while line = self.gets(eol) + yield line + end + end + alias each_line each + + def readlines(eol=$/) + ary = [] + while line = self.gets(eol) + ary << line + end + ary + end + + def readline(eol=$/) + raise EOFError if eof? + gets(eol) + end + + def getc + c = read(1) + c ? c[0] : nil + end + + def each_byte + while c = getc + yield(c) + end + end + + def readchar + raise EOFError if eof? + getc + end + + def ungetc(c) + @rbuffer[0,0] = c.chr + end + + def eof? + fill_rbuff if !@eof && @rbuffer.empty? + @eof && @rbuffer.empty? + end + alias eof eof? + + # + # for writing. + # + private + + def do_write(s) + @wbuffer = "" unless defined? @wbuffer + @wbuffer << s + @sync ||= false + if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) + remain = idx ? idx + $/.size : @wbuffer.length + nwritten = 0 + while remain > 0 + str = @wbuffer[nwritten,remain] + begin + nwrote = syswrite(str) + rescue Errno::EAGAIN + retry + end + remain -= nwrote + nwritten += nwrote + end + @wbuffer[0,nwritten] = "" + end + end + + public + + def write(s) + do_write(s) + s.length + end + + def << (s) + do_write(s) + self + end + + def puts(*args) + s = "" + if args.empty? + s << "\n" + end + args.each{|arg| + s << arg.to_s + if $/ && /\n\z/ !~ s + s << "\n" + end + } + do_write(s) + nil + end + + def print(*args) + s = "" + args.each{ |arg| s << arg.to_s } + do_write(s) + nil + end + + def printf(s, *args) + do_write(s % args) + nil + end + + def flush + osync = @sync + @sync = true + do_write "" + @sync = osync + end + + def close + flush rescue nil + sysclose + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/cipher.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/cipher.rb new file mode 100644 index 00000000..fb924e96 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/cipher.rb @@ -0,0 +1,58 @@ +=begin += $RCSfile$ -- Ruby-space predefined Cipher subclasses + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: cipher.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + module Cipher + %w(AES CAST5 BF DES IDEA RC2 RC4 RC5).each{|name| + klass = Class.new(Cipher){ + define_method(:initialize){|*args| + cipher_name = args.inject(name){|n, arg| "#{n}-#{arg}" } + super(cipher_name) + } + } + const_set(name, klass) + } + + %w(128 192 256).each{|keylen| + klass = Class.new(Cipher){ + define_method(:initialize){|mode| + mode ||= "CBC" + cipher_name = "AES-#{keylen}-#{mode}" + super(cipher_name) + } + } + const_set("AES#{keylen}", klass) + } + + class Cipher + def random_key + str = OpenSSL::Random.random_bytes(self.key_len) + self.key = str + return str + end + + def random_iv + str = OpenSSL::Random.random_bytes(self.iv_len) + self.iv = str + return str + end + end + end # Cipher +end # OpenSSL diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/digest.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/digest.rb new file mode 100644 index 00000000..0d7e7513 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/digest.rb @@ -0,0 +1,49 @@ +=begin += $RCSfile$ -- Ruby-space predefined Digest subclasses + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: digest.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +## +# Should we care what if somebody require this file directly? +#require 'openssl' + +module OpenSSL + module Digest + + alg = %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1) + if OPENSSL_VERSION_NUMBER > 0x00908000 + alg += %w(SHA224 SHA256 SHA384 SHA512) + end + + alg.each{|name| + klass = Class.new(Digest){ + define_method(:initialize){|*data| + if data.length > 1 + raise ArgumentError, + "wrong number of arguments (#{data.length} for 1)" + end + super(name, data.first) + } + } + singleton = (class < + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: ssl.rb 13504 2007-09-24 08:12:24Z shyouhei $ +=end + +require "openssl" +require "openssl/buffering" +require "fcntl" + +module OpenSSL + module SSL + module SocketForwarder + def addr + to_io.addr + end + + def peeraddr + to_io.peeraddr + end + + def setsockopt(level, optname, optval) + to_io.setsockopt(level, optname, optval) + end + + def getsockopt(level, optname) + to_io.getsockopt(level, optname) + end + + def fcntl(*args) + to_io.fcntl(*args) + end + + def closed? + to_io.closed? + end + + def do_not_reverse_lookup=(flag) + to_io.do_not_reverse_lookup = flag + end + end + + module Nonblock + def initialize(*args) + flag = File::NONBLOCK + flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL) + @io.fcntl(Fcntl::F_SETFL, flag) + super + end + end + + class SSLSocket + include Buffering + include SocketForwarder + include Nonblock + + def post_connection_check(hostname) + check_common_name = true + cert = peer_cert + cert.extensions.each{|ext| + next if ext.oid != "subjectAltName" + ext.value.split(/,\s+/).each{|general_name| + if /\ADNS:(.*)/ =~ general_name + check_common_name = false + reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") + return true if /\A#{reg}\z/i =~ hostname + elsif /\AIP Address:(.*)/ =~ general_name + check_common_name = false + return true if $1 == hostname + end + } + } + if check_common_name + cert.subject.to_a.each{|oid, value| + if oid == "CN" + reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") + return true if /\A#{reg}\z/i =~ hostname + end + } + end + raise SSLError, "hostname was not match with the server certificate" + end + end + + class SSLServer + include SocketForwarder + attr_accessor :start_immediately + + def initialize(svr, ctx) + @svr = svr + @ctx = ctx + unless ctx.session_id_context + session_id = OpenSSL::Digest::MD5.hexdigest($0) + @ctx.session_id_context = session_id + end + @start_immediately = true + end + + def to_io + @svr + end + + def listen(backlog=5) + @svr.listen(backlog) + end + + def accept + sock = @svr.accept + begin + ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) + ssl.sync_close = true + ssl.accept if @start_immediately + ssl + rescue SSLError => ex + sock.close + raise ex + end + end + + def close + @svr.close + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/x509.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/x509.rb new file mode 100644 index 00000000..99f239ce --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/openssl/x509.rb @@ -0,0 +1,154 @@ +=begin += $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2002 Michal Rokos + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id: x509.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end + +require "openssl" + +module OpenSSL + module X509 + class ExtensionFactory + def create_extension(*arg) + if arg.size > 1 + create_ext(*arg) + else + send("create_ext_from_"+arg[0].class.name.downcase, arg[0]) + end + end + + def create_ext_from_array(ary) + raise ExtensionError, "unexpected array form" if ary.size > 3 + create_ext(ary[0], ary[1], ary[2]) + end + + def create_ext_from_string(str) # "oid = critical, value" + oid, value = str.split(/=/, 2) + oid.strip! + value.strip! + create_ext(oid, value) + end + + def create_ext_from_hash(hash) + create_ext(hash["oid"], hash["value"], hash["critical"]) + end + end + + class Extension + def to_s # "oid = critical, value" + str = self.oid + str << " = " + str << "critical, " if self.critical? + str << self.value.gsub(/\n/, ", ") + end + + def to_h # {"oid"=>sn|ln, "value"=>value, "critical"=>true|false} + {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical?} + end + + def to_a + [ self.oid, self.value, self.critical? ] + end + end + + class Name + module RFC2253DN + Special = ',=+<>#;' + HexChar = /[0-9a-fA-F]/ + HexPair = /#{HexChar}#{HexChar}/ + HexString = /#{HexPair}+/ + Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ + StringChar = /[^#{Special}\\"]/ + QuoteChar = /[^\\"]/ + AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ + AttributeValue = / + (?!["#])((?:#{StringChar}|#{Pair})*)| + \#(#{HexString})| + "((?:#{QuoteChar}|#{Pair})*)" + /x + TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ + + module_function + + def expand_pair(str) + return nil unless str + return str.gsub(Pair){|pair| + case pair.size + when 2 then pair[1,1] + when 3 then Integer("0x#{pair[1,2]}").chr + else raise OpenSSL::X509::NameError, "invalid pair: #{str}" + end + } + end + + def expand_hexstring(str) + return nil unless str + der = str.gsub(HexPair){|hex| Integer("0x#{hex}").chr } + a1 = OpenSSL::ASN1.decode(der) + return a1.value, a1.tag + end + + def expand_value(str1, str2, str3) + value = expand_pair(str1) + value, tag = expand_hexstring(str2) unless value + value = expand_pair(str3) unless value + return value, tag + end + + def scan(dn) + str = dn + ary = [] + while true + if md = TypeAndValue.match(str) + matched = md.to_s + remain = md.post_match + type = md[1] + value, tag = expand_value(md[2], md[3], md[4]) rescue nil + if value + type_and_value = [type, value] + type_and_value.push(tag) if tag + ary.unshift(type_and_value) + if remain.length > 2 && remain[0] == ?, + str = remain[1..-1] + next + elsif remain.length > 2 && remain[0] == ?+ + raise OpenSSL::X509::NameError, + "multi-valued RDN is not supported: #{dn}" + elsif remain.empty? + break + end + end + end + msg_dn = dn[0, dn.length - str.length] + " =>" + str + raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" + end + return ary + end + end + + class < "iso-2022-jp", "sjis" => "shift_jis" } +# +# # +# # Return a structure describing the options. +# # +# def self.parse(args) +# # The options specified on the command line will be collected in *options*. +# # We set default values here. +# options = OpenStruct.new +# options.library = [] +# options.inplace = false +# options.encoding = "utf8" +# options.transfer_type = :auto +# options.verbose = false +# +# opts = OptionParser.new do |opts| +# opts.banner = "Usage: example.rb [options]" +# +# opts.separator "" +# opts.separator "Specific options:" +# +# # Mandatory argument. +# opts.on("-r", "--require LIBRARY", +# "Require the LIBRARY before executing your script") do |lib| +# options.library << lib +# end +# +# # Optional argument; multi-line description. +# opts.on("-i", "--inplace [EXTENSION]", +# "Edit ARGV files in place", +# " (make backup if EXTENSION supplied)") do |ext| +# options.inplace = true +# options.extension = ext || '' +# options.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot. +# end +# +# # Cast 'delay' argument to a Float. +# opts.on("--delay N", Float, "Delay N seconds before executing") do |n| +# options.delay = n +# end +# +# # Cast 'time' argument to a Time object. +# opts.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time| +# options.time = time +# end +# +# # Cast to octal integer. +# opts.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger, +# "Specify record separator (default \\0)") do |rs| +# options.record_separator = rs +# end +# +# # List of arguments. +# opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list| +# options.list = list +# end +# +# # Keyword completion. We are specifying a specific set of arguments (CODES +# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide +# # the shortest unambiguous text. +# code_list = (CODE_ALIASES.keys + CODES).join(',') +# opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding", +# " (#{code_list})") do |encoding| +# options.encoding = encoding +# end +# +# # Optional argument with keyword completion. +# opts.on("--type [TYPE]", [:text, :binary, :auto], +# "Select transfer type (text, binary, auto)") do |t| +# options.transfer_type = t +# end +# +# # Boolean switch. +# opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| +# options.verbose = v +# end +# +# opts.separator "" +# opts.separator "Common options:" +# +# # No argument, shows at tail. This will print an options summary. +# # Try it and see! +# opts.on_tail("-h", "--help", "Show this message") do +# puts opts +# exit +# end +# +# # Another typical switch to print the version. +# opts.on_tail("--version", "Show version") do +# puts OptionParser::Version.join('.') +# exit +# end +# end +# +# opts.parse!(args) +# options +# end # parse() +# +# end # class OptparseExample +# +# options = OptparseExample.parse(ARGV) +# pp options +# +# === Further documentation +# +# The above examples should be enough to learn how to use this class. If you +# have any questions, email me (gsinclair@soyabean.com.au) and I will update +# this document. +# +class OptionParser + # :stopdoc: + RCSID = %w$Id: optparse.rb 18108 2008-07-17 12:30:12Z shyouhei $[1..-1].each {|s| s.freeze}.freeze + Version = (RCSID[1].split('.').collect {|s| s.to_i}.extend(Comparable).freeze if RCSID[1]) + LastModified = (Time.gm(*RCSID[2, 2].join('-').scan(/\d+/).collect {|s| s.to_i}) if RCSID[2]) + Release = RCSID[2] + + NoArgument = [NO_ARGUMENT = :NONE, nil].freeze + RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze + OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze + # :startdoc: + + # + # Keyword completion module. This allows partial arguments to be specified + # and resolved against a list of acceptable values. + # + module Completion + def complete(key, icase = false, pat = nil) + pat ||= Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), + icase) + canon, sw, k, v, cn = nil + candidates = [] + each do |k, *v| + (if Regexp === k + kn = nil + k === key + else + kn = defined?(k.id2name) ? k.id2name : k + pat === kn + end) or next + v << k if v.empty? + candidates << [k, v, kn] + end + candidates = candidates.sort_by {|k, v, kn| kn.size} + if candidates.size == 1 + canon, sw, * = candidates[0] + elsif candidates.size > 1 + canon, sw, cn = candidates.shift + candidates.each do |k, v, kn| + next if sw == v + if String === cn and String === kn + if cn.rindex(kn, 0) + canon, sw, cn = k, v, kn + next + elsif kn.rindex(cn, 0) + next + end + end + throw :ambiguous, key + end + end + if canon + block_given? or return key, *sw + yield(key, *sw) + end + end + + def convert(opt = nil, val = nil, *) + val + end + end + + + # + # Map from option/keyword string to object with completion. + # + class OptionMap < Hash + include Completion + end + + + # + # Individual switch class. Not important to the user. + # + # Defined within Switch are several Switch-derived classes: NoArgument, + # RequiredArgument, etc. + # + class Switch + attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block + + # + # Guesses argument style from +arg+. Returns corresponding + # OptionParser::Switch class (OptionalArgument, etc.). + # + def self.guess(arg) + case arg + when "" + t = self + when /\A=?\[/ + t = Switch::OptionalArgument + when /\A\s+\[/ + t = Switch::PlacedArgument + else + t = Switch::RequiredArgument + end + self >= t or incompatible_argument_styles(arg, t) + t + end + + def self.incompatible_argument_styles(arg, t) + raise ArgumentError, "#{arg}: incompatible argument styles\n #{self}, #{t}" + end + + def self.pattern + NilClass + end + + def initialize(pattern = nil, conv = nil, + short = nil, long = nil, arg = nil, + desc = ([] if short or long), block = Proc.new) + raise if Array === pattern + @pattern, @conv, @short, @long, @arg, @desc, @block = + pattern, conv, short, long, arg, desc, block + end + + # + # Parses +arg+ and returns rest of +arg+ and matched portion to the + # argument pattern. Yields when the pattern doesn't match substring. + # + def parse_arg(arg) + pattern or return nil, arg + unless m = pattern.match(arg) + yield(InvalidArgument, arg) + return arg, nil + end + if String === m + m = [s = m] + else + m = m.to_a + s = m[0] + return nil, m unless String === s + end + raise InvalidArgument, arg unless arg.rindex(s, 0) + return nil, m if s.length == arg.length + yield(InvalidArgument, arg) # didn't match whole arg + return arg[s.length..-1], m + end + private :parse_arg + + # + # Parses argument, converts and returns +arg+, +block+ and result of + # conversion. Yields at semi-error condition instead of raising an + # exception. + # + def conv_arg(arg, val = nil) + if conv + val = conv.call(*val) + else + val = proc {|val| val}.call(*val) + end + return arg, block, val + end + private :conv_arg + + # + # Produces the summary text. Each line of the summary is yielded to the + # block (without newline). + # + # +sdone+:: Already summarized short style options keyed hash. + # +ldone+:: Already summarized long style options keyed hash. + # +width+:: Width of left side (option part). In other words, the right + # side (description part) starts after +width+ columns. + # +max+:: Maximum width of left side -> the options are filled within + # +max+ columns. + # +indent+:: Prefix string indents all summarized lines. + # + def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "") + sopts, lopts, s = [], [], nil + @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short + @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long + return if sopts.empty? and lopts.empty? # completely hidden + + left = [sopts.join(', ')] + right = desc.dup + + while s = lopts.shift + l = left[-1].length + s.length + l += arg.length if left.size == 1 && arg + l < max or sopts.empty? or left << '' + left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s + end + + left[0] << arg if arg + mlen = left.collect {|s| s.length}.max.to_i + while mlen > width and l = left.shift + mlen = left.collect {|s| s.length}.max.to_i if l.length == mlen + yield(indent + l) + end + + while begin l = left.shift; r = right.shift; l or r end + l = l.to_s.ljust(width) + ' ' + r if r and !r.empty? + yield(indent + l) + end + + self + end + + def add_banner(to) # :nodoc: + unless @short or @long + s = desc.join + to << " [" + s + "]..." unless s.empty? + end + to + end + + def match_nonswitch?(str) # :nodoc: + @pattern =~ str unless @short or @long + end + + # + # Main name of the switch. + # + def switch_name + (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '') + end + + # + # Switch that takes no arguments. + # + class NoArgument < self + + # + # Raises an exception if any arguments given. + # + def parse(arg, argv) + yield(NeedlessArgument, arg) if arg + conv_arg(arg) + end + + def self.incompatible_argument_styles(*) + end + + def self.pattern + Object + end + end + + # + # Switch that takes an argument. + # + class RequiredArgument < self + + # + # Raises an exception if argument is not present. + # + def parse(arg, argv) + unless arg + raise MissingArgument if argv.empty? + arg = argv.shift + end + conv_arg(*parse_arg(arg) {|*exc| raise(*exc)}) + end + end + + # + # Switch that can omit argument. + # + class OptionalArgument < self + + # + # Parses argument if given, or uses default value. + # + def parse(arg, argv, &error) + if arg + conv_arg(*parse_arg(arg, &error)) + else + conv_arg(arg) + end + end + end + + # + # Switch that takes an argument, which does not begin with '-'. + # + class PlacedArgument < self + + # + # Returns nil if argument is not present or begins with '-'. + # + def parse(arg, argv, &error) + if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0])) + return nil, block, nil + end + opt = (val = parse_arg(val, &error))[1] + val = conv_arg(*val) + if opt and !arg + argv.shift + else + val[0] = nil + end + val + end + end + end + + # + # Simple option list providing mapping from short and/or long option + # string to OptionParser::Switch and mapping from acceptable argument to + # matching pattern and converter pair. Also provides summary feature. + # + class List + # Map from acceptable argument types to pattern and converter pairs. + attr_reader :atype + + # Map from short style option switches to actual switch objects. + attr_reader :short + + # Map from long style option switches to actual switch objects. + attr_reader :long + + # List of all switches and summary string. + attr_reader :list + + # + # Just initializes all instance variables. + # + def initialize + @atype = {} + @short = OptionMap.new + @long = OptionMap.new + @list = [] + end + + # + # See OptionParser.accept. + # + def accept(t, pat = /.*/nm, &block) + if pat + pat.respond_to?(:match) or raise TypeError, "has no `match'" + else + pat = t if t.respond_to?(:match) + end + unless block + block = pat.method(:convert).to_proc if pat.respond_to?(:convert) + end + @atype[t] = [pat, block] + end + + # + # See OptionParser.reject. + # + def reject(t) + @atype.delete(t) + end + + # + # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+. + # + # +sw+:: OptionParser::Switch instance to be added. + # +sopts+:: Short style option list. + # +lopts+:: Long style option list. + # +nlopts+:: Negated long style options list. + # + def update(sw, sopts, lopts, nsw = nil, nlopts = nil) + o = nil + sopts.each {|o| @short[o] = sw} if sopts + lopts.each {|o| @long[o] = sw} if lopts + nlopts.each {|o| @long[o] = nsw} if nsw and nlopts + used = @short.invert.update(@long.invert) + @list.delete_if {|o| Switch === o and !used[o]} + end + private :update + + # + # Inserts +switch+ at the head of the list, and associates short, long + # and negated long options. Arguments are: + # + # +switch+:: OptionParser::Switch instance to be inserted. + # +short_opts+:: List of short style options. + # +long_opts+:: List of long style options. + # +nolong_opts+:: List of long style options with "no-" prefix. + # + # prepend(switch, short_opts, long_opts, nolong_opts) + # + def prepend(*args) + update(*args) + @list.unshift(args[0]) + end + + # + # Appends +switch+ at the tail of the list, and associates short, long + # and negated long options. Arguments are: + # + # +switch+:: OptionParser::Switch instance to be inserted. + # +short_opts+:: List of short style options. + # +long_opts+:: List of long style options. + # +nolong_opts+:: List of long style options with "no-" prefix. + # + # append(switch, short_opts, long_opts, nolong_opts) + # + def append(*args) + update(*args) + @list.push(args[0]) + end + + # + # Searches +key+ in +id+ list. The result is returned or yielded if a + # block is given. If it isn't found, nil is returned. + # + def search(id, key) + if list = __send__(id) + val = list.fetch(key) {return nil} + block_given? ? yield(val) : val + end + end + + # + # Searches list +id+ for +opt+ and the optional patterns for completion + # +pat+. If +icase+ is true, the search is case insensitive. The result + # is returned or yielded if a block is given. If it isn't found, nil is + # returned. + # + def complete(id, opt, icase = false, *pat, &block) + __send__(id).complete(opt, icase, *pat, &block) + end + + # + # Iterates over each option, passing the option to the +block+. + # + def each_option(&block) + list.each(&block) + end + + # + # Creates the summary table, passing each line to the +block+ (without + # newline). The arguments +args+ are passed along to the summarize + # method which is called on every option. + # + def summarize(*args, &block) + list.each do |opt| + if opt.respond_to?(:summarize) # perhaps OptionParser::Switch + opt.summarize(*args, &block) + elsif !opt or opt.empty? + yield("") + else + opt.each(&block) + end + end + end + + def add_banner(to) # :nodoc: + list.each do |opt| + if opt.respond_to?(:add_banner) + opt.add_banner(to) + end + end + to + end + end + + # + # Hash with completion search feature. See OptionParser::Completion. + # + class CompletingHash < Hash + include Completion + + # + # Completion for hash key. + # + def match(key) + return key, *fetch(key) { + raise AmbiguousArgument, catch(:ambiguous) {return complete(key)} + } + end + end + + # :stopdoc: + + # + # Enumeration of acceptable argument styles. Possible values are: + # + # NO_ARGUMENT:: The switch takes no arguments. (:NONE) + # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED) + # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL) + # + # Use like --switch=argument (long style) or -Xargument (short style). For + # short style, only portion matched to argument pattern is dealed as + # argument. + # + ArgumentStyle = {} + NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument} + RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument} + OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument} + ArgumentStyle.freeze + + # + # Switches common used such as '--', and also provides default + # argument classes + # + DefaultList = List.new + DefaultList.short['-'] = Switch::NoArgument.new {} + DefaultList.long[''] = Switch::NoArgument.new {throw :terminate} + + # + # Default options for ARGV, which never appear in option summary. + # + Officious = {} + + # + # --help + # Shows option summary. + # + Officious['help'] = proc do |parser| + Switch::NoArgument.new do + puts parser.help + exit + end + end + + # + # --version + # Shows version string if Version is defined. + # + Officious['version'] = proc do |parser| + Switch::OptionalArgument.new do |pkg| + if pkg + begin + require 'optparse/version' + rescue LoadError + else + show_version(*pkg.split(/,/)) or + abort("#{parser.program_name}: no version found in package #{pkg}") + exit + end + end + v = parser.ver or abort("#{parser.program_name}: version unknown") + puts v + exit + end + end + + # :startdoc: + + # + # Class methods + # + + # + # Initializes a new instance and evaluates the optional block in context + # of the instance. Arguments +args+ are passed to #new, see there for + # description of parameters. + # + # This method is *deprecated*, its behavior corresponds to the older #new + # method. + # + def self.with(*args, &block) + opts = new(*args) + opts.instance_eval(&block) + opts + end + + # + # Returns an incremented value of +default+ according to +arg+. + # + def self.inc(arg, default = nil) + case arg + when Integer + arg.nonzero? + when nil + default.to_i + 1 + end + end + def inc(*args) + self.class.inc(*args) + end + + # + # Initializes the instance and yields itself if called with a block. + # + # +banner+:: Banner message. + # +width+:: Summary width. + # +indent+:: Summary indent. + # + def initialize(banner = nil, width = 32, indent = ' ' * 4) + @stack = [DefaultList, List.new, List.new] + @program_name = nil + @banner = banner + @summary_width = width + @summary_indent = indent + @default_argv = ARGV + add_officious + yield self if block_given? + end + + def add_officious # :nodoc: + list = base() + Officious.each do |opt, block| + list.long[opt] ||= block.call(self) + end + end + + # + # Terminates option parsing. Optional parameter +arg+ is a string pushed + # back to be the first non-option argument. + # + def terminate(arg = nil) + self.class.terminate(arg) + end + def self.terminate(arg = nil) + throw :terminate, arg + end + + @stack = [DefaultList] + def self.top() DefaultList end + + # + # Directs to accept specified class +t+. The argument string is passed to + # the block in which it should be converted to the desired class. + # + # +t+:: Argument class specifier, any object including Class. + # +pat+:: Pattern for argument, defaults to +t+ if it responds to match. + # + # accept(t, pat, &block) + # + def accept(*args, &blk) top.accept(*args, &blk) end + # + # See #accept. + # + def self.accept(*args, &blk) top.accept(*args, &blk) end + + # + # Directs to reject specified class argument. + # + # +t+:: Argument class speficier, any object including Class. + # + # reject(t) + # + def reject(*args, &blk) top.reject(*args, &blk) end + # + # See #reject. + # + def self.reject(*args, &blk) top.reject(*args, &blk) end + + # + # Instance methods + # + + # Heading banner preceding summary. + attr_writer :banner + + # Program name to be emitted in error message and default banner, + # defaults to $0. + attr_writer :program_name + + # Width for option list portion of summary. Must be Numeric. + attr_accessor :summary_width + + # Indentation for summary. Must be String (or have + String method). + attr_accessor :summary_indent + + # Strings to be parsed in default. + attr_accessor :default_argv + + # + # Heading banner preceding summary. + # + def banner + unless @banner + @banner = "Usage: #{program_name} [options]" + visit(:add_banner, @banner) + end + @banner + end + + # + # Program name to be emitted in error message and default banner, defaults + # to $0. + # + def program_name + @program_name || File.basename($0, '.*') + end + + # for experimental cascading :-) + alias set_banner banner= + alias set_program_name program_name= + alias set_summary_width summary_width= + alias set_summary_indent summary_indent= + + # Version + attr_writer :version + # Release code + attr_writer :release + + # + # Version + # + def version + @version || (defined?(::Version) && ::Version) + end + + # + # Release code + # + def release + @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE) + end + + # + # Returns version string from program_name, version and release. + # + def ver + if v = version + str = "#{program_name} #{[v].join('.')}" + str << " (#{v})" if v = release + str + end + end + + def warn(mesg = $!) + super("#{program_name}: #{mesg}") + end + + def abort(mesg = $!) + super("#{program_name}: #{mesg}") + end + + # + # Subject of #on / #on_head, #accept / #reject + # + def top + @stack[-1] + end + + # + # Subject of #on_tail. + # + def base + @stack[1] + end + + # + # Pushes a new List. + # + def new + @stack.push(List.new) + if block_given? + yield self + else + self + end + end + + # + # Removes the last List. + # + def remove + @stack.pop + end + + # + # Puts option summary into +to+ and returns +to+. Yields each line if + # a block is given. + # + # +to+:: Output destination, which must have method <<. Defaults to []. + # +width+:: Width of left side, defaults to @summary_width. + # +max+:: Maximum length allowed for left side, defaults to +width+ - 1. + # +indent+:: Indentation, defaults to @summary_indent. + # + def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk) + visit(:summarize, {}, {}, width, max, indent, &(blk || proc {|l| to << l + $/})) + to + end + + # + # Returns option summary string. + # + def help; summarize(banner.to_s.sub(/\n?\z/, "\n")) end + alias to_s help + + # + # Returns option summary list. + # + def to_a; summarize(banner.to_a.dup) end + + # + # Checks if an argument is given twice, in which case an ArgumentError is + # raised. Called from OptionParser#switch only. + # + # +obj+:: New argument. + # +prv+:: Previously specified argument. + # +msg+:: Exception message. + # + def notwice(obj, prv, msg) + unless !prv or prv == obj + begin + raise ArgumentError, "argument #{msg} given twice: #{obj}" + rescue + $@[0, 2] = nil + raise + end + end + obj + end + private :notwice + + # + # Creates an OptionParser::Switch from the parameters. The parsed argument + # value is passed to the given block, where it can be processed. + # + # See at the beginning of OptionParser for some full examples. + # + # +opts+ can include the following elements: + # + # [Argument style:] + # One of the following: + # :NONE, :REQUIRED, :OPTIONAL + # + # [Argument pattern:] + # Acceptable option argument format, must be pre-defined with + # OptionParser.accept or OptionParser#accept, or Regexp. This can appear + # once or assigned as String if not present, otherwise causes an + # ArgumentError. Examples: + # Float, Time, Array + # + # [Possible argument values:] + # Hash or Array. + # [:text, :binary, :auto] + # %w[iso-2022-jp shift_jis euc-jp utf8 binary] + # { "jis" => "iso-2022-jp", "sjis" => "shift_jis" } + # + # [Long style switch:] + # Specifies a long style switch which takes a mandatory, optional or no + # argument. It's a string of the following form: + # "--switch=MANDATORY" or "--switch MANDATORY" + # "--switch[=OPTIONAL]" + # "--switch" + # + # [Short style switch:] + # Specifies short style switch which takes a mandatory, optional or no + # argument. It's a string of the following form: + # "-xMANDATORY" + # "-x[OPTIONAL]" + # "-x" + # There is also a special form which matches character range (not full + # set of regural expression): + # "-[a-z]MANDATORY" + # "-[a-z][OPTIONAL]" + # "-[a-z]" + # + # [Argument style and description:] + # Instead of specifying mandatory or optional orguments directly in the + # switch parameter, this separate parameter can be used. + # "=MANDATORY" + # "=[OPTIONAL]" + # + # [Description:] + # Description string for the option. + # "Run verbosely" + # + # [Handler:] + # Handler for the parsed argument value. Either give a block or pass a + # Proc or Method as an argument. + # + def make_switch(opts, block = nil) + short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], [] + ldesc, sdesc, desc, arg = [], [], [] + default_style = Switch::NoArgument + default_pattern = nil + klass = nil + o = nil + n, q, a = nil + + opts.each do |o| + # argument class + next if search(:atype, o) do |pat, c| + klass = notwice(o, klass, 'type') + if not_style and not_style != Switch::NoArgument + not_pattern, not_conv = pat, c + else + default_pattern, conv = pat, c + end + end + + # directly specified pattern(any object possible to match) + if !(String === o) and o.respond_to?(:match) + pattern = notwice(o, pattern, 'pattern') + conv = (pattern.method(:convert).to_proc if pattern.respond_to?(:convert)) + next + end + + # anything others + case o + when Proc, Method + block = notwice(o, block, 'block') + when Array, Hash + case pattern + when CompletingHash + when nil + pattern = CompletingHash.new + conv = (pattern.method(:convert).to_proc if pattern.respond_to?(:convert)) + else + raise ArgumentError, "argument pattern given twice" + end + o.each {|(o, *v)| pattern[o] = v.fetch(0) {o}} + when Module + raise ArgumentError, "unsupported argument type: #{o}" + when *ArgumentStyle.keys + style = notwice(ArgumentStyle[o], style, 'style') + when /^--no-([^\[\]=\s]*)(.+)?/ + q, a = $1, $2 + o = notwice(a ? Object : TrueClass, klass, 'type') + not_pattern, not_conv = search(:atype, o) unless not_style + not_style = (not_style || default_style).guess(arg = a) if a + default_style = Switch::NoArgument + default_pattern, conv = search(:atype, FalseClass) unless default_pattern + ldesc << "--no-#{q}" + long << 'no-' + (q = q.downcase) + nolong << q + when /^--\[no-\]([^\[\]=\s]*)(.+)?/ + q, a = $1, $2 + o = notwice(a ? Object : TrueClass, klass, 'type') + if a + default_style = default_style.guess(arg = a) + default_pattern, conv = search(:atype, o) unless default_pattern + end + ldesc << "--[no-]#{q}" + long << (o = q.downcase) + not_pattern, not_conv = search(:atype, FalseClass) unless not_style + not_style = Switch::NoArgument + nolong << 'no-' + o + when /^--([^\[\]=\s]*)(.+)?/ + q, a = $1, $2 + if a + o = notwice(NilClass, klass, 'type') + default_style = default_style.guess(arg = a) + default_pattern, conv = search(:atype, o) unless default_pattern + end + ldesc << "--#{q}" + long << (o = q.downcase) + when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/ + q, a = $1, $2 + o = notwice(Object, klass, 'type') + if a + default_style = default_style.guess(arg = a) + default_pattern, conv = search(:atype, o) unless default_pattern + end + sdesc << "-#{q}" + short << Regexp.new(q) + when /^-(.)(.+)?/ + q, a = $1, $2 + if a + o = notwice(NilClass, klass, 'type') + default_style = default_style.guess(arg = a) + default_pattern, conv = search(:atype, o) unless default_pattern + end + sdesc << "-#{q}" + short << q + when /^=/ + style = notwice(default_style.guess(arg = o), style, 'style') + default_pattern, conv = search(:atype, Object) unless default_pattern + else + desc.push(o) + end + end + + default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern + if !(short.empty? and long.empty?) + s = (style || default_style).new(pattern || default_pattern, + conv, sdesc, ldesc, arg, desc, block) + elsif !block + raise ArgumentError, "no switch given" if style or pattern + s = desc + else + short << pattern + s = (style || default_style).new(pattern, + conv, nil, nil, arg, desc, block) + end + return s, short, long, + (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style), + nolong + end + + def define(*opts, &block) + top.append(*(sw = make_switch(opts, block))) + sw[0] + end + + # + # Add option switch and handler. See #make_switch for an explanation of + # parameters. + # + def on(*opts, &block) + define(*opts, &block) + self + end + alias def_option define + + def define_head(*opts, &block) + top.prepend(*(sw = make_switch(opts, block))) + sw[0] + end + + # + # Add option switch like with #on, but at head of summary. + # + def on_head(*opts, &block) + define_head(*opts, &block) + self + end + alias def_head_option define_head + + def define_tail(*opts, &block) + base.append(*(sw = make_switch(opts, block))) + sw[0] + end + + # + # Add option switch like with #on, but at tail of summary. + # + def on_tail(*opts, &block) + define_tail(*opts, &block) + self + end + alias def_tail_option define_tail + + # + # Add separator in summary. + # + def separator(string) + top.append(string, nil, nil) + end + + # + # Parses command line arguments +argv+ in order. When a block is given, + # each non-option argument is yielded. + # + # Returns the rest of +argv+ left unparsed. + # + def order(*argv, &block) + argv = argv[0].dup if argv.size == 1 and Array === argv[0] + order!(argv, &block) + end + + # + # Same as #order, but removes switches destructively. + # + def order!(argv = default_argv, &nonopt) + parse_in_order(argv, &nonopt) + end + + def parse_in_order(argv = default_argv, setter = nil, &nonopt) # :nodoc: + opt, arg, sw, val, rest = nil + nonopt ||= proc {|arg| throw :terminate, arg} + argv.unshift(arg) if arg = catch(:terminate) { + while arg = argv.shift + case arg + # long option + when /\A--([^=]*)(?:=(.*))?/nm + opt, rest = $1, $2 + begin + sw, = complete(:long, opt, true) + rescue ParseError + raise $!.set_option(arg, true) + end + begin + opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)} + val = cb.call(val) if cb + setter.call(sw.switch_name, val) if setter + rescue ParseError + raise $!.set_option(arg, rest) + end + + # short option + when /\A-(.)((=).*|.+)?/nm + opt, has_arg, eq, val, rest = $1, $3, $3, $2, $2 + begin + sw, = search(:short, opt) + unless sw + begin + sw, = complete(:short, opt) + # short option matched. + val = arg.sub(/\A-/, '') + has_arg = true + rescue InvalidOption + # if no short options match, try completion with long + # options. + sw, = complete(:long, opt) + eq ||= !rest + end + end + rescue ParseError + raise $!.set_option(arg, true) + end + begin + opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq} + raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}" + argv.unshift(opt) if opt and (opt = opt.sub(/\A-*/, '-')) != '-' + val = cb.call(val) if cb + setter.call(sw.switch_name, val) if setter + rescue ParseError + raise $!.set_option(arg, arg.length > 2) + end + + # non-option argument + else + catch(:prune) do + visit(:each_option) do |sw| + sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg) + end + nonopt.call(arg) + end + end + end + + nil + } + + visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern} + + argv + end + private :parse_in_order + + # + # Parses command line arguments +argv+ in permutation mode and returns + # list of non-option arguments. + # + def permute(*argv) + argv = argv[0].dup if argv.size == 1 and Array === argv[0] + permute!(argv) + end + + # + # Same as #permute, but removes switches destructively. + # + def permute!(argv = default_argv) + nonopts = [] + arg = nil + order!(argv) {|arg| nonopts << arg} + argv[0, 0] = nonopts + argv + end + + # + # Parses command line arguments +argv+ in order when environment variable + # POSIXLY_CORRECT is set, and in permutation mode otherwise. + # + def parse(*argv) + argv = argv[0].dup if argv.size == 1 and Array === argv[0] + parse!(argv) + end + + # + # Same as #parse, but removes switches destructively. + # + def parse!(argv = default_argv) + if ENV.include?('POSIXLY_CORRECT') + order!(argv) + else + permute!(argv) + end + end + + # + # Wrapper method for getopts.rb. + # + # params = ARGV.getopts("ab:", "foo", "bar:") + # # params[:a] = true # -a + # # params[:b] = "1" # -b1 + # # params[:foo] = "1" # --foo + # # params[:bar] = "x" # --bar x + # + def getopts(*args) + argv = Array === args.first ? args.shift : default_argv + single_options, *long_options = *args + + result = {} + + single_options.scan(/(.)(:)?/) do |opt, val| + if val + result[opt] = nil + define("-#{opt} VAL") + else + result[opt] = false + define("-#{opt}") + end + end if single_options + + long_options.each do |arg| + opt, val = arg.split(':', 2) + if val + result[opt] = val.empty? ? nil : val + define("--#{opt} VAL") + else + result[opt] = false + define("--#{opt}") + end + end + + parse_in_order(argv, result.method(:[]=)) + result + end + + # + # See #getopts. + # + def self.getopts(*args) + new.getopts(*args) + end + + # + # Traverses @stack, sending each element method +id+ with +args+ and + # +block+. + # + def visit(id, *args, &block) + el = nil + @stack.reverse_each do |el| + el.send(id, *args, &block) + end + nil + end + private :visit + + # + # Searches +key+ in @stack for +id+ hash and returns or yields the result. + # + def search(id, key) + block_given = block_given? + visit(:search, id, key) do |k| + return block_given ? yield(k) : k + end + end + private :search + + # + # Completes shortened long style option switch and returns pair of + # canonical switch and switch descriptor OptionParser::Switch. + # + # +id+:: Searching table. + # +opt+:: Searching key. + # +icase+:: Search case insensitive if true. + # +pat+:: Optional pattern for completion. + # + def complete(typ, opt, icase = false, *pat) + if pat.empty? + search(typ, opt) {|sw| return [sw, opt]} # exact match or... + end + raise AmbiguousOption, catch(:ambiguous) { + visit(:complete, typ, opt, icase, *pat) {|opt, *sw| return sw} + raise InvalidOption, opt + } + end + private :complete + + # + # Loads options from file names as +filename+. Does nothing when the file + # is not present. Returns whether successfully loaded. + # + # +filename+ defaults to basename of the program without suffix in a + # directory ~/.options. + # + def load(filename = nil) + begin + filename ||= File.expand_path(File.basename($0, '.*'), '~/.options') + rescue + return false + end + begin + parse(*IO.readlines(filename).each {|s| s.chomp!}) + true + rescue Errno::ENOENT, Errno::ENOTDIR + false + end + end + + # + # Parses environment variable +env+ or its uppercase with splitting like a + # shell. + # + # +env+ defaults to the basename of the program. + # + def environment(env = File.basename($0, '.*')) + env = ENV[env] || ENV[env.upcase] or return + require 'shellwords' + parse(*Shellwords.shellwords(env)) + end + + # + # Acceptable argument classes + # + + # + # Any string and no conversion. This is fall-back. + # + accept(Object) {|s,|s or s.nil?} + + accept(NilClass) {|s,|s} + + # + # Any non-empty string, and no conversion. + # + accept(String, /.+/nm) {|s,*|s} + + # + # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal + # for 0x, and decimal for others; with optional sign prefix. Converts to + # Integer. + # + decimal = '\d+(?:_\d+)*' + binary = 'b[01]+(?:_[01]+)*' + hex = 'x[\da-f]+(?:_[\da-f]+)*' + octal = "0(?:[0-7]*(?:_[0-7]+)*|#{binary}|#{hex})" + integer = "#{octal}|#{decimal}" + accept(Integer, %r"\A[-+]?(?:#{integer})"io) {|s,| Integer(s) if s} + + # + # Float number format, and converts to Float. + # + float = "(?:#{decimal}(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?" + floatpat = %r"\A[-+]?#{float}"io + accept(Float, floatpat) {|s,| s.to_f if s} + + # + # Generic numeric format, converts to Integer for integer format, Float + # for float format. + # + accept(Numeric, %r"\A[-+]?(?:#{octal}|#{float})"io) {|s,| eval(s) if s} + + # + # Decimal integer format, to be converted to Integer. + # + DecimalInteger = /\A[-+]?#{decimal}/io + accept(DecimalInteger) {|s,| s.to_i if s} + + # + # Ruby/C like octal/hexadecimal/binary integer format, to be converted to + # Integer. + # + OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))/io + accept(OctalInteger) {|s,| s.oct if s} + + # + # Decimal integer/float number format, to be converted to Integer for + # integer format, Float for float format. + # + DecimalNumeric = floatpat # decimal integer is allowed as float also. + accept(DecimalNumeric) {|s,| eval(s) if s} + + # + # Boolean switch, which means whether it is present or not, whether it is + # absent or not with prefix no-, or it takes an argument + # yes/no/true/false/+/-. + # + yesno = CompletingHash.new + %w[- no false].each {|el| yesno[el] = false} + %w[+ yes true].each {|el| yesno[el] = true} + yesno['nil'] = false # shoud be nil? + accept(TrueClass, yesno) {|arg, val| val == nil or val} + # + # Similar to TrueClass, but defaults to false. + # + accept(FalseClass, yesno) {|arg, val| val != nil and val} + + # + # List of strings separated by ",". + # + accept(Array) do |s,| + if s + s = s.split(',').collect {|s| s unless s.empty?} + end + s + end + + # + # Regular expression with options. + # + accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o| + f = 0 + if o + f |= Regexp::IGNORECASE if /i/ =~ o + f |= Regexp::MULTILINE if /m/ =~ o + f |= Regexp::EXTENDED if /x/ =~ o + k = o.delete("^imx") + end + Regexp.new(s || all, f, k) + end + + # + # Exceptions + # + + # + # Base class of exceptions from OptionParser. + # + class ParseError < RuntimeError + # Reason which caused the error. + Reason = 'parse error'.freeze + + def initialize(*args) + @args = args + @reason = nil + end + + attr_reader :args + attr_writer :reason + + # + # Pushes back erred argument(s) to +argv+. + # + def recover(argv) + argv[0, 0] = @args + argv + end + + def set_option(opt, eq) + if eq + @args[0] = opt + else + @args.unshift(opt) + end + self + end + + # + # Returns error reason. Override this for I18N. + # + def reason + @reason || self.class::Reason + end + + def inspect + "#<#{self.class.to_s}: #{args.join(' ')}>" + end + + # + # Default stringizing method to emit standard error message. + # + def message + reason + ': ' + args.join(' ') + end + + alias to_s message + end + + # + # Raises when ambiguously completable string is encountered. + # + class AmbiguousOption < ParseError + const_set(:Reason, 'ambiguous option'.freeze) + end + + # + # Raises when there is an argument for a switch which takes no argument. + # + class NeedlessArgument < ParseError + const_set(:Reason, 'needless argument'.freeze) + end + + # + # Raises when a switch with mandatory argument has no argument. + # + class MissingArgument < ParseError + const_set(:Reason, 'missing argument'.freeze) + end + + # + # Raises when switch is undefined. + # + class InvalidOption < ParseError + const_set(:Reason, 'invalid option'.freeze) + end + + # + # Raises when the given argument does not match required format. + # + class InvalidArgument < ParseError + const_set(:Reason, 'invalid argument'.freeze) + end + + # + # Raises when the given argument word can't be completed uniquely. + # + class AmbiguousArgument < InvalidArgument + const_set(:Reason, 'ambiguous argument'.freeze) + end + + # + # Miscellaneous + # + + # + # Extends command line arguments array (ARGV) to parse itself. + # + module Arguable + + # + # Sets OptionParser object, when +opt+ is +false+ or +nil+, methods + # OptionParser::Arguable#options and OptionParser::Arguable#options= are + # undefined. Thus, there is no ways to access the OptionParser object + # via the receiver object. + # + def options=(opt) + unless @optparse = opt + class << self + undef_method(:options) + undef_method(:options=) + end + end + end + + # + # Actual OptionParser object, automatically created if nonexistent. + # + # If called with a block, yields the OptionParser object and returns the + # result of the block. If an OptionParser::ParseError exception occurs + # in the block, it is rescued, a error message printed to STDERR and + # +nil+ returned. + # + def options + @optparse ||= OptionParser.new + @optparse.default_argv = self + block_given? or return @optparse + begin + yield @optparse + rescue ParseError + @optparse.warn $! + nil + end + end + + # + # Parses +self+ destructively in order and returns +self+ containing the + # rest arguments left unparsed. + # + def order!(&blk) options.order!(self, &blk) end + + # + # Parses +self+ destructively in permutation mode and returns +self+ + # containing the rest arguments left unparsed. + # + def permute!() options.permute!(self) end + + # + # Parses +self+ destructively and returns +self+ containing the + # rest arguments left unparsed. + # + def parse!() options.parse!(self) end + + # + # Substitution of getopts is possible as follows. Also see + # OptionParser#getopts. + # + # def getopts(*args) + # ($OPT = ARGV.getopts(*args)).each do |opt, val| + # eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val" + # end + # rescue OptionParser::ParseError + # end + # + def getopts(*args) + options.getopts(self, *args) + end + + # + # Initializes instance variable. + # + def self.extend_object(obj) + super + obj.instance_eval {@optparse = nil} + end + def initialize(*args) + super + @optparse = nil + end + end + + # + # Acceptable argument classes. Now contains DecimalInteger, OctalInteger + # and DecimalNumeric. See Acceptable argument classes (in source code). + # + module Acceptables + const_set(:DecimalInteger, OptionParser::DecimalInteger) + const_set(:OctalInteger, OptionParser::OctalInteger) + const_set(:DecimalNumeric, OptionParser::DecimalNumeric) + end +end + +# ARGV is arguable by OptionParser +ARGV.extend(OptionParser::Arguable) + +if $0 == __FILE__ + Version = OptionParser::Version + ARGV.options {|q| + q.parse!.empty? or puts "what's #{ARGV.join(' ')}?" + } or abort(ARGV.options.to_s) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/date.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/date.rb new file mode 100644 index 00000000..d680559f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/date.rb @@ -0,0 +1,17 @@ +require 'optparse' +require 'date' + +OptionParser.accept(DateTime) do |s,| + begin + DateTime.parse(s) if s + rescue ArgumentError + raise OptionParser::InvalidArgument, s + end +end +OptionParser.accept(Date) do |s,| + begin + Date.parse(s) if s + rescue ArgumentError + raise OptionParser::InvalidArgument, s + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/shellwords.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/shellwords.rb new file mode 100644 index 00000000..0422d7c8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/shellwords.rb @@ -0,0 +1,6 @@ +# -*- ruby -*- + +require 'shellwords' +require 'optparse' + +OptionParser.accept(Shellwords) {|s,| Shellwords.shellwords(s)} diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/time.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/time.rb new file mode 100644 index 00000000..402cadcf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/time.rb @@ -0,0 +1,10 @@ +require 'optparse' +require 'time' + +OptionParser.accept(Time) do |s,| + begin + (Time.httpdate(s) rescue Time.parse(s)) if s + rescue + raise OptionParser::InvalidArgument, s + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/uri.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/uri.rb new file mode 100644 index 00000000..024dc69e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/uri.rb @@ -0,0 +1,6 @@ +# -*- ruby -*- + +require 'optparse' +require 'uri' + +OptionParser.accept(URI) {|s,| URI.parse(s) if s} diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/version.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/version.rb new file mode 100644 index 00000000..558d9d71 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/optparse/version.rb @@ -0,0 +1,70 @@ +# OptionParser internal utility + +class << OptionParser + def show_version(*pkg) + progname = ARGV.options.program_name + result = false + show = proc do |klass, cname, version| + str = "#{progname}" + unless klass == ::Object and cname == :VERSION + version = version.join(".") if Array === version + str << ": #{klass}" unless klass == Object + str << " version #{version}" + end + [:Release, :RELEASE].find do |rel| + if klass.const_defined?(rel) + str << " (#{klass.const_get(rel)})" + end + end + puts str + result = true + end + if pkg.size == 1 and pkg[0] == "all" + self.search_const(::Object, /\AV(?:ERSION|ersion)\z/) do |klass, cname, version| + unless cname[1] == ?e and klass.const_defined?(:Version) + show.call(klass, cname.intern, version) + end + end + else + pkg.each do |pkg| + begin + pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)} + v = case + when pkg.const_defined?(:Version) + pkg.const_get(n = :Version) + when pkg.const_defined?(:VERSION) + pkg.const_get(n = :VERSION) + else + n = nil + "unknown" + end + show.call(pkg, n, v) + rescue NameError + end + end + end + result + end + + def each_const(path, klass = ::Object) + path.split(/::|\//).inject(klass) do |klass, name| + raise NameError, path unless Module === klass + klass.constants.grep(/#{name}/i) do |c| + klass.const_defined?(c) or next + c = klass.const_get(c) + end + end + end + + def search_const(klass, name) + klasses = [klass] + while klass = klasses.shift + klass.constants.each do |cname| + klass.const_defined?(cname) or next + const = klass.const_get(cname) + yield klass, cname, const if name === cname + klasses << const if Module === const and const != ::Object + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/ostruct.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/ostruct.rb new file mode 100644 index 00000000..6af5bbda --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/ostruct.rb @@ -0,0 +1,146 @@ +# +# = ostruct.rb: OpenStruct implementation +# +# Author:: Yukihiro Matsumoto +# Documentation:: Gavin Sinclair +# +# OpenStruct allows the creation of data objects with arbitrary attributes. +# See OpenStruct for an example. +# + +# +# OpenStruct allows you to create data objects and set arbitrary attributes. +# For example: +# +# require 'ostruct' +# +# record = OpenStruct.new +# record.name = "John Smith" +# record.age = 70 +# record.pension = 300 +# +# puts record.name # -> "John Smith" +# puts record.address # -> nil +# +# It is like a hash with a different way to access the data. In fact, it is +# implemented with a hash, and you can initialize it with one. +# +# hash = { "country" => "Australia", :population => 20_000_000 } +# data = OpenStruct.new(hash) +# +# p data # -> +# +class OpenStruct + # + # Create a new OpenStruct object. The optional +hash+, if given, will + # generate attributes and values. For example. + # + # require 'ostruct' + # hash = { "country" => "Australia", :population => 20_000_000 } + # data = OpenStruct.new(hash) + # + # p data # -> + # + # By default, the resulting OpenStruct object will have no attributes. + # + def initialize(hash=nil) + @table = {} + if hash + for k,v in hash + @table[k.to_sym] = v + new_ostruct_member(k) + end + end + end + + # Duplicate an OpenStruct object members. + def initialize_copy(orig) + super + @table = @table.dup + end + + def marshal_dump + @table + end + def marshal_load(x) + @table = x + @table.each_key{|key| new_ostruct_member(key)} + end + + def new_ostruct_member(name) + name = name.to_sym + unless self.respond_to?(name) + meta = class << self; self; end + meta.send(:define_method, name) { @table[name] } + meta.send(:define_method, :"#{name}=") { |x| @table[name] = x } + end + end + + def method_missing(mid, *args) # :nodoc: + mname = mid.id2name + len = args.length + if mname =~ /=$/ + if len != 1 + raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) + end + if self.frozen? + raise TypeError, "can't modify frozen #{self.class}", caller(1) + end + mname.chop! + self.new_ostruct_member(mname) + @table[mname.intern] = args[0] + elsif len == 0 + @table[mid] + else + raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1) + end + end + + # + # Remove the named field from the object. + # + def delete_field(name) + @table.delete name.to_sym + end + + InspectKey = :__inspect_key__ # :nodoc: + + # + # Returns a string containing a detailed summary of the keys and values. + # + def inspect + str = "#<#{self.class}" + + Thread.current[InspectKey] ||= [] + if Thread.current[InspectKey].include?(self) then + str << " ..." + else + first = true + for k,v in @table + str << "," unless first + first = false + + Thread.current[InspectKey] << v + begin + str << " #{k}=#{v.inspect}" + ensure + Thread.current[InspectKey].pop + end + end + end + + str << ">" + end + alias :to_s :inspect + + attr_reader :table # :nodoc: + protected :table + + # + # Compare this object and +other+ for equality. + # + def ==(other) + return false unless(other.kind_of?(OpenStruct)) + return @table == other.table + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/parsearg.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/parsearg.rb new file mode 100644 index 00000000..9c4d0f1d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/parsearg.rb @@ -0,0 +1,87 @@ +# +# parsearg.rb - parse arguments +# $Release Version: $ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Yasuo OHBA(SHL Japan Inc. Technology Dept.) +# +# -- +# +# +# + +warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: parsearg is deprecated after Ruby 1.8.1; use optparse instead" + +$RCS_ID=%q$Header$ + +require "getopts" + +def printUsageAndExit() + if $USAGE + eval($USAGE) + end + exit() +end + +def setParenthesis(ex, opt, c) + if opt != "" + ex = sprintf("%s$OPT_%s%s", ex, opt, c) + else + ex = sprintf("%s%s", ex, c) + end + return ex +end + +def setOrAnd(ex, opt, c) + if opt != "" + ex = sprintf("%s$OPT_%s %s%s ", ex, opt, c, c) + else + ex = sprintf("%s %s%s ", ex, c, c) + end + return ex +end + +def setExpression(ex, opt, op) + if !op + ex = sprintf("%s$OPT_%s", ex, opt) + return ex + end + case op.chr + when "(", ")" + ex = setParenthesis(ex, opt, op.chr) + when "|", "&" + ex = setOrAnd(ex, opt, op.chr) + else + return nil + end + return ex +end + +# parseArgs is obsolete. Use OptionParser instead. + +def parseArgs(argc, nopt, single_opts, *opts) + if (noOptions = getopts(single_opts, *opts)) == nil + printUsageAndExit() + end + if nopt + ex = nil + pos = 0 + for o in nopt.split(/[()|&]/) + pos += o.length + ex = setExpression(ex, o, nopt[pos]) + pos += 1 + end + begin + if !eval(ex) + printUsageAndExit() + end + rescue + print "Format Error!! : \"" + nopt + "\"\t[parseArgs]\n" + exit!(-1) + end + end + if ARGV.length < argc + printUsageAndExit() + end + return noOptions +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/parsedate.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/parsedate.rb new file mode 100644 index 00000000..b52a79ba --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/parsedate.rb @@ -0,0 +1,53 @@ +# +# = parsedate.rb: Parses dates +# +# Author:: Tadayoshi Funaba +# Documentation:: Konrad Meyer +# +# ParseDate munches on a date and turns it into an array of values. +# + +# +# ParseDate converts a date into an array of values. +# For example: +# +# require 'parsedate' +# +# ParseDate.parsedate "Tuesday, July 6th, 2007, 18:35:20 UTC" +# # => [2007, 7, 6, 18, 35, 20, "UTC", 2] +# +# The order is of the form [year, month, day of month, hour, minute, second, +# timezone, day of the week]. + +require 'date/format' + +module ParseDate + # + # Parse a string representation of a date into values. + # For example: + # + # require 'parsedate' + # + # ParseDate.parsedate "Tuesday, July 5th, 2007, 18:35:20 UTC" + # # => [2007, 7, 5, 18, 35, 20, "UTC", 2] + # + # The order is of the form [year, month, day of month, hour, minute, + # second, timezone, day of week]. + # + # ParseDate.parsedate can also take a second argument, +comp+, which + # is a boolean telling the method to compensate for dates with years + # expressed as two digits. Example: + # + # require 'parsedate' + # + # ParseDate.parsedate "Mon Dec 25 00 06:53:24 UTC", true + # # => [2000, 12, 25, 6, 53, 24, "UTC", 1] + # + def parsedate(str, comp=false) + Date._parse(str, comp). + values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday) + end + + module_function :parsedate + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pathname.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pathname.rb new file mode 100644 index 00000000..e4ca5489 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pathname.rb @@ -0,0 +1,1062 @@ +# +# = pathname.rb +# +# Object-Oriented Pathname Class +# +# Author:: Tanaka Akira +# Documentation:: Author and Gavin Sinclair +# +# For documentation, see class Pathname. +# +# pathname.rb is distributed with Ruby since 1.8.0. +# + +# +# == Pathname +# +# Pathname represents a pathname which locates a file in a filesystem. +# The pathname depends on OS: Unix, Windows, etc. +# Pathname library works with pathnames of local OS. +# However non-Unix pathnames are supported experimentally. +# +# It does not represent the file itself. +# A Pathname can be relative or absolute. It's not until you try to +# reference the file that it even matters whether the file exists or not. +# +# Pathname is immutable. It has no method for destructive update. +# +# The value of this class is to manipulate file path information in a neater +# way than standard Ruby provides. The examples below demonstrate the +# difference. *All* functionality from File, FileTest, and some from Dir and +# FileUtils is included, in an unsurprising way. It is essentially a facade for +# all of these, and more. +# +# == Examples +# +# === Example 1: Using Pathname +# +# require 'pathname' +# p = Pathname.new("/usr/bin/ruby") +# size = p.size # 27662 +# isdir = p.directory? # false +# dir = p.dirname # Pathname:/usr/bin +# base = p.basename # Pathname:ruby +# dir, base = p.split # [Pathname:/usr/bin, Pathname:ruby] +# data = p.read +# p.open { |f| _ } +# p.each_line { |line| _ } +# +# === Example 2: Using standard Ruby +# +# p = "/usr/bin/ruby" +# size = File.size(p) # 27662 +# isdir = File.directory?(p) # false +# dir = File.dirname(p) # "/usr/bin" +# base = File.basename(p) # "ruby" +# dir, base = File.split(p) # ["/usr/bin", "ruby"] +# data = File.read(p) +# File.open(p) { |f| _ } +# File.foreach(p) { |line| _ } +# +# === Example 3: Special features +# +# p1 = Pathname.new("/usr/lib") # Pathname:/usr/lib +# p2 = p1 + "ruby/1.8" # Pathname:/usr/lib/ruby/1.8 +# p3 = p1.parent # Pathname:/usr +# p4 = p2.relative_path_from(p3) # Pathname:lib/ruby/1.8 +# pwd = Pathname.pwd # Pathname:/home/gavin +# pwd.absolute? # true +# p5 = Pathname.new "." # Pathname:. +# p5 = p5 + "music/../articles" # Pathname:music/../articles +# p5.cleanpath # Pathname:articles +# p5.realpath # Pathname:/home/gavin/articles +# p5.children # [Pathname:/home/gavin/articles/linux, ...] +# +# == Breakdown of functionality +# +# === Core methods +# +# These methods are effectively manipulating a String, because that's all a path +# is. Except for #mountpoint?, #children, and #realpath, they don't access the +# filesystem. +# +# - + +# - #join +# - #parent +# - #root? +# - #absolute? +# - #relative? +# - #relative_path_from +# - #each_filename +# - #cleanpath +# - #realpath +# - #children +# - #mountpoint? +# +# === File status predicate methods +# +# These methods are a facade for FileTest: +# - #blockdev? +# - #chardev? +# - #directory? +# - #executable? +# - #executable_real? +# - #exist? +# - #file? +# - #grpowned? +# - #owned? +# - #pipe? +# - #readable? +# - #world_readable? +# - #readable_real? +# - #setgid? +# - #setuid? +# - #size +# - #size? +# - #socket? +# - #sticky? +# - #symlink? +# - #writable? +# - #world_writable? +# - #writable_real? +# - #zero? +# +# === File property and manipulation methods +# +# These methods are a facade for File: +# - #atime +# - #ctime +# - #mtime +# - #chmod(mode) +# - #lchmod(mode) +# - #chown(owner, group) +# - #lchown(owner, group) +# - #fnmatch(pattern, *args) +# - #fnmatch?(pattern, *args) +# - #ftype +# - #make_link(old) +# - #open(*args, &block) +# - #readlink +# - #rename(to) +# - #stat +# - #lstat +# - #make_symlink(old) +# - #truncate(length) +# - #utime(atime, mtime) +# - #basename(*args) +# - #dirname +# - #extname +# - #expand_path(*args) +# - #split +# +# === Directory methods +# +# These methods are a facade for Dir: +# - Pathname.glob(*args) +# - Pathname.getwd / Pathname.pwd +# - #rmdir +# - #entries +# - #each_entry(&block) +# - #mkdir(*args) +# - #opendir(*args) +# +# === IO +# +# These methods are a facade for IO: +# - #each_line(*args, &block) +# - #read(*args) +# - #readlines(*args) +# - #sysopen(*args) +# +# === Utilities +# +# These methods are a mixture of Find, FileUtils, and others: +# - #find(&block) +# - #mkpath +# - #rmtree +# - #unlink / #delete +# +# +# == Method documentation +# +# As the above section shows, most of the methods in Pathname are facades. The +# documentation for these methods generally just says, for instance, "See +# FileTest.writable?", as you should be familiar with the original method +# anyway, and its documentation (e.g. through +ri+) will contain more +# information. In some cases, a brief description will follow. +# +class Pathname + + # :stopdoc: + if RUBY_VERSION < "1.9" + TO_PATH = :to_str + else + # to_path is implemented so Pathname objects are usable with File.open, etc. + TO_PATH = :to_path + end + # :startdoc: + + # + # Create a Pathname object from the given String (or String-like object). + # If +path+ contains a NUL character (\0), an ArgumentError is raised. + # + def initialize(path) + path = path.__send__(TO_PATH) if path.respond_to? TO_PATH + @path = path.dup + + if /\0/ =~ @path + raise ArgumentError, "pathname contains \\0: #{@path.inspect}" + end + + self.taint if @path.tainted? + end + + def freeze() super; @path.freeze; self end + def taint() super; @path.taint; self end + def untaint() super; @path.untaint; self end + + # + # Compare this pathname with +other+. The comparison is string-based. + # Be aware that two different paths (foo.txt and ./foo.txt) + # can refer to the same file. + # + def ==(other) + return false unless Pathname === other + other.to_s == @path + end + alias === == + alias eql? == + + # Provides for comparing pathnames, case-sensitively. + def <=>(other) + return nil unless Pathname === other + @path.tr('/', "\0") <=> other.to_s.tr('/', "\0") + end + + def hash # :nodoc: + @path.hash + end + + # Return the path as a String. + def to_s + @path.dup + end + + # to_path is implemented so Pathname objects are usable with File.open, etc. + alias_method TO_PATH, :to_s + + def inspect # :nodoc: + "#<#{self.class}:#{@path}>" + end + + # Return a pathname which is substituted by String#sub. + def sub(pattern, *rest, &block) + self.class.new(@path.sub(pattern, *rest, &block)) + end + + if File::ALT_SEPARATOR + SEPARATOR_PAT = /[#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}]/ + else + SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/ + end + + # chop_basename(path) -> [pre-basename, basename] or nil + def chop_basename(path) + base = File.basename(path) + if /\A#{SEPARATOR_PAT}?\z/ =~ base + return nil + else + return path[0, path.rindex(base)], base + end + end + private :chop_basename + + # split_names(path) -> prefix, [name, ...] + def split_names(path) + names = [] + while r = chop_basename(path) + path, basename = r + names.unshift basename + end + return path, names + end + private :split_names + + def prepend_prefix(prefix, relpath) + if relpath.empty? + File.dirname(prefix) + elsif /#{SEPARATOR_PAT}/ =~ prefix + prefix = File.dirname(prefix) + prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a' + prefix + relpath + else + prefix + relpath + end + end + private :prepend_prefix + + # Returns clean pathname of +self+ with consecutive slashes and useless dots + # removed. The filesystem is not accessed. + # + # If +consider_symlink+ is +true+, then a more conservative algorithm is used + # to avoid breaking symbolic linkages. This may retain more .. + # entries than absolutely necessary, but without accessing the filesystem, + # this can't be avoided. See #realpath. + # + def cleanpath(consider_symlink=false) + if consider_symlink + cleanpath_conservative + else + cleanpath_aggressive + end + end + + # + # Clean the path simply by resolving and removing excess "." and ".." entries. + # Nothing more, nothing less. + # + def cleanpath_aggressive + path = @path + names = [] + pre = path + while r = chop_basename(pre) + pre, base = r + case base + when '.' + when '..' + names.unshift base + else + if names[0] == '..' + names.shift + else + names.unshift base + end + end + end + if /#{SEPARATOR_PAT}/o =~ File.basename(pre) + names.shift while names[0] == '..' + end + self.class.new(prepend_prefix(pre, File.join(*names))) + end + private :cleanpath_aggressive + + # has_trailing_separator?(path) -> bool + def has_trailing_separator?(path) + if r = chop_basename(path) + pre, basename = r + pre.length + basename.length < path.length + else + false + end + end + private :has_trailing_separator? + + # add_trailing_separator(path) -> path + def add_trailing_separator(path) + if File.basename(path + 'a') == 'a' + path + else + File.join(path, "") # xxx: Is File.join is appropriate to add separator? + end + end + private :add_trailing_separator + + def del_trailing_separator(path) + if r = chop_basename(path) + pre, basename = r + pre + basename + elsif /#{SEPARATOR_PAT}+\z/o =~ path + $` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o] + else + path + end + end + private :del_trailing_separator + + def cleanpath_conservative + path = @path + names = [] + pre = path + while r = chop_basename(pre) + pre, base = r + names.unshift base if base != '.' + end + if /#{SEPARATOR_PAT}/o =~ File.basename(pre) + names.shift while names[0] == '..' + end + if names.empty? + self.class.new(File.dirname(pre)) + else + if names.last != '..' && File.basename(path) == '.' + names << '.' + end + result = prepend_prefix(pre, File.join(*names)) + if /\A(?:\.|\.\.)\z/ !~ names.last && has_trailing_separator?(path) + self.class.new(add_trailing_separator(result)) + else + self.class.new(result) + end + end + end + private :cleanpath_conservative + + def realpath_rec(prefix, unresolved, h) + resolved = [] + until unresolved.empty? + n = unresolved.shift + if n == '.' + next + elsif n == '..' + resolved.pop + else + path = prepend_prefix(prefix, File.join(*(resolved + [n]))) + if h.include? path + if h[path] == :resolving + raise Errno::ELOOP.new(path) + else + prefix, *resolved = h[path] + end + else + s = File.lstat(path) + if s.symlink? + h[path] = :resolving + link_prefix, link_names = split_names(File.readlink(path)) + if link_prefix == '' + prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h) + else + prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h) + end + else + resolved << n + h[path] = [prefix, *resolved] + end + end + end + end + return prefix, *resolved + end + private :realpath_rec + + # + # Returns a real (absolute) pathname of +self+ in the actual filesystem. + # The real pathname doesn't contain symlinks or useless dots. + # + # No arguments should be given; the old behaviour is *obsoleted*. + # + def realpath + path = @path + prefix, names = split_names(path) + if prefix == '' + prefix, names2 = split_names(Dir.pwd) + names = names2 + names + end + prefix, *names = realpath_rec(prefix, names, {}) + self.class.new(prepend_prefix(prefix, File.join(*names))) + end + + # #parent returns the parent directory. + # + # This is same as self + '..'. + def parent + self + '..' + end + + # #mountpoint? returns +true+ if self points to a mountpoint. + def mountpoint? + begin + stat1 = self.lstat + stat2 = self.parent.lstat + stat1.dev == stat2.dev && stat1.ino == stat2.ino || + stat1.dev != stat2.dev + rescue Errno::ENOENT + false + end + end + + # + # #root? is a predicate for root directories. I.e. it returns +true+ if the + # pathname consists of consecutive slashes. + # + # It doesn't access actual filesystem. So it may return +false+ for some + # pathnames which points to roots such as /usr/... + # + def root? + !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path) + end + + # Predicate method for testing whether a path is absolute. + # It returns +true+ if the pathname begins with a slash. + def absolute? + !relative? + end + + # The opposite of #absolute? + def relative? + path = @path + while r = chop_basename(path) + path, basename = r + end + path == '' + end + + # + # Iterates over each component of the path. + # + # Pathname.new("/usr/bin/ruby").each_filename {|filename| ... } + # # yields "usr", "bin", and "ruby". + # + def each_filename # :yield: filename + prefix, names = split_names(@path) + names.each {|filename| yield filename } + nil + end + + # Iterates over and yields a new Pathname object + # for each element in the given path in descending order. + # + # Pathname.new('/path/to/some/file.rb').descend {|v| p v} + # # + # # + # # + # # + # # + # + # Pathname.new('path/to/some/file.rb').descend {|v| p v} + # # + # # + # # + # # + # + # It doesn't access actual filesystem. + # + # This method is available since 1.8.5. + # + def descend + vs = [] + ascend {|v| vs << v } + vs.reverse_each {|v| yield v } + nil + end + + # Iterates over and yields a new Pathname object + # for each element in the given path in ascending order. + # + # Pathname.new('/path/to/some/file.rb').ascend {|v| p v} + # # + # # + # # + # # + # # + # + # Pathname.new('path/to/some/file.rb').ascend {|v| p v} + # # + # # + # # + # # + # + # It doesn't access actual filesystem. + # + # This method is available since 1.8.5. + # + def ascend + path = @path + yield self + while r = chop_basename(path) + path, name = r + break if path.empty? + yield self.class.new(del_trailing_separator(path)) + end + end + + # + # Pathname#+ appends a pathname fragment to this one to produce a new Pathname + # object. + # + # p1 = Pathname.new("/usr") # Pathname:/usr + # p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby + # p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd + # + # This method doesn't access the file system; it is pure string manipulation. + # + def +(other) + other = Pathname.new(other) unless Pathname === other + Pathname.new(plus(@path, other.to_s)) + end + + def plus(path1, path2) # -> path + prefix2 = path2 + index_list2 = [] + basename_list2 = [] + while r2 = chop_basename(prefix2) + prefix2, basename2 = r2 + index_list2.unshift prefix2.length + basename_list2.unshift basename2 + end + return path2 if prefix2 != '' + prefix1 = path1 + while true + while !basename_list2.empty? && basename_list2.first == '.' + index_list2.shift + basename_list2.shift + end + break unless r1 = chop_basename(prefix1) + prefix1, basename1 = r1 + next if basename1 == '.' + if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..' + prefix1 = prefix1 + basename1 + break + end + index_list2.shift + basename_list2.shift + end + r1 = chop_basename(prefix1) + if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1) + while !basename_list2.empty? && basename_list2.first == '..' + index_list2.shift + basename_list2.shift + end + end + if !basename_list2.empty? + suffix2 = path2[index_list2.first..-1] + r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2 + else + r1 ? prefix1 : File.dirname(prefix1) + end + end + private :plus + + # + # Pathname#join joins pathnames. + # + # path0.join(path1, ..., pathN) is the same as + # path0 + path1 + ... + pathN. + # + def join(*args) + args.unshift self + result = args.pop + result = Pathname.new(result) unless Pathname === result + return result if result.absolute? + args.reverse_each {|arg| + arg = Pathname.new(arg) unless Pathname === arg + result = arg + result + return result if result.absolute? + } + result + end + + # + # Returns the children of the directory (files and subdirectories, not + # recursive) as an array of Pathname objects. By default, the returned + # pathnames will have enough information to access the files. If you set + # +with_directory+ to +false+, then the returned pathnames will contain the + # filename only. + # + # For example: + # p = Pathname("/usr/lib/ruby/1.8") + # p.children + # # -> [ Pathname:/usr/lib/ruby/1.8/English.rb, + # Pathname:/usr/lib/ruby/1.8/Env.rb, + # Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ] + # p.children(false) + # # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ] + # + # Note that the result never contain the entries . and .. in + # the directory because they are not children. + # + # This method has existed since 1.8.1. + # + def children(with_directory=true) + with_directory = false if @path == '.' + result = [] + Dir.foreach(@path) {|e| + next if e == '.' || e == '..' + if with_directory + result << self.class.new(File.join(@path, e)) + else + result << self.class.new(e) + end + } + result + end + + # + # #relative_path_from returns a relative path from the argument to the + # receiver. If +self+ is absolute, the argument must be absolute too. If + # +self+ is relative, the argument must be relative too. + # + # #relative_path_from doesn't access the filesystem. It assumes no symlinks. + # + # ArgumentError is raised when it cannot find a relative path. + # + # This method has existed since 1.8.1. + # + def relative_path_from(base_directory) + dest_directory = self.cleanpath.to_s + base_directory = base_directory.cleanpath.to_s + dest_prefix = dest_directory + dest_names = [] + while r = chop_basename(dest_prefix) + dest_prefix, basename = r + dest_names.unshift basename if basename != '.' + end + base_prefix = base_directory + base_names = [] + while r = chop_basename(base_prefix) + base_prefix, basename = r + base_names.unshift basename if basename != '.' + end + if dest_prefix != base_prefix + raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}" + end + while !dest_names.empty? && + !base_names.empty? && + dest_names.first == base_names.first + dest_names.shift + base_names.shift + end + if base_names.include? '..' + raise ArgumentError, "base_directory has ..: #{base_directory.inspect}" + end + base_names.fill('..') + relpath_names = base_names + dest_names + if relpath_names.empty? + Pathname.new('.') + else + Pathname.new(File.join(*relpath_names)) + end + end +end + +class Pathname # * IO * + # + # #each_line iterates over the line in the file. It yields a String object + # for each line. + # + # This method has existed since 1.8.1. + # + def each_line(*args, &block) # :yield: line + IO.foreach(@path, *args, &block) + end + + # Pathname#foreachline is *obsoleted* at 1.8.1. Use #each_line. + def foreachline(*args, &block) + warn "Pathname#foreachline is obsoleted. Use Pathname#each_line." + each_line(*args, &block) + end + + # See IO.read. Returns all the bytes from the file, or the first +N+ + # if specified. + def read(*args) IO.read(@path, *args) end + + # See IO.readlines. Returns all the lines from the file. + def readlines(*args) IO.readlines(@path, *args) end + + # See IO.sysopen. + def sysopen(*args) IO.sysopen(@path, *args) end +end + + +class Pathname # * File * + + # See File.atime. Returns last access time. + def atime() File.atime(@path) end + + # See File.ctime. Returns last (directory entry, not file) change time. + def ctime() File.ctime(@path) end + + # See File.mtime. Returns last modification time. + def mtime() File.mtime(@path) end + + # See File.chmod. Changes permissions. + def chmod(mode) File.chmod(mode, @path) end + + # See File.lchmod. + def lchmod(mode) File.lchmod(mode, @path) end + + # See File.chown. Change owner and group of file. + def chown(owner, group) File.chown(owner, group, @path) end + + # See File.lchown. + def lchown(owner, group) File.lchown(owner, group, @path) end + + # See File.fnmatch. Return +true+ if the receiver matches the given + # pattern. + def fnmatch(pattern, *args) File.fnmatch(pattern, @path, *args) end + + # See File.fnmatch? (same as #fnmatch). + def fnmatch?(pattern, *args) File.fnmatch?(pattern, @path, *args) end + + # See File.ftype. Returns "type" of file ("file", "directory", + # etc). + def ftype() File.ftype(@path) end + + # See File.link. Creates a hard link. + def make_link(old) File.link(old, @path) end + + # See File.open. Opens the file for reading or writing. + def open(*args, &block) # :yield: file + File.open(@path, *args, &block) + end + + # See File.readlink. Read symbolic link. + def readlink() self.class.new(File.readlink(@path)) end + + # See File.rename. Rename the file. + def rename(to) File.rename(@path, to) end + + # See File.stat. Returns a File::Stat object. + def stat() File.stat(@path) end + + # See File.lstat. + def lstat() File.lstat(@path) end + + # See File.symlink. Creates a symbolic link. + def make_symlink(old) File.symlink(old, @path) end + + # See File.truncate. Truncate the file to +length+ bytes. + def truncate(length) File.truncate(@path, length) end + + # See File.utime. Update the access and modification times. + def utime(atime, mtime) File.utime(atime, mtime, @path) end + + # See File.basename. Returns the last component of the path. + def basename(*args) self.class.new(File.basename(@path, *args)) end + + # See File.dirname. Returns all but the last component of the path. + def dirname() self.class.new(File.dirname(@path)) end + + # See File.extname. Returns the file's extension. + def extname() File.extname(@path) end + + # See File.expand_path. + def expand_path(*args) self.class.new(File.expand_path(@path, *args)) end + + # See File.split. Returns the #dirname and the #basename in an + # Array. + def split() File.split(@path).map {|f| self.class.new(f) } end + + # Pathname#link is confusing and *obsoleted* because the receiver/argument + # order is inverted to corresponding system call. + def link(old) + warn 'Pathname#link is obsoleted. Use Pathname#make_link.' + File.link(old, @path) + end + + # Pathname#symlink is confusing and *obsoleted* because the receiver/argument + # order is inverted to corresponding system call. + def symlink(old) + warn 'Pathname#symlink is obsoleted. Use Pathname#make_symlink.' + File.symlink(old, @path) + end +end + + +class Pathname # * FileTest * + + # See FileTest.blockdev?. + def blockdev?() FileTest.blockdev?(@path) end + + # See FileTest.chardev?. + def chardev?() FileTest.chardev?(@path) end + + # See FileTest.executable?. + def executable?() FileTest.executable?(@path) end + + # See FileTest.executable_real?. + def executable_real?() FileTest.executable_real?(@path) end + + # See FileTest.exist?. + def exist?() FileTest.exist?(@path) end + + # See FileTest.grpowned?. + def grpowned?() FileTest.grpowned?(@path) end + + # See FileTest.directory?. + def directory?() FileTest.directory?(@path) end + + # See FileTest.file?. + def file?() FileTest.file?(@path) end + + # See FileTest.pipe?. + def pipe?() FileTest.pipe?(@path) end + + # See FileTest.socket?. + def socket?() FileTest.socket?(@path) end + + # See FileTest.owned?. + def owned?() FileTest.owned?(@path) end + + # See FileTest.readable?. + def readable?() FileTest.readable?(@path) end + + # See FileTest.world_readable?. + def world_readable?() FileTest.world_readable?(@path) end + + # See FileTest.readable_real?. + def readable_real?() FileTest.readable_real?(@path) end + + # See FileTest.setuid?. + def setuid?() FileTest.setuid?(@path) end + + # See FileTest.setgid?. + def setgid?() FileTest.setgid?(@path) end + + # See FileTest.size. + def size() FileTest.size(@path) end + + # See FileTest.size?. + def size?() FileTest.size?(@path) end + + # See FileTest.sticky?. + def sticky?() FileTest.sticky?(@path) end + + # See FileTest.symlink?. + def symlink?() FileTest.symlink?(@path) end + + # See FileTest.writable?. + def writable?() FileTest.writable?(@path) end + + # See FileTest.world_writable?. + def world_writable?() FileTest.world_writable?(@path) end + + # See FileTest.writable_real?. + def writable_real?() FileTest.writable_real?(@path) end + + # See FileTest.zero?. + def zero?() FileTest.zero?(@path) end +end + + +class Pathname # * Dir * + # See Dir.glob. Returns or yields Pathname objects. + def Pathname.glob(*args) # :yield: p + if block_given? + Dir.glob(*args) {|f| yield self.new(f) } + else + Dir.glob(*args).map {|f| self.new(f) } + end + end + + # See Dir.getwd. Returns the current working directory as a Pathname. + def Pathname.getwd() self.new(Dir.getwd) end + class << self; alias pwd getwd end + + # Pathname#chdir is *obsoleted* at 1.8.1. + def chdir(&block) + warn "Pathname#chdir is obsoleted. Use Dir.chdir." + Dir.chdir(@path, &block) + end + + # Pathname#chroot is *obsoleted* at 1.8.1. + def chroot + warn "Pathname#chroot is obsoleted. Use Dir.chroot." + Dir.chroot(@path) + end + + # Return the entries (files and subdirectories) in the directory, each as a + # Pathname object. + def entries() Dir.entries(@path).map {|f| self.class.new(f) } end + + # Iterates over the entries (files and subdirectories) in the directory. It + # yields a Pathname object for each entry. + # + # This method has existed since 1.8.1. + def each_entry(&block) # :yield: p + Dir.foreach(@path) {|f| yield self.class.new(f) } + end + + # Pathname#dir_foreach is *obsoleted* at 1.8.1. + def dir_foreach(*args, &block) + warn "Pathname#dir_foreach is obsoleted. Use Pathname#each_entry." + each_entry(*args, &block) + end + + # See Dir.mkdir. Create the referenced directory. + def mkdir(*args) Dir.mkdir(@path, *args) end + + # See Dir.rmdir. Remove the referenced directory. + def rmdir() Dir.rmdir(@path) end + + # See Dir.open. + def opendir(&block) # :yield: dir + Dir.open(@path, &block) + end +end + + +class Pathname # * Find * + # + # Pathname#find is an iterator to traverse a directory tree in a depth first + # manner. It yields a Pathname for each file under "this" directory. + # + # Since it is implemented by find.rb, Find.prune can be used + # to control the traverse. + # + # If +self+ is ., yielded pathnames begin with a filename in the + # current directory, not ./. + # + def find(&block) # :yield: p + require 'find' + if @path == '.' + Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) } + else + Find.find(@path) {|f| yield self.class.new(f) } + end + end +end + + +class Pathname # * FileUtils * + # See FileUtils.mkpath. Creates a full path, including any + # intermediate directories that don't yet exist. + def mkpath + require 'fileutils' + FileUtils.mkpath(@path) + nil + end + + # See FileUtils.rm_r. Deletes a directory and all beneath it. + def rmtree + # The name "rmtree" is borrowed from File::Path of Perl. + # File::Path provides "mkpath" and "rmtree". + require 'fileutils' + FileUtils.rm_r(@path) + nil + end +end + + +class Pathname # * mixed * + # Removes a file or directory, using File.unlink or + # Dir.unlink as necessary. + def unlink() + begin + Dir.unlink @path + rescue Errno::ENOTDIR + File.unlink @path + end + end + alias delete unlink + + # This method is *obsoleted* at 1.8.1. Use #each_line or #each_entry. + def foreach(*args, &block) + warn "Pathname#foreach is obsoleted. Use each_line or each_entry." + if FileTest.directory? @path + # For polymorphism between Dir.foreach and IO.foreach, + # Pathname#foreach doesn't yield Pathname object. + Dir.foreach(@path, *args, &block) + else + IO.foreach(@path, *args, &block) + end + end +end + +module Kernel + # create a pathname object. + # + # This method is available since 1.8.5. + def Pathname(path) # :doc: + Pathname.new(path) + end + private :Pathname +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/ping.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/ping.rb new file mode 100644 index 00000000..c2966b61 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/ping.rb @@ -0,0 +1,64 @@ +# +# = ping.rb: Check a host for upness +# +# Author:: Yukihiro Matsumoto +# Documentation:: Konrad Meyer +# +# Performs the function of the basic network testing tool, ping. +# See: Ping. +# + +require 'timeout' +require "socket" + +# +# Ping contains routines to test for the reachability of remote hosts. +# Currently the only routine implemented is pingecho(). +# +# Ping.pingecho uses a TCP echo (not an ICMP echo) to determine if the +# remote host is reachable. This is usually adequate to tell that a remote +# host is available to telnet, ftp, or ssh to. +# +# Warning: Ping.pingecho may block for a long time if DNS resolution is +# slow. Requiring 'resolv-replace' allows non-blocking name resolution. +# +# Usage: +# +# require 'ping' +# +# puts "'jimmy' is alive and kicking" if Ping.pingecho('jimmy', 10) +# +module Ping + + # + # Return true if we can open a connection to the hostname or IP address + # +host+ on port +service+ (which defaults to the "echo" port) waiting up + # to +timeout+ seconds. + # + # Example: + # + # require 'ping' + # + # Ping.pingecho "google.com", 10, 80 + # + def pingecho(host, timeout=5, service="echo") + begin + timeout(timeout) do + s = TCPSocket.new(host, service) + s.close + end + rescue Errno::ECONNREFUSED + return true + rescue Timeout::Error, StandardError + return false + end + return true + end + module_function :pingecho +end + +if $0 == __FILE__ + host = ARGV[0] + host ||= "localhost" + printf("%s alive? - %s\n", host, Ping::pingecho(host, 5)) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pp.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pp.rb new file mode 100644 index 00000000..8080d879 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pp.rb @@ -0,0 +1,647 @@ +# == Pretty-printer for Ruby objects. +# +# = Which seems better? +# +# non-pretty-printed output by #p is: +# #, @group_queue=#], []]>, @buffer=[], @newline="\n", @group_stack=[#], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#> +# +# pretty-printed output by #pp is: +# #, +# @group_queue= +# #], +# []]>, +# @group_stack= +# [#], +# @indent=0, +# @maxwidth=79, +# @newline="\n", +# @output=#, +# @output_width=2> +# +# I like the latter. If you do too, this library is for you. +# +# = Usage +# +# pp(obj) +# +# output +obj+ to +$>+ in pretty printed format. +# +# It returns +nil+. +# +# = Output Customization +# To define your customized pretty printing function for your classes, +# redefine a method #pretty_print(+pp+) in the class. +# It takes an argument +pp+ which is an instance of the class PP. +# The method should use PP#text, PP#breakable, PP#nest, PP#group and +# PP#pp to print the object. +# +# = Author +# Tanaka Akira + +require 'prettyprint' + +module Kernel + # returns a pretty printed object as a string. + def pretty_inspect + PP.pp(self, '') + end + + private + # prints arguments in pretty form. + # + # pp returns nil. + def pp(*objs) # :doc: + objs.each {|obj| + PP.pp(obj) + } + nil + end + module_function :pp +end + +class PP < PrettyPrint + # Outputs +obj+ to +out+ in pretty printed format of + # +width+ columns in width. + # + # If +out+ is omitted, +$>+ is assumed. + # If +width+ is omitted, 79 is assumed. + # + # PP.pp returns +out+. + def PP.pp(obj, out=$>, width=79) + q = PP.new(out, width) + q.guard_inspect_key {q.pp obj} + q.flush + #$pp = q + out << "\n" + end + + # Outputs +obj+ to +out+ like PP.pp but with no indent and + # newline. + # + # PP.singleline_pp returns +out+. + def PP.singleline_pp(obj, out=$>) + q = SingleLine.new(out) + q.guard_inspect_key {q.pp obj} + q.flush + out + end + + # :stopdoc: + def PP.mcall(obj, mod, meth, *args, &block) + mod.instance_method(meth).bind(obj).call(*args, &block) + end + # :startdoc: + + @sharing_detection = false + class << self + # Returns the sharing detection flag as a boolean value. + # It is false by default. + attr_accessor :sharing_detection + end + + module PPMethods + InspectKey = :__inspect_key__ + + def guard_inspect_key + if Thread.current[InspectKey] == nil + Thread.current[InspectKey] = [] + end + + save = Thread.current[InspectKey] + + begin + Thread.current[InspectKey] = [] + yield + ensure + Thread.current[InspectKey] = save + end + end + + # Adds +obj+ to the pretty printing buffer + # using Object#pretty_print or Object#pretty_print_cycle. + # + # Object#pretty_print_cycle is used when +obj+ is already + # printed, a.k.a the object reference chain has a cycle. + def pp(obj) + id = obj.__id__ + + if Thread.current[InspectKey].include? id + group {obj.pretty_print_cycle self} + return + end + + begin + Thread.current[InspectKey] << id + group {obj.pretty_print self} + ensure + Thread.current[InspectKey].pop unless PP.sharing_detection + end + end + + # A convenience method which is same as follows: + # + # group(1, '#<' + obj.class.name, '>') { ... } + def object_group(obj, &block) # :yield: + group(1, '#<' + obj.class.name, '>', &block) + end + + def object_address_group(obj, &block) + id = "%x" % (obj.__id__ * 2) + id.sub!(/\Af(?=[[:xdigit:]]{2}+\z)/, '') if id.sub!(/\A\.\./, '') + group(1, "\#<#{obj.class}:0x#{id}", '>', &block) + end + + # A convenience method which is same as follows: + # + # text ',' + # breakable + def comma_breakable + text ',' + breakable + end + + # Adds a separated list. + # The list is separated by comma with breakable space, by default. + # + # #seplist iterates the +list+ using +iter_method+. + # It yields each object to the block given for #seplist. + # The procedure +separator_proc+ is called between each yields. + # + # If the iteration is zero times, +separator_proc+ is not called at all. + # + # If +separator_proc+ is nil or not given, + # +lambda { comma_breakable }+ is used. + # If +iter_method+ is not given, :each is used. + # + # For example, following 3 code fragments has similar effect. + # + # q.seplist([1,2,3]) {|v| xxx v } + # + # q.seplist([1,2,3], lambda { comma_breakable }, :each) {|v| xxx v } + # + # xxx 1 + # q.comma_breakable + # xxx 2 + # q.comma_breakable + # xxx 3 + def seplist(list, sep=nil, iter_method=:each) # :yield: element + sep ||= lambda { comma_breakable } + first = true + list.__send__(iter_method) {|*v| + if first + first = false + else + sep.call + end + yield(*v) + } + end + + def pp_object(obj) + object_address_group(obj) { + seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v| + breakable + v = v.to_s if Symbol === v + text v + text '=' + group(1) { + breakable '' + pp(obj.instance_eval(v)) + } + } + } + end + + def pp_hash(obj) + group(1, '{', '}') { + seplist(obj, nil, :each_pair) {|k, v| + group { + pp k + text '=>' + group(1) { + breakable '' + pp v + } + } + } + } + end + end + + include PPMethods + + class SingleLine < PrettyPrint::SingleLine + include PPMethods + end + + module ObjectMixin + # 1. specific pretty_print + # 2. specific inspect + # 3. specific to_s if instance variable is empty + # 4. generic pretty_print + + # A default pretty printing method for general objects. + # It calls #pretty_print_instance_variables to list instance variables. + # + # If +self+ has a customized (redefined) #inspect method, + # the result of self.inspect is used but it obviously has no + # line break hints. + # + # This module provides predefined #pretty_print methods for some of + # the most commonly used built-in classes for convenience. + def pretty_print(q) + if /\(Kernel\)#/ !~ method(:inspect).inspect + q.text self.inspect + elsif /\(Kernel\)#/ !~ method(:to_s).inspect && instance_variables.empty? + q.text self.to_s + else + q.pp_object(self) + end + end + + # A default pretty printing method for general objects that are + # detected as part of a cycle. + def pretty_print_cycle(q) + q.object_address_group(self) { + q.breakable + q.text '...' + } + end + + # Returns a sorted array of instance variable names. + # + # This method should return an array of names of instance variables as symbols or strings as: + # +[:@a, :@b]+. + def pretty_print_instance_variables + instance_variables.sort + end + + # Is #inspect implementation using #pretty_print. + # If you implement #pretty_print, it can be used as follows. + # + # alias inspect pretty_print_inspect + # + # However, doing this requires that every class that #inspect is called on + # implement #pretty_print, or a RuntimeError will be raised. + def pretty_print_inspect + if /\(PP::ObjectMixin\)#/ =~ method(:pretty_print).inspect + raise "pretty_print is not overridden for #{self.class}" + end + PP.singleline_pp(self, '') + end + end +end + +class Array + def pretty_print(q) + q.group(1, '[', ']') { + q.seplist(self) {|v| + q.pp v + } + } + end + + def pretty_print_cycle(q) + q.text(empty? ? '[]' : '[...]') + end +end + +class Hash + def pretty_print(q) + q.pp_hash self + end + + def pretty_print_cycle(q) + q.text(empty? ? '{}' : '{...}') + end +end + +class << ENV + def pretty_print(q) + q.pp_hash self + end +end + +class Struct + def pretty_print(q) + q.group(1, '#') { + q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member| + q.breakable + q.text member.to_s + q.text '=' + q.group(1) { + q.breakable '' + q.pp self[member] + } + } + } + end + + def pretty_print_cycle(q) + q.text sprintf("#", PP.mcall(self, Kernel, :class).name) + end +end + +class Range + def pretty_print(q) + q.pp self.begin + q.breakable '' + q.text(self.exclude_end? ? '...' : '..') + q.breakable '' + q.pp self.end + end +end + +class File + class Stat + def pretty_print(q) + require 'etc.so' + q.object_group(self) { + q.breakable + q.text sprintf("dev=0x%x", self.dev); q.comma_breakable + q.text "ino="; q.pp self.ino; q.comma_breakable + q.group { + m = self.mode + q.text sprintf("mode=0%o", m) + q.breakable + q.text sprintf("(%s %c%c%c%c%c%c%c%c%c)", + self.ftype, + (m & 0400 == 0 ? ?- : ?r), + (m & 0200 == 0 ? ?- : ?w), + (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) : + (m & 04000 == 0 ? ?x : ?s)), + (m & 0040 == 0 ? ?- : ?r), + (m & 0020 == 0 ? ?- : ?w), + (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) : + (m & 02000 == 0 ? ?x : ?s)), + (m & 0004 == 0 ? ?- : ?r), + (m & 0002 == 0 ? ?- : ?w), + (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) : + (m & 01000 == 0 ? ?x : ?t))) + } + q.comma_breakable + q.text "nlink="; q.pp self.nlink; q.comma_breakable + q.group { + q.text "uid="; q.pp self.uid + begin + pw = Etc.getpwuid(self.uid) + rescue ArgumentError + end + if pw + q.breakable; q.text "(#{pw.name})" + end + } + q.comma_breakable + q.group { + q.text "gid="; q.pp self.gid + begin + gr = Etc.getgrgid(self.gid) + rescue ArgumentError + end + if gr + q.breakable; q.text "(#{gr.name})" + end + } + q.comma_breakable + q.group { + q.text sprintf("rdev=0x%x", self.rdev) + q.breakable + q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor) + } + q.comma_breakable + q.text "size="; q.pp self.size; q.comma_breakable + q.text "blksize="; q.pp self.blksize; q.comma_breakable + q.text "blocks="; q.pp self.blocks; q.comma_breakable + q.group { + t = self.atime + q.text "atime="; q.pp t + q.breakable; q.text "(#{t.tv_sec})" + } + q.comma_breakable + q.group { + t = self.mtime + q.text "mtime="; q.pp t + q.breakable; q.text "(#{t.tv_sec})" + } + q.comma_breakable + q.group { + t = self.ctime + q.text "ctime="; q.pp t + q.breakable; q.text "(#{t.tv_sec})" + } + } + end + end +end + +class MatchData + def pretty_print(q) + q.object_group(self) { + q.breakable + q.seplist(1..self.size, lambda { q.breakable }) {|i| + q.pp self[i-1] + } + } + end +end + +class Object + include PP::ObjectMixin +end + +[Numeric, Symbol, FalseClass, TrueClass, NilClass, Module].each {|c| + c.class_eval { + def pretty_print_cycle(q) + q.text inspect + end + } +} + +[Numeric, FalseClass, TrueClass, Module].each {|c| + c.class_eval { + def pretty_print(q) + q.text inspect + end + } +} + +# :enddoc: +if __FILE__ == $0 + require 'test/unit' + + class PPTest < Test::Unit::TestCase + def test_list0123_12 + assert_equal("[0, 1, 2, 3]\n", PP.pp([0,1,2,3], '', 12)) + end + + def test_list0123_11 + assert_equal("[0,\n 1,\n 2,\n 3]\n", PP.pp([0,1,2,3], '', 11)) + end + + OverriddenStruct = Struct.new("OverriddenStruct", :members, :class) + def test_struct_override_members # [ruby-core:7865] + a = OverriddenStruct.new(1,2) + assert_equal("#\n", PP.pp(a, '')) + end + end + + class HasInspect + def initialize(a) + @a = a + end + + def inspect + return "" + end + end + + class HasPrettyPrint + def initialize(a) + @a = a + end + + def pretty_print(q) + q.text "" + end + end + + class HasBoth + def initialize(a) + @a = a + end + + def inspect + return "" + end + + def pretty_print(q) + q.text "" + end + end + + class PrettyPrintInspect < HasPrettyPrint + alias inspect pretty_print_inspect + end + + class PrettyPrintInspectWithoutPrettyPrint + alias inspect pretty_print_inspect + end + + class PPInspectTest < Test::Unit::TestCase + def test_hasinspect + a = HasInspect.new(1) + assert_equal("\n", PP.pp(a, '')) + end + + def test_hasprettyprint + a = HasPrettyPrint.new(1) + assert_equal("\n", PP.pp(a, '')) + end + + def test_hasboth + a = HasBoth.new(1) + assert_equal("\n", PP.pp(a, '')) + end + + def test_pretty_print_inspect + a = PrettyPrintInspect.new(1) + assert_equal("", a.inspect) + a = PrettyPrintInspectWithoutPrettyPrint.new + assert_raise(RuntimeError) { a.inspect } + end + + def test_proc + a = proc {1} + assert_equal("#{a.inspect}\n", PP.pp(a, '')) + end + + def test_to_s_with_iv + a = Object.new + def a.to_s() "aaa" end + a.instance_eval { @a = nil } + result = PP.pp(a, '') + assert_equal("#{a.inspect}\n", result) + assert_match(/\A#\n\z/m, result) + a = 1.0 + a.instance_eval { @a = nil } + result = PP.pp(a, '') + assert_equal("#{a.inspect}\n", result) + end + + def test_to_s_without_iv + a = Object.new + def a.to_s() "aaa" end + result = PP.pp(a, '') + assert_equal("#{a.inspect}\n", result) + assert_equal("aaa\n", result) + end + end + + class PPCycleTest < Test::Unit::TestCase + def test_array + a = [] + a << a + assert_equal("[[...]]\n", PP.pp(a, '')) + assert_equal("#{a.inspect}\n", PP.pp(a, '')) + end + + def test_hash + a = {} + a[0] = a + assert_equal("{0=>{...}}\n", PP.pp(a, '')) + assert_equal("#{a.inspect}\n", PP.pp(a, '')) + end + + S = Struct.new("S", :a, :b) + def test_struct + a = S.new(1,2) + a.b = a + assert_equal("#>\n", PP.pp(a, '')) + assert_equal("#{a.inspect}\n", PP.pp(a, '')) + end + + def test_object + a = Object.new + a.instance_eval {@a = a} + assert_equal(a.inspect + "\n", PP.pp(a, '')) + end + + def test_anonymous + a = Class.new.new + assert_equal(a.inspect + "\n", PP.pp(a, '')) + end + + def test_withinspect + a = [] + a << HasInspect.new(a) + assert_equal("[]\n", PP.pp(a, '')) + assert_equal("#{a.inspect}\n", PP.pp(a, '')) + end + + def test_share_nil + begin + PP.sharing_detection = true + a = [nil, nil] + assert_equal("[nil, nil]\n", PP.pp(a, '')) + ensure + PP.sharing_detection = false + end + end + end + + class PPSingleLineTest < Test::Unit::TestCase + def test_hash + assert_equal("{1=>1}", PP.singleline_pp({ 1 => 1}, '')) # [ruby-core:02699] + assert_equal("[1#{', 1'*99}]", PP.singleline_pp([1]*100, '')) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/prettyprint.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/prettyprint.rb new file mode 100644 index 00000000..315c422e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/prettyprint.rb @@ -0,0 +1,896 @@ +# $Id$ + +# This class implements a pretty printing algorithm. It finds line breaks and +# nice indentations for grouped structure. +# +# By default, the class assumes that primitive elements are strings and each +# byte in the strings have single column in width. But it can be used for +# other situations by giving suitable arguments for some methods: +# * newline object and space generation block for PrettyPrint.new +# * optional width argument for PrettyPrint#text +# * PrettyPrint#breakable +# +# There are several candidate uses: +# * text formatting using proportional fonts +# * multibyte characters which has columns different to number of bytes +# * non-string formatting +# +# == Bugs +# * Box based formatting? +# * Other (better) model/algorithm? +# +# == References +# Christian Lindig, Strictly Pretty, March 2000, +# http://www.st.cs.uni-sb.de/~lindig/papers/#pretty +# +# Philip Wadler, A prettier printer, March 1998, +# http://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier +# +# == Author +# Tanaka Akira +# +class PrettyPrint + + # This is a convenience method which is same as follows: + # + # begin + # q = PrettyPrint.new(output, maxwidth, newline, &genspace) + # ... + # q.flush + # output + # end + # + def PrettyPrint.format(output='', maxwidth=79, newline="\n", genspace=lambda {|n| ' ' * n}) + q = PrettyPrint.new(output, maxwidth, newline, &genspace) + yield q + q.flush + output + end + + # This is similar to PrettyPrint::format but the result has no breaks. + # + # +maxwidth+, +newline+ and +genspace+ are ignored. + # + # The invocation of +breakable+ in the block doesn't break a line and is + # treated as just an invocation of +text+. + # + def PrettyPrint.singleline_format(output='', maxwidth=nil, newline=nil, genspace=nil) + q = SingleLine.new(output) + yield q + output + end + + # Creates a buffer for pretty printing. + # + # +output+ is an output target. If it is not specified, '' is assumed. It + # should have a << method which accepts the first argument +obj+ of + # PrettyPrint#text, the first argument +sep+ of PrettyPrint#breakable, the + # first argument +newline+ of PrettyPrint.new, and the result of a given + # block for PrettyPrint.new. + # + # +maxwidth+ specifies maximum line length. If it is not specified, 79 is + # assumed. However actual outputs may overflow +maxwidth+ if long + # non-breakable texts are provided. + # + # +newline+ is used for line breaks. "\n" is used if it is not specified. + # + # The block is used to generate spaces. {|width| ' ' * width} is used if it + # is not given. + # + def initialize(output='', maxwidth=79, newline="\n", &genspace) + @output = output + @maxwidth = maxwidth + @newline = newline + @genspace = genspace || lambda {|n| ' ' * n} + + @output_width = 0 + @buffer_width = 0 + @buffer = [] + + root_group = Group.new(0) + @group_stack = [root_group] + @group_queue = GroupQueue.new(root_group) + @indent = 0 + end + attr_reader :output, :maxwidth, :newline, :genspace + attr_reader :indent, :group_queue + + def current_group + @group_stack.last + end + + # first? is a predicate to test the call is a first call to first? with + # current group. + # + # It is useful to format comma separated values as: + # + # q.group(1, '[', ']') { + # xxx.each {|yyy| + # unless q.first? + # q.text ',' + # q.breakable + # end + # ... pretty printing yyy ... + # } + # } + # + # first? is obsoleted in 1.8.2. + # + def first? + warn "PrettyPrint#first? is obsoleted at 1.8.2." + current_group.first? + end + + def break_outmost_groups + while @maxwidth < @output_width + @buffer_width + return unless group = @group_queue.deq + until group.breakables.empty? + data = @buffer.shift + @output_width = data.output(@output, @output_width) + @buffer_width -= data.width + end + while !@buffer.empty? && Text === @buffer.first + text = @buffer.shift + @output_width = text.output(@output, @output_width) + @buffer_width -= text.width + end + end + end + + # This adds +obj+ as a text of +width+ columns in width. + # + # If +width+ is not specified, obj.length is used. + # + def text(obj, width=obj.length) + if @buffer.empty? + @output << obj + @output_width += width + else + text = @buffer.last + unless Text === text + text = Text.new + @buffer << text + end + text.add(obj, width) + @buffer_width += width + break_outmost_groups + end + end + + def fill_breakable(sep=' ', width=sep.length) + group { breakable sep, width } + end + + # This tells "you can break a line here if necessary", and a +width+\-column + # text +sep+ is inserted if a line is not broken at the point. + # + # If +sep+ is not specified, " " is used. + # + # If +width+ is not specified, +sep.length+ is used. You will have to + # specify this when +sep+ is a multibyte character, for example. + # + def breakable(sep=' ', width=sep.length) + group = @group_stack.last + if group.break? + flush + @output << @newline + @output << @genspace.call(@indent) + @output_width = @indent + @buffer_width = 0 + else + @buffer << Breakable.new(sep, width, self) + @buffer_width += width + break_outmost_groups + end + end + + # Groups line break hints added in the block. The line break hints are all + # to be used or not. + # + # If +indent+ is specified, the method call is regarded as nested by + # nest(indent) { ... }. + # + # If +open_obj+ is specified, text open_obj, open_width is called + # before grouping. If +close_obj+ is specified, text close_obj, + # close_width is called after grouping. + # + def group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length) + text open_obj, open_width + group_sub { + nest(indent) { + yield + } + } + text close_obj, close_width + end + + def group_sub + group = Group.new(@group_stack.last.depth + 1) + @group_stack.push group + @group_queue.enq group + begin + yield + ensure + @group_stack.pop + if group.breakables.empty? + @group_queue.delete group + end + end + end + + # Increases left margin after newline with +indent+ for line breaks added in + # the block. + # + def nest(indent) + @indent += indent + begin + yield + ensure + @indent -= indent + end + end + + # outputs buffered data. + # + def flush + @buffer.each {|data| + @output_width = data.output(@output, @output_width) + } + @buffer.clear + @buffer_width = 0 + end + + class Text + def initialize + @objs = [] + @width = 0 + end + attr_reader :width + + def output(out, output_width) + @objs.each {|obj| out << obj} + output_width + @width + end + + def add(obj, width) + @objs << obj + @width += width + end + end + + class Breakable + def initialize(sep, width, q) + @obj = sep + @width = width + @pp = q + @indent = q.indent + @group = q.current_group + @group.breakables.push self + end + attr_reader :obj, :width, :indent + + def output(out, output_width) + @group.breakables.shift + if @group.break? + out << @pp.newline + out << @pp.genspace.call(@indent) + @indent + else + @pp.group_queue.delete @group if @group.breakables.empty? + out << @obj + output_width + @width + end + end + end + + class Group + def initialize(depth) + @depth = depth + @breakables = [] + @break = false + end + attr_reader :depth, :breakables + + def break + @break = true + end + + def break? + @break + end + + def first? + if defined? @first + false + else + @first = false + true + end + end + end + + class GroupQueue + def initialize(*groups) + @queue = [] + groups.each {|g| enq g} + end + + def enq(group) + depth = group.depth + @queue << [] until depth < @queue.length + @queue[depth] << group + end + + def deq + @queue.each {|gs| + (gs.length-1).downto(0) {|i| + unless gs[i].breakables.empty? + group = gs.slice!(i, 1).first + group.break + return group + end + } + gs.each {|group| group.break} + gs.clear + } + return nil + end + + def delete(group) + @queue[group.depth].delete(group) + end + end + + class SingleLine + def initialize(output, maxwidth=nil, newline=nil) + @output = output + @first = [true] + end + + def text(obj, width=nil) + @output << obj + end + + def breakable(sep=' ', width=nil) + @output << sep + end + + def nest(indent) + yield + end + + def group(indent=nil, open_obj='', close_obj='', open_width=nil, close_width=nil) + @first.push true + @output << open_obj + yield + @output << close_obj + @first.pop + end + + def flush + end + + def first? + result = @first[-1] + @first[-1] = false + result + end + end +end + +if __FILE__ == $0 + require 'test/unit' + + class WadlerExample < Test::Unit::TestCase # :nodoc: + def setup + @tree = Tree.new("aaaa", Tree.new("bbbbb", Tree.new("ccc"), + Tree.new("dd")), + Tree.new("eee"), + Tree.new("ffff", Tree.new("gg"), + Tree.new("hhh"), + Tree.new("ii"))) + end + + def hello(width) + PrettyPrint.format('', width) {|hello| + hello.group { + hello.group { + hello.group { + hello.group { + hello.text 'hello' + hello.breakable; hello.text 'a' + } + hello.breakable; hello.text 'b' + } + hello.breakable; hello.text 'c' + } + hello.breakable; hello.text 'd' + } + } + end + + def test_hello_00_06 + expected = <<'End'.chomp +hello +a +b +c +d +End + assert_equal(expected, hello(0)) + assert_equal(expected, hello(6)) + end + + def test_hello_07_08 + expected = <<'End'.chomp +hello a +b +c +d +End + assert_equal(expected, hello(7)) + assert_equal(expected, hello(8)) + end + + def test_hello_09_10 + expected = <<'End'.chomp +hello a b +c +d +End + out = hello(9); assert_equal(expected, out) + out = hello(10); assert_equal(expected, out) + end + + def test_hello_11_12 + expected = <<'End'.chomp +hello a b c +d +End + assert_equal(expected, hello(11)) + assert_equal(expected, hello(12)) + end + + def test_hello_13 + expected = <<'End'.chomp +hello a b c d +End + assert_equal(expected, hello(13)) + end + + def tree(width) + PrettyPrint.format('', width) {|q| @tree.show(q)} + end + + def test_tree_00_19 + expected = <<'End'.chomp +aaaa[bbbbb[ccc, + dd], + eee, + ffff[gg, + hhh, + ii]] +End + assert_equal(expected, tree(0)) + assert_equal(expected, tree(19)) + end + + def test_tree_20_22 + expected = <<'End'.chomp +aaaa[bbbbb[ccc, dd], + eee, + ffff[gg, + hhh, + ii]] +End + assert_equal(expected, tree(20)) + assert_equal(expected, tree(22)) + end + + def test_tree_23_43 + expected = <<'End'.chomp +aaaa[bbbbb[ccc, dd], + eee, + ffff[gg, hhh, ii]] +End + assert_equal(expected, tree(23)) + assert_equal(expected, tree(43)) + end + + def test_tree_44 + assert_equal(<<'End'.chomp, tree(44)) +aaaa[bbbbb[ccc, dd], eee, ffff[gg, hhh, ii]] +End + end + + def tree_alt(width) + PrettyPrint.format('', width) {|q| @tree.altshow(q)} + end + + def test_tree_alt_00_18 + expected = <<'End'.chomp +aaaa[ + bbbbb[ + ccc, + dd + ], + eee, + ffff[ + gg, + hhh, + ii + ] +] +End + assert_equal(expected, tree_alt(0)) + assert_equal(expected, tree_alt(18)) + end + + def test_tree_alt_19_20 + expected = <<'End'.chomp +aaaa[ + bbbbb[ ccc, dd ], + eee, + ffff[ + gg, + hhh, + ii + ] +] +End + assert_equal(expected, tree_alt(19)) + assert_equal(expected, tree_alt(20)) + end + + def test_tree_alt_20_49 + expected = <<'End'.chomp +aaaa[ + bbbbb[ ccc, dd ], + eee, + ffff[ gg, hhh, ii ] +] +End + assert_equal(expected, tree_alt(21)) + assert_equal(expected, tree_alt(49)) + end + + def test_tree_alt_50 + expected = <<'End'.chomp +aaaa[ bbbbb[ ccc, dd ], eee, ffff[ gg, hhh, ii ] ] +End + assert_equal(expected, tree_alt(50)) + end + + class Tree # :nodoc: + def initialize(string, *children) + @string = string + @children = children + end + + def show(q) + q.group { + q.text @string + q.nest(@string.length) { + unless @children.empty? + q.text '[' + q.nest(1) { + first = true + @children.each {|t| + if first + first = false + else + q.text ',' + q.breakable + end + t.show(q) + } + } + q.text ']' + end + } + } + end + + def altshow(q) + q.group { + q.text @string + unless @children.empty? + q.text '[' + q.nest(2) { + q.breakable + first = true + @children.each {|t| + if first + first = false + else + q.text ',' + q.breakable + end + t.altshow(q) + } + } + q.breakable + q.text ']' + end + } + end + + end + end + + class StrictPrettyExample < Test::Unit::TestCase # :nodoc: + def prog(width) + PrettyPrint.format('', width) {|q| + q.group { + q.group {q.nest(2) { + q.text "if"; q.breakable; + q.group { + q.nest(2) { + q.group {q.text "a"; q.breakable; q.text "=="} + q.breakable; q.text "b"}}}} + q.breakable + q.group {q.nest(2) { + q.text "then"; q.breakable; + q.group { + q.nest(2) { + q.group {q.text "a"; q.breakable; q.text "<<"} + q.breakable; q.text "2"}}}} + q.breakable + q.group {q.nest(2) { + q.text "else"; q.breakable; + q.group { + q.nest(2) { + q.group {q.text "a"; q.breakable; q.text "+"} + q.breakable; q.text "b"}}}}} + } + end + + def test_00_04 + expected = <<'End'.chomp +if + a + == + b +then + a + << + 2 +else + a + + + b +End + assert_equal(expected, prog(0)) + assert_equal(expected, prog(4)) + end + + def test_05 + expected = <<'End'.chomp +if + a + == + b +then + a + << + 2 +else + a + + b +End + assert_equal(expected, prog(5)) + end + + def test_06 + expected = <<'End'.chomp +if + a == + b +then + a << + 2 +else + a + + b +End + assert_equal(expected, prog(6)) + end + + def test_07 + expected = <<'End'.chomp +if + a == + b +then + a << + 2 +else + a + b +End + assert_equal(expected, prog(7)) + end + + def test_08 + expected = <<'End'.chomp +if + a == b +then + a << 2 +else + a + b +End + assert_equal(expected, prog(8)) + end + + def test_09 + expected = <<'End'.chomp +if a == b +then + a << 2 +else + a + b +End + assert_equal(expected, prog(9)) + end + + def test_10 + expected = <<'End'.chomp +if a == b +then + a << 2 +else a + b +End + assert_equal(expected, prog(10)) + end + + def test_11_31 + expected = <<'End'.chomp +if a == b +then a << 2 +else a + b +End + assert_equal(expected, prog(11)) + assert_equal(expected, prog(15)) + assert_equal(expected, prog(31)) + end + + def test_32 + expected = <<'End'.chomp +if a == b then a << 2 else a + b +End + assert_equal(expected, prog(32)) + end + + end + + class TailGroup < Test::Unit::TestCase # :nodoc: + def test_1 + out = PrettyPrint.format('', 10) {|q| + q.group { + q.group { + q.text "abc" + q.breakable + q.text "def" + } + q.group { + q.text "ghi" + q.breakable + q.text "jkl" + } + } + } + assert_equal("abc defghi\njkl", out) + end + end + + class NonString < Test::Unit::TestCase # :nodoc: + def format(width) + PrettyPrint.format([], width, 'newline', lambda {|n| "#{n} spaces"}) {|q| + q.text(3, 3) + q.breakable(1, 1) + q.text(3, 3) + } + end + + def test_6 + assert_equal([3, "newline", "0 spaces", 3], format(6)) + end + + def test_7 + assert_equal([3, 1, 3], format(7)) + end + + end + + class Fill < Test::Unit::TestCase # :nodoc: + def format(width) + PrettyPrint.format('', width) {|q| + q.group { + q.text 'abc' + q.fill_breakable + q.text 'def' + q.fill_breakable + q.text 'ghi' + q.fill_breakable + q.text 'jkl' + q.fill_breakable + q.text 'mno' + q.fill_breakable + q.text 'pqr' + q.fill_breakable + q.text 'stu' + } + } + end + + def test_00_06 + expected = <<'End'.chomp +abc +def +ghi +jkl +mno +pqr +stu +End + assert_equal(expected, format(0)) + assert_equal(expected, format(6)) + end + + def test_07_10 + expected = <<'End'.chomp +abc def +ghi jkl +mno pqr +stu +End + assert_equal(expected, format(7)) + assert_equal(expected, format(10)) + end + + def test_11_14 + expected = <<'End'.chomp +abc def ghi +jkl mno pqr +stu +End + assert_equal(expected, format(11)) + assert_equal(expected, format(14)) + end + + def test_15_18 + expected = <<'End'.chomp +abc def ghi jkl +mno pqr stu +End + assert_equal(expected, format(15)) + assert_equal(expected, format(18)) + end + + def test_19_22 + expected = <<'End'.chomp +abc def ghi jkl mno +pqr stu +End + assert_equal(expected, format(19)) + assert_equal(expected, format(22)) + end + + def test_23_26 + expected = <<'End'.chomp +abc def ghi jkl mno pqr +stu +End + assert_equal(expected, format(23)) + assert_equal(expected, format(26)) + end + + def test_27 + expected = <<'End'.chomp +abc def ghi jkl mno pqr stu +End + assert_equal(expected, format(27)) + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/profile.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/profile.rb new file mode 100644 index 00000000..104cb205 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/profile.rb @@ -0,0 +1,6 @@ +require 'profiler' + +END { + Profiler__::print_profile(STDERR) +} +Profiler__::start_profile diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/profiler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/profiler.rb new file mode 100644 index 00000000..9762fa11 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/profiler.rb @@ -0,0 +1,59 @@ +module Profiler__ + # internal values + @@start = @@stack = @@map = nil + PROFILE_PROC = proc{|event, file, line, id, binding, klass| + case event + when "call", "c-call" + now = Process.times[0] + @@stack.push [now, 0.0] + when "return", "c-return" + now = Process.times[0] + key = [klass, id] + if tick = @@stack.pop + data = (@@map[key] ||= [0, 0.0, 0.0, key]) + data[0] += 1 + cost = now - tick[0] + data[1] += cost + data[2] += cost - tick[1] + @@stack[-1][1] += cost if @@stack[-1] + end + end + } +module_function + def start_profile + @@start = Process.times[0] + @@stack = [] + @@map = {} + set_trace_func PROFILE_PROC + end + def stop_profile + set_trace_func nil + end + def print_profile(f) + stop_profile + total = Process.times[0] - @@start + if total == 0 then total = 0.01 end + data = @@map.values + data.sort!{|a,b| b[2] <=> a[2]} + sum = 0 + f.printf " %% cumulative self self total\n" + f.printf " time seconds seconds calls ms/call ms/call name\n" + for d in data + sum += d[2] + f.printf "%6.2f %8.2f %8.2f %8d ", d[2]/total*100, sum, d[2], d[0] + f.printf "%8.2f %8.2f %s\n", d[2]*1000/d[0], d[1]*1000/d[0], get_name(*d[3]) + end + f.printf "%6.2f %8.2f %8.2f %8d ", 0.0, total, 0.0, 1 # ??? + f.printf "%8.2f %8.2f %s\n", 0.0, total*1000, "#toplevel" # ??? + end + def get_name(klass, id) + name = klass.to_s || "" + if klass.kind_of? Class + name += "#" + else + name += "." + end + name + id.id2name + end + private :get_name +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pstore.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pstore.rb new file mode 100644 index 00000000..6df64474 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/pstore.rb @@ -0,0 +1,395 @@ +# = PStore -- Transactional File Storage for Ruby Objects +# +# pstore.rb - +# originally by matz +# documentation by Kev Jackson and James Edward Gray II +# +# See PStore for documentation. + + +require "fileutils" +require "digest/md5" + +# +# PStore implements a file based persistance mechanism based on a Hash. User +# code can store hierarchies of Ruby objects (values) into the data store file +# by name (keys). An object hierarchy may be just a single object. User code +# may later read values back from the data store or even update data, as needed. +# +# The transactional behavior ensures that any changes succeed or fail together. +# This can be used to ensure that the data store is not left in a transitory +# state, where some values were upated but others were not. +# +# Behind the scenes, Ruby objects are stored to the data store file with +# Marshal. That carries the usual limitations. Proc objects cannot be +# marshalled, for example. +# +# == Usage example: +# +# require "pstore" +# +# # a mock wiki object... +# class WikiPage +# def initialize( page_name, author, contents ) +# @page_name = page_name +# @revisions = Array.new +# +# add_revision(author, contents) +# end +# +# attr_reader :page_name +# +# def add_revision( author, contents ) +# @revisions << { :created => Time.now, +# :author => author, +# :contents => contents } +# end +# +# def wiki_page_references +# [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/) +# end +# +# # ... +# end +# +# # create a new page... +# home_page = WikiPage.new( "HomePage", "James Edward Gray II", +# "A page about the JoysOfDocumentation..." ) +# +# # then we want to update page data and the index together, or not at all... +# wiki = PStore.new("wiki_pages.pstore") +# wiki.transaction do # begin transaction; do all of this or none of it +# # store page... +# wiki[home_page.page_name] = home_page +# # ensure that an index has been created... +# wiki[:wiki_index] ||= Array.new +# # update wiki index... +# wiki[:wiki_index].push(*home_page.wiki_page_references) +# end # commit changes to wiki data store file +# +# ### Some time later... ### +# +# # read wiki data... +# wiki.transaction(true) do # begin read-only transaction, no changes allowed +# wiki.roots.each do |data_root_name| +# p data_root_name +# p wiki[data_root_name] +# end +# end +# +class PStore + binmode = defined?(File::BINARY) ? File::BINARY : 0 + RDWR_ACCESS = File::RDWR | File::CREAT | binmode + RD_ACCESS = File::RDONLY | binmode + WR_ACCESS = File::WRONLY | File::CREAT | File::TRUNC | binmode + + # The error type thrown by all PStore methods. + class Error < StandardError + end + + # + # To construct a PStore object, pass in the _file_ path where you would like + # the data to be stored. + # + def initialize(file) + dir = File::dirname(file) + unless File::directory? dir + raise PStore::Error, format("directory %s does not exist", dir) + end + if File::exist? file and not File::readable? file + raise PStore::Error, format("file %s not readable", file) + end + @transaction = false + @filename = file + @abort = false + end + + # Raises PStore::Error if the calling code is not in a PStore#transaction. + def in_transaction + raise PStore::Error, "not in transaction" unless @transaction + end + # + # Raises PStore::Error if the calling code is not in a PStore#transaction or + # if the code is in a read-only PStore#transaction. + # + def in_transaction_wr() + in_transaction() + raise PStore::Error, "in read-only transaction" if @rdonly + end + private :in_transaction, :in_transaction_wr + + # + # Retrieves a value from the PStore file data, by _name_. The hierarchy of + # Ruby objects stored under that root _name_ will be returned. + # + # *WARNING*: This method is only valid in a PStore#transaction. It will + # raise PStore::Error if called at any other time. + # + def [](name) + in_transaction + @table[name] + end + # + # This method is just like PStore#[], save that you may also provide a + # _default_ value for the object. In the event the specified _name_ is not + # found in the data store, your _default_ will be returned instead. If you do + # not specify a default, PStore::Error will be raised if the object is not + # found. + # + # *WARNING*: This method is only valid in a PStore#transaction. It will + # raise PStore::Error if called at any other time. + # + def fetch(name, default=PStore::Error) + in_transaction + unless @table.key? name + if default==PStore::Error + raise PStore::Error, format("undefined root name `%s'", name) + else + return default + end + end + @table[name] + end + # + # Stores an individual Ruby object or a hierarchy of Ruby objects in the data + # store file under the root _name_. Assigning to a _name_ already in the data + # store clobbers the old data. + # + # == Example: + # + # require "pstore" + # + # store = PStore.new("data_file.pstore") + # store.transaction do # begin transaction + # # load some data into the store... + # store[:single_object] = "My data..." + # store[:obj_heirarchy] = { "Kev Jackson" => ["rational.rb", "pstore.rb"], + # "James Gray" => ["erb.rb", "pstore.rb"] } + # end # commit changes to data store file + # + # *WARNING*: This method is only valid in a PStore#transaction and it cannot + # be read-only. It will raise PStore::Error if called at any other time. + # + def []=(name, value) + in_transaction_wr() + @table[name] = value + end + # + # Removes an object hierarchy from the data store, by _name_. + # + # *WARNING*: This method is only valid in a PStore#transaction and it cannot + # be read-only. It will raise PStore::Error if called at any other time. + # + def delete(name) + in_transaction_wr() + @table.delete name + end + + # + # Returns the names of all object hierarchies currently in the store. + # + # *WARNING*: This method is only valid in a PStore#transaction. It will + # raise PStore::Error if called at any other time. + # + def roots + in_transaction + @table.keys + end + # + # Returns true if the supplied _name_ is currently in the data store. + # + # *WARNING*: This method is only valid in a PStore#transaction. It will + # raise PStore::Error if called at any other time. + # + def root?(name) + in_transaction + @table.key? name + end + # Returns the path to the data store file. + def path + @filename + end + + # + # Ends the current PStore#transaction, committing any changes to the data + # store immediately. + # + # == Example: + # + # require "pstore" + # + # store = PStore.new("data_file.pstore") + # store.transaction do # begin transaction + # # load some data into the store... + # store[:one] = 1 + # store[:two] = 2 + # + # store.commit # end transaction here, committing changes + # + # store[:three] = 3 # this change is never reached + # end + # + # *WARNING*: This method is only valid in a PStore#transaction. It will + # raise PStore::Error if called at any other time. + # + def commit + in_transaction + @abort = false + throw :pstore_abort_transaction + end + # + # Ends the current PStore#transaction, discarding any changes to the data + # store. + # + # == Example: + # + # require "pstore" + # + # store = PStore.new("data_file.pstore") + # store.transaction do # begin transaction + # store[:one] = 1 # this change is not applied, see below... + # store[:two] = 2 # this change is not applied, see below... + # + # store.abort # end transaction here, discard all changes + # + # store[:three] = 3 # this change is never reached + # end + # + # *WARNING*: This method is only valid in a PStore#transaction. It will + # raise PStore::Error if called at any other time. + # + def abort + in_transaction + @abort = true + throw :pstore_abort_transaction + end + + # + # Opens a new transaction for the data store. Code executed inside a block + # passed to this method may read and write data to and from the data store + # file. + # + # At the end of the block, changes are committed to the data store + # automatically. You may exit the transaction early with a call to either + # PStore#commit or PStore#abort. See those methods for details about how + # changes are handled. Raising an uncaught Exception in the block is + # equivalent to calling PStore#abort. + # + # If _read_only_ is set to +true+, you will only be allowed to read from the + # data store during the transaction and any attempts to change the data will + # raise a PStore::Error. + # + # Note that PStore does not support nested transactions. + # + def transaction(read_only=false) # :yields: pstore + raise PStore::Error, "nested transaction" if @transaction + begin + @rdonly = read_only + @abort = false + @transaction = true + value = nil + new_file = @filename + ".new" + + content = nil + unless read_only + file = File.open(@filename, RDWR_ACCESS) + file.flock(File::LOCK_EX) + commit_new(file) if FileTest.exist?(new_file) + content = file.read() + else + begin + file = File.open(@filename, RD_ACCESS) + file.flock(File::LOCK_SH) + content = (File.open(new_file, RD_ACCESS) {|n| n.read} rescue file.read()) + rescue Errno::ENOENT + content = "" + end + end + + if content != "" + @table = load(content) + if !read_only + size = content.size + md5 = Digest::MD5.digest(content) + end + else + @table = {} + end + content = nil # unreference huge data + + begin + catch(:pstore_abort_transaction) do + value = yield(self) + end + rescue Exception + @abort = true + raise + ensure + if !read_only and !@abort + tmp_file = @filename + ".tmp" + content = dump(@table) + if !md5 || size != content.size || md5 != Digest::MD5.digest(content) + File.open(tmp_file, WR_ACCESS) {|t| t.write(content)} + File.rename(tmp_file, new_file) + commit_new(file) + end + content = nil # unreference huge data + end + end + ensure + @table = nil + @transaction = false + file.close if file + end + value + end + + # This method is just a wrapped around Marshal.dump. + def dump(table) # :nodoc: + Marshal::dump(table) + end + + # This method is just a wrapped around Marshal.load. + def load(content) # :nodoc: + Marshal::load(content) + end + + # This method is just a wrapped around Marshal.load. + def load_file(file) # :nodoc: + Marshal::load(file) + end + + private + # Commits changes to the data store file. + def commit_new(f) + f.truncate(0) + f.rewind + new_file = @filename + ".new" + File.open(new_file, RD_ACCESS) do |nf| + FileUtils.copy_stream(nf, f) + end + File.unlink(new_file) + end +end + +# :enddoc: + +if __FILE__ == $0 + db = PStore.new("/tmp/foo") + db.transaction do + p db.roots + ary = db["root"] = [1,2,3,4] + ary[1] = [1,1.5] + end + + 1000.times do + db.transaction do + db["root"][0] += 1 + p db["root"][0] + end + end + + db.transaction(true) do + p db["root"] + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/racc/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/racc/parser.rb new file mode 100644 index 00000000..a7408dd0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/racc/parser.rb @@ -0,0 +1,442 @@ +# +# $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $ +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# +# As a special exception, when this code is copied by Racc +# into a Racc output file, you may use that output file +# without restriction. +# + +unless defined?(NotImplementedError) + NotImplementedError = NotImplementError +end + +module Racc + class ParseError < StandardError; end +end +unless defined?(::ParseError) + ParseError = Racc::ParseError +end + +module Racc + + unless defined?(Racc_No_Extentions) + Racc_No_Extentions = false + end + + class Parser + + Racc_Runtime_Version = '1.4.5' + Racc_Runtime_Revision = '$originalRevision: 1.8 $'.split[1] + + Racc_Runtime_Core_Version_R = '1.4.5' + Racc_Runtime_Core_Revision_R = '$originalRevision: 1.8 $'.split[1] + begin + require 'racc/cparse' + # Racc_Runtime_Core_Version_C = (defined in extention) + Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2] + unless new.respond_to?(:_racc_do_parse_c, true) + raise LoadError, 'old cparse.so' + end + if Racc_No_Extentions + raise LoadError, 'selecting ruby version of racc runtime core' + end + + Racc_Main_Parsing_Routine = :_racc_do_parse_c + Racc_YY_Parse_Method = :_racc_yyparse_c + Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C + Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C + Racc_Runtime_Type = 'c' + rescue LoadError + Racc_Main_Parsing_Routine = :_racc_do_parse_rb + Racc_YY_Parse_Method = :_racc_yyparse_rb + Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R + Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R + Racc_Runtime_Type = 'ruby' + end + + def Parser.racc_runtime_type + Racc_Runtime_Type + end + + private + + def _racc_setup + @yydebug = false unless self.class::Racc_debug_parser + @yydebug = false unless defined?(@yydebug) + if @yydebug + @racc_debug_out = $stderr unless defined?(@racc_debug_out) + @racc_debug_out ||= $stderr + end + arg = self.class::Racc_arg + arg[13] = true if arg.size < 14 + arg + end + + def _racc_init_sysvars + @racc_state = [0] + @racc_tstack = [] + @racc_vstack = [] + + @racc_t = nil + @racc_val = nil + + @racc_read_next = true + + @racc_user_yyerror = false + @racc_error_status = 0 + end + + ### + ### do_parse + ### + + def do_parse + __send__(Racc_Main_Parsing_Routine, _racc_setup(), false) + end + + def next_token + raise NotImplementedError, "#{self.class}\#next_token is not defined" + end + + def _racc_do_parse_rb(arg, in_debug) + action_table, action_check, action_default, action_pointer, + goto_table, goto_check, goto_default, goto_pointer, + nt_base, reduce_table, token_table, shift_n, + reduce_n, use_result, * = arg + + _racc_init_sysvars + tok = act = i = nil + nerr = 0 + + catch(:racc_end_parse) { + while true + if i = action_pointer[@racc_state[-1]] + if @racc_read_next + if @racc_t != 0 # not EOF + tok, @racc_val = next_token() + unless tok # EOF + @racc_t = 0 + else + @racc_t = (token_table[tok] or 1) # error token + end + racc_read_token(@racc_t, tok, @racc_val) if @yydebug + @racc_read_next = false + end + end + i += @racc_t + unless i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + else + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + end + } + end + + ### + ### yyparse + ### + + def yyparse(recv, mid) + __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true) + end + + def _racc_yyparse_rb(recv, mid, arg, c_debug) + action_table, action_check, action_default, action_pointer, + goto_table, goto_check, goto_default, goto_pointer, + nt_base, reduce_table, token_table, shift_n, + reduce_n, use_result, * = arg + + _racc_init_sysvars + tok = nil + act = nil + i = nil + nerr = 0 + + catch(:racc_end_parse) { + until i = action_pointer[@racc_state[-1]] + while act = _racc_evalact(action_default[@racc_state[-1]], arg) + ; + end + end + recv.__send__(mid) do |tok, val| + unless tok + @racc_t = 0 + else + @racc_t = (token_table[tok] or 1) # error token + end + @racc_val = val + @racc_read_next = false + + i += @racc_t + unless i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + + while not (i = action_pointer[@racc_state[-1]]) or + not @racc_read_next or + @racc_t == 0 # $ + unless i and i += @racc_t and + i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + end + end + } + end + + ### + ### common + ### + + def _racc_evalact(act, arg) + action_table, action_check, action_default, action_pointer, + goto_table, goto_check, goto_default, goto_pointer, + nt_base, reduce_table, token_table, shift_n, + reduce_n, use_result, * = arg + nerr = 0 # tmp + + if act > 0 and act < shift_n + # + # shift + # + if @racc_error_status > 0 + @racc_error_status -= 1 unless @racc_t == 1 # error token + end + @racc_vstack.push @racc_val + @racc_state.push act + @racc_read_next = true + if @yydebug + @racc_tstack.push @racc_t + racc_shift @racc_t, @racc_tstack, @racc_vstack + end + + elsif act < 0 and act > -reduce_n + # + # reduce + # + code = catch(:racc_jump) { + @racc_state.push _racc_do_reduce(arg, act) + false + } + if code + case code + when 1 # yyerror + @racc_user_yyerror = true # user_yyerror + return -reduce_n + when 2 # yyaccept + return shift_n + else + raise '[Racc Bug] unknown jump code' + end + end + + elsif act == shift_n + # + # accept + # + racc_accept if @yydebug + throw :racc_end_parse, @racc_vstack[0] + + elsif act == -reduce_n + # + # error + # + case @racc_error_status + when 0 + unless arg[21] # user_yyerror + nerr += 1 + on_error @racc_t, @racc_val, @racc_vstack + end + when 3 + if @racc_t == 0 # is $ + throw :racc_end_parse, nil + end + @racc_read_next = true + end + @racc_user_yyerror = false + @racc_error_status = 3 + while true + if i = action_pointer[@racc_state[-1]] + i += 1 # error token + if i >= 0 and + (act = action_table[i]) and + action_check[i] == @racc_state[-1] + break + end + end + throw :racc_end_parse, nil if @racc_state.size <= 1 + @racc_state.pop + @racc_vstack.pop + if @yydebug + @racc_tstack.pop + racc_e_pop @racc_state, @racc_tstack, @racc_vstack + end + end + return act + + else + raise "[Racc Bug] unknown action #{act.inspect}" + end + + racc_next_state(@racc_state[-1], @racc_state) if @yydebug + + nil + end + + def _racc_do_reduce(arg, act) + action_table, action_check, action_default, action_pointer, + goto_table, goto_check, goto_default, goto_pointer, + nt_base, reduce_table, token_table, shift_n, + reduce_n, use_result, * = arg + state = @racc_state + vstack = @racc_vstack + tstack = @racc_tstack + + i = act * -3 + len = reduce_table[i] + reduce_to = reduce_table[i+1] + method_id = reduce_table[i+2] + void_array = [] + + tmp_t = tstack[-len, len] if @yydebug + tmp_v = vstack[-len, len] + tstack[-len, len] = void_array if @yydebug + vstack[-len, len] = void_array + state[-len, len] = void_array + + # tstack must be updated AFTER method call + if use_result + vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0]) + else + vstack.push __send__(method_id, tmp_v, vstack) + end + tstack.push reduce_to + + racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug + + k1 = reduce_to - nt_base + if i = goto_pointer[k1] + i += state[-1] + if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1 + return curstate + end + end + goto_default[k1] + end + + def on_error(t, val, vstack) + raise ParseError, sprintf("\nparse error on value %s (%s)", + val.inspect, token_to_str(t) || '?') + end + + def yyerror + throw :racc_jump, 1 + end + + def yyaccept + throw :racc_jump, 2 + end + + def yyerrok + @racc_error_status = 0 + end + + # + # for debugging output + # + + def racc_read_token(t, tok, val) + @racc_debug_out.print 'read ' + @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') ' + @racc_debug_out.puts val.inspect + @racc_debug_out.puts + end + + def racc_shift(tok, tstack, vstack) + @racc_debug_out.puts "shift #{racc_token2str tok}" + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_reduce(toks, sim, tstack, vstack) + out = @racc_debug_out + out.print 'reduce ' + if toks.empty? + out.print ' ' + else + toks.each {|t| out.print ' ', racc_token2str(t) } + end + out.puts " --> #{racc_token2str(sim)}" + + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_accept + @racc_debug_out.puts 'accept' + @racc_debug_out.puts + end + + def racc_e_pop(state, tstack, vstack) + @racc_debug_out.puts 'error recovering mode: pop token' + racc_print_states state + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_next_state(curstate, state) + @racc_debug_out.puts "goto #{curstate}" + racc_print_states state + @racc_debug_out.puts + end + + def racc_print_stacks(t, v) + out = @racc_debug_out + out.print ' [' + t.each_index do |i| + out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')' + end + out.puts ' ]' + end + + def racc_print_states(s) + out = @racc_debug_out + out.print ' [' + s.each {|st| out.print ' ', st } + out.puts ' ]' + end + + def racc_token2str(tok) + self.class::Racc_token_to_s_table[tok] or + raise "[Racc Bug] can't convert token #{tok} to string" + end + + def token_to_str(t) + self.class::Racc_token_to_s_table[t] + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rational.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rational.rb new file mode 100644 index 00000000..ce754cfa --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rational.rb @@ -0,0 +1,530 @@ +# +# rational.rb - +# $Release Version: 0.5 $ +# $Revision: 1.7 $ +# $Date: 1999/08/24 12:49:28 $ +# by Keiju ISHITSUKA(SHL Japan Inc.) +# +# Documentation by Kevin Jackson and Gavin Sinclair. +# +# When you require 'rational', all interactions between numbers +# potentially return a rational result. For example: +# +# 1.quo(2) # -> 0.5 +# require 'rational' +# 1.quo(2) # -> Rational(1,2) +# +# See Rational for full documentation. +# + + +# +# Creates a Rational number (i.e. a fraction). +a+ and +b+ should be Integers: +# +# Rational(1,3) # -> 1/3 +# +# Note: trying to construct a Rational with floating point or real values +# produces errors: +# +# Rational(1.1, 2.3) # -> NoMethodError +# +def Rational(a, b = 1) + if a.kind_of?(Rational) && b == 1 + a + else + Rational.reduce(a, b) + end +end + +# +# Rational implements a rational class for numbers. +# +# A rational number is a number that can be expressed as a fraction p/q +# where p and q are integers and q != 0. A rational number p/q is said to have +# numerator p and denominator q. Numbers that are not rational are called +# irrational numbers. (http://mathworld.wolfram.com/RationalNumber.html) +# +# To create a Rational Number: +# Rational(a,b) # -> a/b +# Rational.new!(a,b) # -> a/b +# +# Examples: +# Rational(5,6) # -> 5/6 +# Rational(5) # -> 5/1 +# +# Rational numbers are reduced to their lowest terms: +# Rational(6,10) # -> 3/5 +# +# But not if you use the unusual method "new!": +# Rational.new!(6,10) # -> 6/10 +# +# Division by zero is obviously not allowed: +# Rational(3,0) # -> ZeroDivisionError +# +class Rational < Numeric + @RCS_ID='-$Id: rational.rb,v 1.7 1999/08/24 12:49:28 keiju Exp keiju $-' + + # + # Reduces the given numerator and denominator to their lowest terms. Use + # Rational() instead. + # + def Rational.reduce(num, den = 1) + raise ZeroDivisionError, "denominator is zero" if den == 0 + + if den < 0 + num = -num + den = -den + end + gcd = num.gcd(den) + num = num.div(gcd) + den = den.div(gcd) + if den == 1 && defined?(Unify) + num + else + new!(num, den) + end + end + + # + # Implements the constructor. This method does not reduce to lowest terms or + # check for division by zero. Therefore #Rational() should be preferred in + # normal use. + # + def Rational.new!(num, den = 1) + new(num, den) + end + + private_class_method :new + + # + # This method is actually private. + # + def initialize(num, den) + if den < 0 + num = -num + den = -den + end + if num.kind_of?(Integer) and den.kind_of?(Integer) + @numerator = num + @denominator = den + else + @numerator = num.to_i + @denominator = den.to_i + end + end + + # + # Returns the addition of this value and +a+. + # + # Examples: + # r = Rational(3,4) # -> Rational(3,4) + # r + 1 # -> Rational(7,4) + # r + 0.5 # -> 1.25 + # + def + (a) + if a.kind_of?(Rational) + num = @numerator * a.denominator + num_a = a.numerator * @denominator + Rational(num + num_a, @denominator * a.denominator) + elsif a.kind_of?(Integer) + self + Rational.new!(a, 1) + elsif a.kind_of?(Float) + Float(self) + a + else + x, y = a.coerce(self) + x + y + end + end + + # + # Returns the difference of this value and +a+. + # subtracted. + # + # Examples: + # r = Rational(3,4) # -> Rational(3,4) + # r - 1 # -> Rational(-1,4) + # r - 0.5 # -> 0.25 + # + def - (a) + if a.kind_of?(Rational) + num = @numerator * a.denominator + num_a = a.numerator * @denominator + Rational(num - num_a, @denominator*a.denominator) + elsif a.kind_of?(Integer) + self - Rational.new!(a, 1) + elsif a.kind_of?(Float) + Float(self) - a + else + x, y = a.coerce(self) + x - y + end + end + + # + # Returns the product of this value and +a+. + # + # Examples: + # r = Rational(3,4) # -> Rational(3,4) + # r * 2 # -> Rational(3,2) + # r * 4 # -> Rational(3,1) + # r * 0.5 # -> 0.375 + # r * Rational(1,2) # -> Rational(3,8) + # + def * (a) + if a.kind_of?(Rational) + num = @numerator * a.numerator + den = @denominator * a.denominator + Rational(num, den) + elsif a.kind_of?(Integer) + self * Rational.new!(a, 1) + elsif a.kind_of?(Float) + Float(self) * a + else + x, y = a.coerce(self) + x * y + end + end + + # + # Returns the quotient of this value and +a+. + # r = Rational(3,4) # -> Rational(3,4) + # r / 2 # -> Rational(3,8) + # r / 2.0 # -> 0.375 + # r / Rational(1,2) # -> Rational(3,2) + # + def / (a) + if a.kind_of?(Rational) + num = @numerator * a.denominator + den = @denominator * a.numerator + Rational(num, den) + elsif a.kind_of?(Integer) + raise ZeroDivisionError, "division by zero" if a == 0 + self / Rational.new!(a, 1) + elsif a.kind_of?(Float) + Float(self) / a + else + x, y = a.coerce(self) + x / y + end + end + + # + # Returns this value raised to the given power. + # + # Examples: + # r = Rational(3,4) # -> Rational(3,4) + # r ** 2 # -> Rational(9,16) + # r ** 2.0 # -> 0.5625 + # r ** Rational(1,2) # -> 0.866025403784439 + # + def ** (other) + if other.kind_of?(Rational) + Float(self) ** other + elsif other.kind_of?(Integer) + if other > 0 + num = @numerator ** other + den = @denominator ** other + elsif other < 0 + num = @denominator ** -other + den = @numerator ** -other + elsif other == 0 + num = 1 + den = 1 + end + Rational.new!(num, den) + elsif other.kind_of?(Float) + Float(self) ** other + else + x, y = other.coerce(self) + x ** y + end + end + + # + # Returns the remainder when this value is divided by +other+. + # + # Examples: + # r = Rational(7,4) # -> Rational(7,4) + # r % Rational(1,2) # -> Rational(1,4) + # r % 1 # -> Rational(3,4) + # r % Rational(1,7) # -> Rational(1,28) + # r % 0.26 # -> 0.19 + # + def % (other) + value = (self / other).to_i + return self - other * value + end + + # + # Returns the quotient _and_ remainder. + # + # Examples: + # r = Rational(7,4) # -> Rational(7,4) + # r.divmod Rational(1,2) # -> [3, Rational(1,4)] + # + def divmod(other) + value = (self / other).to_i + return value, self - other * value + end + + # + # Returns the absolute value. + # + def abs + if @numerator > 0 + Rational.new!(@numerator, @denominator) + else + Rational.new!(-@numerator, @denominator) + end + end + + # + # Returns +true+ iff this value is numerically equal to +other+. + # + # But beware: + # Rational(1,2) == Rational(4,8) # -> true + # Rational(1,2) == Rational.new!(4,8) # -> false + # + # Don't use Rational.new! + # + def == (other) + if other.kind_of?(Rational) + @numerator == other.numerator and @denominator == other.denominator + elsif other.kind_of?(Integer) + self == Rational.new!(other, 1) + elsif other.kind_of?(Float) + Float(self) == other + else + other == self + end + end + + # + # Standard comparison operator. + # + def <=> (other) + if other.kind_of?(Rational) + num = @numerator * other.denominator + num_a = other.numerator * @denominator + v = num - num_a + if v > 0 + return 1 + elsif v < 0 + return -1 + else + return 0 + end + elsif other.kind_of?(Integer) + return self <=> Rational.new!(other, 1) + elsif other.kind_of?(Float) + return Float(self) <=> other + elsif defined? other.coerce + x, y = other.coerce(self) + return x <=> y + else + return nil + end + end + + def coerce(other) + if other.kind_of?(Float) + return other, self.to_f + elsif other.kind_of?(Integer) + return Rational.new!(other, 1), self + else + super + end + end + + # + # Converts the rational to an Integer. Not the _nearest_ integer, the + # truncated integer. Study the following example carefully: + # Rational(+7,4).to_i # -> 1 + # Rational(-7,4).to_i # -> -2 + # (-1.75).to_i # -> -1 + # + # In other words: + # Rational(-7,4) == -1.75 # -> true + # Rational(-7,4).to_i == (-1.75).to_i # false + # + def to_i + Integer(@numerator.div(@denominator)) + end + + # + # Converts the rational to a Float. + # + def to_f + @numerator.to_f/@denominator.to_f + end + + # + # Returns a string representation of the rational number. + # + # Example: + # Rational(3,4).to_s # "3/4" + # Rational(8).to_s # "8" + # + def to_s + if @denominator == 1 + @numerator.to_s + else + @numerator.to_s+"/"+@denominator.to_s + end + end + + # + # Returns +self+. + # + def to_r + self + end + + # + # Returns a reconstructable string representation: + # + # Rational(5,8).inspect # -> "Rational(5, 8)" + # + def inspect + sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect) + end + + # + # Returns a hash code for the object. + # + def hash + @numerator.hash ^ @denominator.hash + end + + attr :numerator + attr :denominator + + private :initialize +end + +class Integer + # + # In an integer, the value _is_ the numerator of its rational equivalent. + # Therefore, this method returns +self+. + # + def numerator + self + end + + # + # In an integer, the denominator is 1. Therefore, this method returns 1. + # + def denominator + 1 + end + + # + # Returns a Rational representation of this integer. + # + def to_r + Rational(self, 1) + end + + # + # Returns the greatest common denominator of the two numbers (+self+ + # and +n+). + # + # Examples: + # 72.gcd 168 # -> 24 + # 19.gcd 36 # -> 1 + # + # The result is positive, no matter the sign of the arguments. + # + def gcd(other) + min = self.abs + max = other.abs + while min > 0 + tmp = min + min = max % min + max = tmp + end + max + end + + # + # Returns the lowest common multiple (LCM) of the two arguments + # (+self+ and +other+). + # + # Examples: + # 6.lcm 7 # -> 42 + # 6.lcm 9 # -> 18 + # + def lcm(other) + if self.zero? or other.zero? + 0 + else + (self.div(self.gcd(other)) * other).abs + end + end + + # + # Returns the GCD _and_ the LCM (see #gcd and #lcm) of the two arguments + # (+self+ and +other+). This is more efficient than calculating them + # separately. + # + # Example: + # 6.gcdlcm 9 # -> [3, 18] + # + def gcdlcm(other) + gcd = self.gcd(other) + if self.zero? or other.zero? + [gcd, 0] + else + [gcd, (self.div(gcd) * other).abs] + end + end +end + +class Fixnum + undef quo + # If Rational is defined, returns a Rational number instead of a Fixnum. + def quo(other) + Rational.new!(self,1) / other + end + alias rdiv quo + + # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0). + def rpower (other) + if other >= 0 + self.power!(other) + else + Rational.new!(self,1)**other + end + end + + unless defined? 1.power! + alias power! ** + alias ** rpower + end +end + +class Bignum + unless defined? Complex + alias power! ** + end + + undef quo + # If Rational is defined, returns a Rational number instead of a Bignum. + def quo(other) + Rational.new!(self,1) / other + end + alias rdiv quo + + # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0). + def rpower (other) + if other >= 0 + self.power!(other) + else + Rational.new!(self, 1)**other + end + end + + unless defined? Complex + alias ** rpower + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rbconfig.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rbconfig.rb new file mode 100644 index 00000000..68144120 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rbconfig.rb @@ -0,0 +1,154 @@ + +# This file was created by mkconfig.rb when ruby was built. Any +# changes made to this file will be lost the next time ruby is built. + +module Config + RUBY_VERSION == "1.8.6" or + raise "ruby lib version (1.8.6) doesn't match executable version (#{RUBY_VERSION})" + + TOPDIR = File.dirname(__FILE__).chomp!("/lib/ruby/1.8/i386-mswin32") + DESTDIR = TOPDIR && TOPDIR[/\A[a-z]:/i] || '' unless defined? DESTDIR + CONFIG = {} + CONFIG["DESTDIR"] = DESTDIR + CONFIG["MAJOR"] = "1" + CONFIG["MINOR"] = "8" + CONFIG["TEENY"] = "6" + CONFIG["PATCHLEVEL"] = "111" + CONFIG["prefix"] = (TOPDIR || DESTDIR + "") + CONFIG["EXEEXT"] = ".exe" + CONFIG["ruby_install_name"] = "ruby" + CONFIG["RUBY_INSTALL_NAME"] = "ruby" + CONFIG["RUBY_SO_NAME"] = "msvcrt-ruby18" + CONFIG["SHELL"] = "$(COMSPEC)" + CONFIG["BUILD_FILE_SEPARATOR"] = "\\" + CONFIG["PATH_SEPARATOR"] = ";" + CONFIG["CFLAGS"] = "-MD -Zi -O2b2xg- -G6" + CONFIG["CPPFLAGS"] = "" + CONFIG["CXXFLAGS"] = "" + CONFIG["FFLAGS"] = "" + CONFIG["LDFLAGS"] = "" + CONFIG["LIBS"] = "oldnames.lib user32.lib advapi32.lib ws2_32.lib " + CONFIG["exec_prefix"] = "$(prefix)" + CONFIG["bindir"] = "$(exec_prefix)/bin" + CONFIG["sbindir"] = "$(exec_prefix)/sbin" + CONFIG["libexecdir"] = "$(exec_prefix)/libexec" + CONFIG["datadir"] = "$(prefix)/share" + CONFIG["sysconfdir"] = "$(prefix)/etc" + CONFIG["sharedstatedir"] = "$(DESTDIR)/etc" + CONFIG["localstatedir"] = "$(DESTDIR)/var" + CONFIG["libdir"] = "$(exec_prefix)/lib" + CONFIG["includedir"] = "$(prefix)/include" + CONFIG["oldincludedir"] = "/usr/include" + CONFIG["infodir"] = "$(prefix)/info" + CONFIG["mandir"] = "$(prefix)/man" + CONFIG["build"] = "i686-pc-mswin32" + CONFIG["build_alias"] = "i686-mswin32" + CONFIG["build_cpu"] = "i686" + CONFIG["build_vendor"] = "pc" + CONFIG["build_os"] = "mswin32" + CONFIG["host"] = "i686-pc-mswin32" + CONFIG["host_alias"] = "i686-mswin32" + CONFIG["host_cpu"] = "i686" + CONFIG["host_vendor"] = "pc" + CONFIG["host_os"] = "mswin32" + CONFIG["target"] = "i386-pc-mswin32" + CONFIG["target_alias"] = "i386-mswin32" + CONFIG["target_cpu"] = "i386" + CONFIG["target_vendor"] = "pc" + CONFIG["target_os"] = "mswin32" + CONFIG["CC"] = "cl -nologo" + CONFIG["CPP"] = "cl -nologo -E" + CONFIG["YACC"] = "byacc" + CONFIG["RANLIB"] = "" + CONFIG["AR"] = "lib -nologo" + CONFIG["ARFLAGS"] = "-machine:x86 -out:" + CONFIG["LN_S"] = "" + CONFIG["SET_MAKE"] = "" + CONFIG["CP"] = "copy > nul" + CONFIG["ALLOCA"] = "" + CONFIG["DEFAULT_KCODE"] = "" + CONFIG["OBJEXT"] = "obj" + CONFIG["XCFLAGS"] = "-DRUBY_EXPORT -I. -IC:/develop/win/ruby/ruby-1.8.6-p111 -IC:/develop/win/ruby/ruby-1.8.6-p111/missing" + CONFIG["XLDFLAGS"] = "-stack:0x2000000" + CONFIG["DLDFLAGS"] = "-link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH) -def:$(DEFFILE) -implib:$(*F:.so=)-$(arch).lib -pdb:$(*F:.so=)-$(arch).pdb" + CONFIG["ARCH_FLAG"] = "" + CONFIG["STATIC"] = "" + CONFIG["CCDLFLAGS"] = "" + CONFIG["LDSHARED"] = "cl -nologo -LD" + CONFIG["DLEXT"] = "so" + CONFIG["DLEXT2"] = "dll" + CONFIG["LIBEXT"] = "lib" + CONFIG["STRIP"] = "" + CONFIG["EXTSTATIC"] = "" + CONFIG["setup"] = "Setup" + CONFIG["MINIRUBY"] = ".\\miniruby.exe " + CONFIG["PREP"] = "miniruby.exe" + CONFIG["RUNRUBY"] = ".\\ruby.exe \"C:/develop/win/ruby/ruby-1.8.6-p111/runruby.rb\" --extout=\".ext\" --" + CONFIG["EXTOUT"] = ".ext" + CONFIG["ARCHFILE"] = "" + CONFIG["RDOCTARGET"] = "install-nodoc" + CONFIG["LIBRUBY_LDSHARED"] = "cl -nologo -LD" + CONFIG["LIBRUBY_DLDFLAGS"] = " -def:msvcrt-ruby18.def" + CONFIG["rubyw_install_name"] = "rubyw" + CONFIG["RUBYW_INSTALL_NAME"] = "rubyw" + CONFIG["LIBRUBY_A"] = "$(RUBY_SO_NAME)-static.lib" + CONFIG["LIBRUBY_SO"] = "$(RUBY_SO_NAME).dll" + CONFIG["LIBRUBY_ALIASES"] = "" + CONFIG["LIBRUBY"] = "$(RUBY_SO_NAME).lib" + CONFIG["LIBRUBYARG"] = "$(LIBRUBYARG_SHARED)" + CONFIG["LIBRUBYARG_STATIC"] = "$(LIBRUBY_A)" + CONFIG["LIBRUBYARG_SHARED"] = "$(LIBRUBY)" + CONFIG["SOLIBS"] = "" + CONFIG["DLDLIBS"] = "" + CONFIG["ENABLE_SHARED"] = "yes" + CONFIG["OUTFLAG"] = "-Fe" + CONFIG["CPPOUTFILE"] = "-P" + CONFIG["LIBPATHFLAG"] = " -libpath:\"%s\"" + CONFIG["RPATHFLAG"] = "" + CONFIG["LIBARG"] = "%s.lib" + CONFIG["LINK_SO"] = "$(LDSHARED) -Fe$(@) $(OBJS) $(LIBS) $(LOCAL_LIBS) $(DLDFLAGS)" + CONFIG["COMPILE_C"] = "$(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)" + CONFIG["COMPILE_CXX"] = "$(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\\=/)" + CONFIG["COMPILE_RULES"] = "{$(srcdir)}.%s{}.%s: {$(topdir)}.%s{}.%s: {$(hdrdir)}.%s{}.%s: .%s.%s:" + CONFIG["RULE_SUBST"] = "{.;$(srcdir);$(topdir);$(hdrdir)}%s" + CONFIG["TRY_LINK"] = "$(CC) -Feconftest $(INCFLAGS) -I$(hdrdir) $(CPPFLAGS) $(CFLAGS) $(src) $(LOCAL_LIBS) $(LIBS) -link $(LDFLAGS) $(LIBPATH) $(XLDFLAGS)" + CONFIG["COMMON_LIBS"] = "m" + CONFIG["COMMON_MACROS"] = "WIN32_LEAN_AND_MEAN" + CONFIG["COMMON_HEADERS"] = "winsock2.h windows.h" + CONFIG["DISTCLEANFILES"] = "vc*.pdb" + CONFIG["EXPORT_PREFIX"] = " " + CONFIG["arch"] = "i386-mswin32" + CONFIG["sitearch"] = "i386-msvcrt" + CONFIG["sitedir"] = "$(prefix)/lib/ruby/site_ruby" + CONFIG["configure_args"] = "--with-make-prog=nmake --enable-shared --with-winsock2" + CONFIG["ruby_version"] = "$(MAJOR).$(MINOR)" + CONFIG["rubylibdir"] = "$(libdir)/ruby/$(ruby_version)" + CONFIG["archdir"] = "$(rubylibdir)/$(arch)" + CONFIG["sitelibdir"] = "$(sitedir)/$(ruby_version)" + CONFIG["sitearchdir"] = "$(sitelibdir)/$(sitearch)" + CONFIG["topdir"] = File.dirname(__FILE__) + MAKEFILE_CONFIG = {} + CONFIG.each{|k,v| MAKEFILE_CONFIG[k] = v.dup} + def Config::expand(val, config = CONFIG) + val.gsub!(/\$\$|\$\(([^()]+)\)|\$\{([^{}]+)\}/) do |var| + if !(v = $1 || $2) + '$' + elsif key = config[v = v[/\A[^:]+(?=(?::(.*?)=(.*))?\z)/]] + pat, sub = $1, $2 + config[v] = false + Config::expand(key, config) + config[v] = key + key = key.gsub(/#{Regexp.quote(pat)}(?=\s|\z)/n) {sub} if pat + key + else + var + end + end + val + end + CONFIG.each_value do |val| + Config::expand(val) + end +end +RbConfig = Config # compatibility for ruby-1.9 +CROSS_COMPILING = nil unless defined? CROSS_COMPILING diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/code_objects.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/code_objects.rb new file mode 100644 index 00000000..d6c4f1bd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/code_objects.rb @@ -0,0 +1,765 @@ +# We represent the various high-level code constructs that appear +# in Ruby programs: classes, modules, methods, and so on. + +require 'rdoc/tokenstream' + +module RDoc + + + # We contain the common stuff for contexts (which are containers) + # and other elements (methods, attributes and so on) + # + class CodeObject + + attr_accessor :parent + + # We are the model of the code, but we know that at some point + # we will be worked on by viewers. By implementing the Viewable + # protocol, viewers can associated themselves with these objects. + + attr_accessor :viewer + + # are we done documenting (ie, did we come across a :enddoc:)? + + attr_accessor :done_documenting + + # Which section are we in + + attr_accessor :section + + # do we document ourselves? + + attr_reader :document_self + + def document_self=(val) + @document_self = val + if !val + remove_methods_etc + end + end + + # set and cleared by :startdoc: and :enddoc:, this is used to toggle + # the capturing of documentation + def start_doc + @document_self = true + @document_children = true + end + + def stop_doc + @document_self = false + @document_children = false + end + + # do we document ourselves and our children + + attr_reader :document_children + + def document_children=(val) + @document_children = val + if !val + remove_classes_and_modules + end + end + + # Do we _force_ documentation, even is we wouldn't normally show the entity + attr_accessor :force_documentation + + # Default callbacks to nothing, but this is overridden for classes + # and modules + def remove_classes_and_modules + end + + def remove_methods_etc + end + + def initialize + @document_self = true + @document_children = true + @force_documentation = false + @done_documenting = false + end + + # Access the code object's comment + attr_reader :comment + + # Update the comment, but don't overwrite a real comment + # with an empty one + def comment=(comment) + @comment = comment unless comment.empty? + end + + # There's a wee trick we pull. Comment blocks can have directives that + # override the stuff we extract during the parse. So, we have a special + # class method, attr_overridable, that lets code objects list + # those directives. Wehn a comment is assigned, we then extract + # out any matching directives and update our object + + def CodeObject.attr_overridable(name, *aliases) + @overridables ||= {} + + attr_accessor name + + aliases.unshift name + aliases.each do |directive_name| + @overridables[directive_name.to_s] = name + end + end + + end + + # A Context is something that can hold modules, classes, methods, + # attributes, aliases, requires, and includes. Classes, modules, and + # files are all Contexts. + + class Context < CodeObject + attr_reader :name, :method_list, :attributes, :aliases, :constants + attr_reader :requires, :includes, :in_files, :visibility + + attr_reader :sections + + class Section + attr_reader :title, :comment, :sequence + + @@sequence = "SEC00000" + + def initialize(title, comment) + @title = title + @@sequence.succ! + @sequence = @@sequence.dup + set_comment(comment) + end + + private + + # Set the comment for this section from the original comment block + # If the first line contains :section:, strip it and use the rest. Otherwise + # remove lines up to the line containing :section:, and look for + # those lines again at the end and remove them. This lets us write + # + # # --------------------- + # # :SECTION: The title + # # The body + # # --------------------- + + def set_comment(comment) + return unless comment + + if comment =~ /^.*?:section:.*$/ + start = $` + rest = $' + if start.empty? + @comment = rest + else + @comment = rest.sub(/#{start.chomp}\Z/, '') + end + else + @comment = comment + end + @comment = nil if @comment.empty? + end + end + + + def initialize + super() + + @in_files = [] + + @name ||= "unknown" + @comment ||= "" + @parent = nil + @visibility = :public + + @current_section = Section.new(nil, nil) + @sections = [ @current_section ] + + initialize_methods_etc + initialize_classes_and_modules + end + + # map the class hash to an array externally + def classes + @classes.values + end + + # map the module hash to an array externally + def modules + @modules.values + end + + # Change the default visibility for new methods + def ongoing_visibility=(vis) + @visibility = vis + end + + # Given an array +methods+ of method names, set the + # visibility of the corresponding AnyMethod object + + def set_visibility_for(methods, vis, singleton=false) + count = 0 + @method_list.each do |m| + if methods.include?(m.name) && m.singleton == singleton + m.visibility = vis + count += 1 + end + end + + return if count == methods.size || singleton + + # perhaps we need to look at attributes + + @attributes.each do |a| + if methods.include?(a.name) + a.visibility = vis + count += 1 + end + end + end + + # Record the file that we happen to find it in + def record_location(toplevel) + @in_files << toplevel unless @in_files.include?(toplevel) + end + + # Return true if at least part of this thing was defined in +file+ + def defined_in?(file) + @in_files.include?(file) + end + + def add_class(class_type, name, superclass) + add_class_or_module(@classes, class_type, name, superclass) + end + + def add_module(class_type, name) + add_class_or_module(@modules, class_type, name, nil) + end + + def add_method(a_method) + puts "Adding #@visibility method #{a_method.name} to #@name" if $DEBUG + a_method.visibility = @visibility + add_to(@method_list, a_method) + end + + def add_attribute(an_attribute) + add_to(@attributes, an_attribute) + end + + def add_alias(an_alias) + meth = find_instance_method_named(an_alias.old_name) + if meth + new_meth = AnyMethod.new(an_alias.text, an_alias.new_name) + new_meth.is_alias_for = meth + new_meth.singleton = meth.singleton + new_meth.params = meth.params + new_meth.comment = "Alias for \##{meth.name}" + meth.add_alias(new_meth) + add_method(new_meth) + else + add_to(@aliases, an_alias) + end + end + + def add_include(an_include) + add_to(@includes, an_include) + end + + def add_constant(const) + add_to(@constants, const) + end + + # Requires always get added to the top-level (file) context + def add_require(a_require) + if self.kind_of? TopLevel + add_to(@requires, a_require) + else + parent.add_require(a_require) + end + end + + def add_class_or_module(collection, class_type, name, superclass=nil) + cls = collection[name] + if cls + puts "Reusing class/module #{name}" if $DEBUG + else + cls = class_type.new(name, superclass) + puts "Adding class/module #{name} to #@name" if $DEBUG +# collection[name] = cls if @document_self && !@done_documenting + collection[name] = cls if !@done_documenting + cls.parent = self + cls.section = @current_section + end + cls + end + + def add_to(array, thing) + array << thing if @document_self && !@done_documenting + thing.parent = self + thing.section = @current_section + end + + # If a class's documentation is turned off after we've started + # collecting methods etc., we need to remove the ones + # we have + + def remove_methods_etc + initialize_methods_etc + end + + def initialize_methods_etc + @method_list = [] + @attributes = [] + @aliases = [] + @requires = [] + @includes = [] + @constants = [] + end + + # and remove classes and modules when we see a :nodoc: all + def remove_classes_and_modules + initialize_classes_and_modules + end + + def initialize_classes_and_modules + @classes = {} + @modules = {} + end + + # Find a named module + def find_module_named(name) + return self if self.name == name + res = @modules[name] || @classes[name] + return res if res + find_enclosing_module_named(name) + end + + # find a module at a higher scope + def find_enclosing_module_named(name) + parent && parent.find_module_named(name) + end + + # Iterate over all the classes and modules in + # this object + + def each_classmodule + @modules.each_value {|m| yield m} + @classes.each_value {|c| yield c} + end + + def each_method + @method_list.each {|m| yield m} + end + + def each_attribute + @attributes.each {|a| yield a} + end + + def each_constant + @constants.each {|c| yield c} + end + + # Return the toplevel that owns us + + def toplevel + return @toplevel if defined? @toplevel + @toplevel = self + @toplevel = @toplevel.parent until TopLevel === @toplevel + @toplevel + end + + # allow us to sort modules by name + def <=>(other) + name <=> other.name + end + + # Look up the given symbol. If method is non-nil, then + # we assume the symbol references a module that + # contains that method + def find_symbol(symbol, method=nil) + result = nil + case symbol + when /^::(.*)/ + result = toplevel.find_symbol($1) + when /::/ + modules = symbol.split(/::/) + unless modules.empty? + module_name = modules.shift + result = find_module_named(module_name) + if result + modules.each do |module_name| + result = result.find_module_named(module_name) + break unless result + end + end + end + else + # if a method is specified, then we're definitely looking for + # a module, otherwise it could be any symbol + if method + result = find_module_named(symbol) + else + result = find_local_symbol(symbol) + if result.nil? + if symbol =~ /^[A-Z]/ + result = parent + while result && result.name != symbol + result = result.parent + end + end + end + end + end + if result && method + if !result.respond_to?(:find_local_symbol) + p result.name + p method + fail + end + result = result.find_local_symbol(method) + end + result + end + + def find_local_symbol(symbol) + res = find_method_named(symbol) || + find_constant_named(symbol) || + find_attribute_named(symbol) || + find_module_named(symbol) + end + + # Handle sections + + def set_current_section(title, comment) + @current_section = Section.new(title, comment) + @sections << @current_section + end + + private + + # Find a named method, or return nil + def find_method_named(name) + @method_list.find {|meth| meth.name == name} + end + + # Find a named instance method, or return nil + def find_instance_method_named(name) + @method_list.find {|meth| meth.name == name && !meth.singleton} + end + + # Find a named constant, or return nil + def find_constant_named(name) + @constants.find {|m| m.name == name} + end + + # Find a named attribute, or return nil + def find_attribute_named(name) + @attributes.find {|m| m.name == name} + end + + end + + + # A TopLevel context is a source file + + class TopLevel < Context + attr_accessor :file_stat + attr_accessor :file_relative_name + attr_accessor :file_absolute_name + attr_accessor :diagram + + @@all_classes = {} + @@all_modules = {} + + def TopLevel::reset + @@all_classes = {} + @@all_modules = {} + end + + def initialize(file_name) + super() + @name = "TopLevel" + @file_relative_name = file_name + @file_absolute_name = file_name + @file_stat = File.stat(file_name) + @diagram = nil + end + + def full_name + nil + end + + # Adding a class or module to a TopLevel is special, as we only + # want one copy of a particular top-level class. For example, + # if both file A and file B implement class C, we only want one + # ClassModule object for C. This code arranges to share + # classes and modules between files. + + def add_class_or_module(collection, class_type, name, superclass) + cls = collection[name] + if cls + puts "Reusing class/module #{name}" if $DEBUG + else + if class_type == NormalModule + all = @@all_modules + else + all = @@all_classes + end + cls = all[name] + if !cls + cls = class_type.new(name, superclass) + all[name] = cls unless @done_documenting + end + puts "Adding class/module #{name} to #@name" if $DEBUG + collection[name] = cls unless @done_documenting + cls.parent = self + end + cls + end + + def TopLevel.all_classes_and_modules + @@all_classes.values + @@all_modules.values + end + + def TopLevel.find_class_named(name) + @@all_classes.each_value do |c| + res = c.find_class_named(name) + return res if res + end + nil + end + + def find_local_symbol(symbol) + find_class_or_module_named(symbol) || super + end + + def find_class_or_module_named(symbol) + @@all_classes.each_value {|c| return c if c.name == symbol} + @@all_modules.each_value {|m| return m if m.name == symbol} + nil + end + + # Find a named module + def find_module_named(name) + find_class_or_module_named(name) || find_enclosing_module_named(name) + end + + + end + + # ClassModule is the base class for objects representing either a + # class or a module. + + class ClassModule < Context + + attr_reader :superclass + attr_accessor :diagram + + def initialize(name, superclass = nil) + @name = name + @diagram = nil + @superclass = superclass + @comment = "" + super() + end + + # Return the fully qualified name of this class or module + def full_name + if @parent && @parent.full_name + @parent.full_name + "::" + @name + else + @name + end + end + + def http_url(prefix) + path = full_name.split("::") + File.join(prefix, *path) + ".html" + end + + # Return +true+ if this object represents a module + def is_module? + false + end + + # to_s is simply for debugging + def to_s + res = self.class.name + ": " + @name + res << @comment.to_s + res << super + res + end + + def find_class_named(name) + return self if full_name == name + @classes.each_value {|c| return c if c.find_class_named(name) } + nil + end + end + + # Anonymous classes + class AnonClass < ClassModule + end + + # Normal classes + class NormalClass < ClassModule + end + + # Singleton classes + class SingleClass < ClassModule + end + + # Module + class NormalModule < ClassModule + def is_module? + true + end + end + + + # AnyMethod is the base class for objects representing methods + + class AnyMethod < CodeObject + attr_accessor :name + attr_accessor :visibility + attr_accessor :block_params + attr_accessor :dont_rename_initialize + attr_accessor :singleton + attr_reader :aliases # list of other names for this method + attr_accessor :is_alias_for # or a method we're aliasing + + attr_overridable :params, :param, :parameters, :parameter + + attr_accessor :call_seq + + + include TokenStream + + def initialize(text, name) + super() + @text = text + @name = name + @token_stream = nil + @visibility = :public + @dont_rename_initialize = false + @block_params = nil + @aliases = [] + @is_alias_for = nil + @comment = "" + @call_seq = nil + end + + def <=>(other) + @name <=> other.name + end + + def to_s + res = self.class.name + ": " + @name + " (" + @text + ")\n" + res << @comment.to_s + res + end + + def param_seq + p = params.gsub(/\s*\#.*/, '') + p = p.tr("\n", " ").squeeze(" ") + p = "(" + p + ")" unless p[0] == ?( + + if (block = block_params) + # If this method has explicit block parameters, remove any + # explicit &block +$stderr.puts p + p.sub!(/,?\s*&\w+/) +$stderr.puts p + + block.gsub!(/\s*\#.*/, '') + block = block.tr("\n", " ").squeeze(" ") + if block[0] == ?( + block.sub!(/^\(/, '').sub!(/\)/, '') + end + p << " {|#{block}| ...}" + end + p + end + + def add_alias(method) + @aliases << method + end + end + + + # Represent an alias, which is an old_name/ new_name pair associated + # with a particular context + class Alias < CodeObject + attr_accessor :text, :old_name, :new_name, :comment + + def initialize(text, old_name, new_name, comment) + super() + @text = text + @old_name = old_name + @new_name = new_name + self.comment = comment + end + + def to_s + "alias: #{self.old_name} -> #{self.new_name}\n#{self.comment}" + end + end + + # Represent a constant + class Constant < CodeObject + attr_accessor :name, :value + + def initialize(name, value, comment) + super() + @name = name + @value = value + self.comment = comment + end + end + + # Represent attributes + class Attr < CodeObject + attr_accessor :text, :name, :rw, :visibility + + def initialize(text, name, rw, comment) + super() + @text = text + @name = name + @rw = rw + @visibility = :public + self.comment = comment + end + + def to_s + "attr: #{self.name} #{self.rw}\n#{self.comment}" + end + + def <=>(other) + self.name <=> other.name + end + end + + # a required file + + class Require < CodeObject + attr_accessor :name + + def initialize(name, comment) + super() + @name = name.gsub(/'|"/, "") #' + self.comment = comment + end + + end + + # an included module + class Include < CodeObject + attr_accessor :name + + def initialize(name, comment) + super() + @name = name + self.comment = comment + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/diagram.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/diagram.rb new file mode 100644 index 00000000..9fdc49c0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/diagram.rb @@ -0,0 +1,335 @@ +# A wonderful hack by to draw package diagrams using the dot package. +# Originally written by Jah, team Enticla. +# +# You must have the V1.7 or later in your path +# http://www.research.att.com/sw/tools/graphviz/ + +require "rdoc/dot/dot" +require 'rdoc/options' + +module RDoc + + # Draw a set of diagrams representing the modules and classes in the + # system. We draw one diagram for each file, and one for each toplevel + # class or module. This means there will be overlap. However, it also + # means that you'll get better context for objects. + # + # To use, simply + # + # d = Diagram.new(info) # pass in collection of top level infos + # d.draw + # + # The results will be written to the +dot+ subdirectory. The process + # also sets the +diagram+ attribute in each object it graphs to + # the name of the file containing the image. This can be used + # by output generators to insert images. + + class Diagram + + FONT = "Arial" + + DOT_PATH = "dot" + + # Pass in the set of top level objects. The method also creates + # the subdirectory to hold the images + + def initialize(info, options) + @info = info + @options = options + @counter = 0 + File.makedirs(DOT_PATH) + @diagram_cache = {} + end + + # Draw the diagrams. We traverse the files, drawing a diagram for + # each. We also traverse each top-level class and module in that + # file drawing a diagram for these too. + + def draw + unless @options.quiet + $stderr.print "Diagrams: " + $stderr.flush + end + + @info.each_with_index do |i, file_count| + @done_modules = {} + @local_names = find_names(i) + @global_names = [] + @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel', + 'fontname' => FONT, + 'fontsize' => '8', + 'bgcolor' => 'lightcyan1', + 'compound' => 'true') + + # it's a little hack %) i'm too lazy to create a separate class + # for default node + graph << DOT::DOTNode.new('name' => 'node', + 'fontname' => FONT, + 'color' => 'black', + 'fontsize' => 8) + + i.modules.each do |mod| + draw_module(mod, graph, true, i.file_relative_name) + end + add_classes(i, graph, i.file_relative_name) + + i.diagram = convert_to_png("f_#{file_count}", graph) + + # now go through and document each top level class and + # module independently + i.modules.each_with_index do |mod, count| + @done_modules = {} + @local_names = find_names(mod) + @global_names = [] + + @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel', + 'fontname' => FONT, + 'fontsize' => '8', + 'bgcolor' => 'lightcyan1', + 'compound' => 'true') + + graph << DOT::DOTNode.new('name' => 'node', + 'fontname' => FONT, + 'color' => 'black', + 'fontsize' => 8) + draw_module(mod, graph, true) + mod.diagram = convert_to_png("m_#{file_count}_#{count}", + graph) + end + end + $stderr.puts unless @options.quiet + end + + ####### + private + ####### + + def find_names(mod) + return [mod.full_name] + mod.classes.collect{|cl| cl.full_name} + + mod.modules.collect{|m| find_names(m)}.flatten + end + + def find_full_name(name, mod) + full_name = name.dup + return full_name if @local_names.include?(full_name) + mod_path = mod.full_name.split('::')[0..-2] + unless mod_path.nil? + until mod_path.empty? + full_name = mod_path.pop + '::' + full_name + return full_name if @local_names.include?(full_name) + end + end + return name + end + + def draw_module(mod, graph, toplevel = false, file = nil) + return if @done_modules[mod.full_name] and not toplevel + + @counter += 1 + url = mod.http_url("classes") + m = DOT::DOTSubgraph.new('name' => "cluster_#{mod.full_name.gsub( /:/,'_' )}", + 'label' => mod.name, + 'fontname' => FONT, + 'color' => 'blue', + 'style' => 'filled', + 'URL' => %{"#{url}"}, + 'fillcolor' => toplevel ? 'palegreen1' : 'palegreen3') + + @done_modules[mod.full_name] = m + add_classes(mod, m, file) + graph << m + + unless mod.includes.empty? + mod.includes.each do |m| + m_full_name = find_full_name(m.name, mod) + if @local_names.include?(m_full_name) + @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{mod.full_name.gsub( /:/,'_' )}", + 'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}", + 'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}") + else + unless @global_names.include?(m_full_name) + path = m_full_name.split("::") + url = File.join('classes', *path) + ".html" + @global_graph << DOT::DOTNode.new('name' => "#{m_full_name.gsub( /:/,'_' )}", + 'shape' => 'box', + 'label' => "#{m_full_name}", + 'URL' => %{"#{url}"}) + @global_names << m_full_name + end + @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{mod.full_name.gsub( /:/,'_' )}", + 'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}") + end + end + end + end + + def add_classes(container, graph, file = nil ) + + use_fileboxes = Options.instance.fileboxes + + files = {} + + # create dummy node (needed if empty and for module includes) + if container.full_name + graph << DOT::DOTNode.new('name' => "#{container.full_name.gsub( /:/,'_' )}", + 'label' => "", + 'width' => (container.classes.empty? and + container.modules.empty?) ? + '0.75' : '0.01', + 'height' => '0.01', + 'shape' => 'plaintext') + end + container.classes.each_with_index do |cl, cl_index| + last_file = cl.in_files[-1].file_relative_name + + if use_fileboxes && !files.include?(last_file) + @counter += 1 + files[last_file] = + DOT::DOTSubgraph.new('name' => "cluster_#{@counter}", + 'label' => "#{last_file}", + 'fontname' => FONT, + 'color'=> + last_file == file ? 'red' : 'black') + end + + next if cl.name == 'Object' || cl.name[0,2] == "<<" + + url = cl.http_url("classes") + + label = cl.name.dup + if use_fileboxes && cl.in_files.length > 1 + label << '\n[' + + cl.in_files.collect {|i| + i.file_relative_name + }.sort.join( '\n' ) + + ']' + end + + attrs = { + 'name' => "#{cl.full_name.gsub( /:/, '_' )}", + 'fontcolor' => 'black', + 'style'=>'filled', + 'color'=>'palegoldenrod', + 'label' => label, + 'shape' => 'ellipse', + 'URL' => %{"#{url}"} + } + + c = DOT::DOTNode.new(attrs) + + if use_fileboxes + files[last_file].push c + else + graph << c + end + end + + if use_fileboxes + files.each_value do |val| + graph << val + end + end + + unless container.classes.empty? + container.classes.each_with_index do |cl, cl_index| + cl.includes.each do |m| + m_full_name = find_full_name(m.name, cl) + if @local_names.include?(m_full_name) + @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{cl.full_name.gsub( /:/,'_' )}", + 'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}") + else + unless @global_names.include?(m_full_name) + path = m_full_name.split("::") + url = File.join('classes', *path) + ".html" + @global_graph << DOT::DOTNode.new('name' => "#{m_full_name.gsub( /:/,'_' )}", + 'shape' => 'box', + 'label' => "#{m_full_name}", + 'URL' => %{"#{url}"}) + @global_names << m_full_name + end + @global_graph << DOT::DOTEdge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{cl.full_name.gsub( /:/, '_')}") + end + end + + sclass = cl.superclass + next if sclass.nil? || sclass == 'Object' + sclass_full_name = find_full_name(sclass,cl) + unless @local_names.include?(sclass_full_name) or @global_names.include?(sclass_full_name) + path = sclass_full_name.split("::") + url = File.join('classes', *path) + ".html" + @global_graph << DOT::DOTNode.new( + 'name' => "#{sclass_full_name.gsub( /:/, '_' )}", + 'label' => sclass_full_name, + 'URL' => %{"#{url}"}) + @global_names << sclass_full_name + end + @global_graph << DOT::DOTEdge.new('from' => "#{sclass_full_name.gsub( /:/,'_' )}", + 'to' => "#{cl.full_name.gsub( /:/, '_')}") + end + end + + container.modules.each do |submod| + draw_module(submod, graph) + end + + end + + def convert_to_png(file_base, graph) + str = graph.to_s + return @diagram_cache[str] if @diagram_cache[str] + op_type = Options.instance.image_format + dotfile = File.join(DOT_PATH, file_base) + src = dotfile + ".dot" + dot = dotfile + "." + op_type + + unless @options.quiet + $stderr.print "." + $stderr.flush + end + + File.open(src, 'w+' ) do |f| + f << str << "\n" + end + + system "dot", "-T#{op_type}", src, "-o", dot + + # Now construct the imagemap wrapper around + # that png + + ret = wrap_in_image_map(src, dot) + @diagram_cache[str] = ret + return ret + end + + # Extract the client-side image map from dot, and use it + # to generate the imagemap proper. Return the whole + # .. combination, suitable for inclusion on + # the page + + def wrap_in_image_map(src, dot) + res = %{\n} + dot_map = `dot -Tismap #{src}` + dot_map.each do |area| + unless area =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) ([\/\w.]+)\s*(.*)/ + $stderr.puts "Unexpected output from dot:\n#{area}" + return nil + end + + xs, ys = [$1.to_i, $3.to_i], [$2.to_i, $4.to_i] + url, area_name = $5, $6 + + res << %{ #{area_name}\n} + end + res << "\n" +# map_file = src.sub(/.dot/, '.map') +# system("dot -Timap #{src} -o #{map_file}") + res << %{#{dot}} + return res + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/dot/dot.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/dot/dot.rb new file mode 100644 index 00000000..6dbb7cb2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/dot/dot.rb @@ -0,0 +1,255 @@ +module DOT + + # these glogal vars are used to make nice graph source + $tab = ' ' + $tab2 = $tab * 2 + + # if we don't like 4 spaces, we can change it any time + def change_tab( t ) + $tab = t + $tab2 = t * 2 + end + + # options for node declaration + NODE_OPTS = [ + 'bgcolor', + 'color', + 'fontcolor', + 'fontname', + 'fontsize', + 'height', + 'width', + 'label', + 'layer', + 'rank', + 'shape', + 'shapefile', + 'style', + 'URL', + ] + + # options for edge declaration + EDGE_OPTS = [ + 'color', + 'decorate', + 'dir', + 'fontcolor', + 'fontname', + 'fontsize', + 'id', + 'label', + 'layer', + 'lhead', + 'ltail', + 'minlen', + 'style', + 'weight' + ] + + # options for graph declaration + GRAPH_OPTS = [ + 'bgcolor', + 'center', + 'clusterrank', + 'color', + 'compound', + 'concentrate', + 'fillcolor', + 'fontcolor', + 'fontname', + 'fontsize', + 'label', + 'layerseq', + 'margin', + 'mclimit', + 'nodesep', + 'nslimit', + 'ordering', + 'orientation', + 'page', + 'rank', + 'rankdir', + 'ranksep', + 'ratio', + 'size', + 'style', + 'URL' + ] + + # a root class for any element in dot notation + class DOTSimpleElement + attr_accessor :name + + def initialize( params = {} ) + @label = params['name'] ? params['name'] : '' + end + + def to_s + @name + end + end + + # an element that has options ( node, edge or graph ) + class DOTElement < DOTSimpleElement + #attr_reader :parent + attr_accessor :name, :options + + def initialize( params = {}, option_list = [] ) + super( params ) + @name = params['name'] ? params['name'] : nil + @parent = params['parent'] ? params['parent'] : nil + @options = {} + option_list.each{ |i| + @options[i] = params[i] if params[i] + } + @options['label'] ||= @name if @name != 'node' + end + + def each_option + @options.each{ |i| yield i } + end + + def each_option_pair + @options.each_pair{ |key, val| yield key, val } + end + + #def parent=( thing ) + # @parent.delete( self ) if defined?( @parent ) and @parent + # @parent = thing + #end + end + + + # this is used when we build nodes that have shape=record + # ports don't have options :) + class DOTPort < DOTSimpleElement + attr_accessor :label + + def initialize( params = {} ) + super( params ) + @name = params['label'] ? params['label'] : '' + end + def to_s + ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}" + end + end + + # node element + class DOTNode < DOTElement + + def initialize( params = {}, option_list = NODE_OPTS ) + super( params, option_list ) + @ports = params['ports'] ? params['ports'] : [] + end + + def each_port + @ports.each{ |i| yield i } + end + + def << ( thing ) + @ports << thing + end + + def push ( thing ) + @ports.push( thing ) + end + + def pop + @ports.pop + end + + def to_s( t = '' ) + + label = @options['shape'] != 'record' && @ports.length == 0 ? + @options['label'] ? + t + $tab + "label = \"#{@options['label']}\"\n" : + '' : + t + $tab + 'label = "' + " \\\n" + + t + $tab2 + "#{@options['label']}| \\\n" + + @ports.collect{ |i| + t + $tab2 + i.to_s + }.join( "| \\\n" ) + " \\\n" + + t + $tab + '"' + "\n" + + t + "#{@name} [\n" + + @options.to_a.collect{ |i| + i[1] && i[0] != 'label' ? + t + $tab + "#{i[0]} = #{i[1]}" : nil + }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) + + label + + t + "]\n" + end + end + + # subgraph element is the same to graph, but has another header in dot + # notation + class DOTSubgraph < DOTElement + + def initialize( params = {}, option_list = GRAPH_OPTS ) + super( params, option_list ) + @nodes = params['nodes'] ? params['nodes'] : [] + @dot_string = 'subgraph' + end + + def each_node + @nodes.each{ |i| yield i } + end + + def << ( thing ) + @nodes << thing + end + + def push( thing ) + @nodes.push( thing ) + end + + def pop + @nodes.pop + end + + def to_s( t = '' ) + hdr = t + "#{@dot_string} #{@name} {\n" + + options = @options.to_a.collect{ |name, val| + val && name != 'label' ? + t + $tab + "#{name} = #{val}" : + name ? t + $tab + "#{name} = \"#{val}\"" : nil + }.compact.join( "\n" ) + "\n" + + nodes = @nodes.collect{ |i| + i.to_s( t + $tab ) + }.join( "\n" ) + "\n" + hdr + options + nodes + t + "}\n" + end + end + + # this is graph + class DOTDigraph < DOTSubgraph + def initialize( params = {}, option_list = GRAPH_OPTS ) + super( params, option_list ) + @dot_string = 'digraph' + end + end + + # this is edge + class DOTEdge < DOTElement + attr_accessor :from, :to + def initialize( params = {}, option_list = EDGE_OPTS ) + super( params, option_list ) + @from = params['from'] ? params['from'] : nil + @to = params['to'] ? params['to'] : nil + end + + def to_s( t = '' ) + t + "#{@from} -> #{to} [\n" + + @options.to_a.collect{ |i| + i[1] && i[0] != 'label' ? + t + $tab + "#{i[0]} = #{i[1]}" : + i[1] ? t + $tab + "#{i[0]} = \"#{i[1]}\"" : nil + }.compact.join( "\n" ) + "\n" + t + "]\n" + end + end +end + + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/chm_generator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/chm_generator.rb new file mode 100644 index 00000000..51eeda8d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/chm_generator.rb @@ -0,0 +1,112 @@ +require 'rdoc/generators/html_generator' + +module Generators + + class CHMGenerator < HTMLGenerator + + HHC_PATH = "c:/Program Files/HTML Help Workshop/hhc.exe" + + # Standard generator factory + def CHMGenerator.for(options) + CHMGenerator.new(options) + end + + + def initialize(*args) + super + @op_name = @options.op_name || "rdoc" + check_for_html_help_workshop + end + + def check_for_html_help_workshop + stat = File.stat(HHC_PATH) + rescue + $stderr << + "\n.chm output generation requires that Microsoft's Html Help\n" << + "Workshop is installed. RDoc looks for it in:\n\n " << + HHC_PATH << + "\n\nYou can download a copy for free from:\n\n" << + " http://msdn.microsoft.com/library/default.asp?" << + "url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp\n\n" + + exit 99 + end + + # Generate the html as normal, then wrap it + # in a help project + def generate(info) + super + @project_name = @op_name + ".hhp" + create_help_project + end + + # The project contains the project file, a table of contents + # and an index + def create_help_project + create_project_file + create_contents_and_index + compile_project + end + + # The project file links together all the various + # files that go to make up the help. + + def create_project_file + template = TemplatePage.new(RDoc::Page::HPP_FILE) + values = { "title" => @options.title, "opname" => @op_name } + files = [] + @files.each do |f| + files << { "html_file_name" => f.path } + end + + values['all_html_files'] = files + + File.open(@project_name, "w") do |f| + template.write_html_on(f, values) + end + end + + # The contents is a list of all files and modules. + # For each we include as sub-entries the list + # of methods they contain. As we build the contents + # we also build an index file + + def create_contents_and_index + contents = [] + index = [] + + (@files+@classes).sort.each do |entry| + content_entry = { "c_name" => entry.name, "ref" => entry.path } + index << { "name" => entry.name, "aref" => entry.path } + + internals = [] + + methods = entry.build_method_summary_list(entry.path) + + content_entry["methods"] = methods unless methods.empty? + contents << content_entry + index.concat methods + end + + values = { "contents" => contents } + template = TemplatePage.new(RDoc::Page::CONTENTS) + File.open("contents.hhc", "w") do |f| + template.write_html_on(f, values) + end + + values = { "index" => index } + template = TemplatePage.new(RDoc::Page::CHM_INDEX) + File.open("index.hhk", "w") do |f| + template.write_html_on(f, values) + end + end + + # Invoke the windows help compiler to compiler the project + def compile_project + system(HHC_PATH, @project_name) + end + + end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/html_generator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/html_generator.rb new file mode 100644 index 00000000..1f9b808e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/html_generator.rb @@ -0,0 +1,1509 @@ +# We're responsible for generating all the HTML files +# from the object tree defined in code_objects.rb. We +# generate: +# +# [files] an html file for each input file given. These +# input files appear as objects of class +# TopLevel +# +# [classes] an html file for each class or module encountered. +# These classes are not grouped by file: if a file +# contains four classes, we'll generate an html +# file for the file itself, and four html files +# for the individual classes. +# +# [indices] we generate three indices for files, classes, +# and methods. These are displayed in a browser +# like window with three index panes across the +# top and the selected description below +# +# Method descriptions appear in whatever entity (file, class, +# or module) that contains them. +# +# We generate files in a structure below a specified subdirectory, +# normally +doc+. +# +# opdir +# | +# |___ files +# | |__ per file summaries +# | +# |___ classes +# |__ per class/module descriptions +# +# HTML is generated using the Template class. +# + +require 'ftools' + +require 'rdoc/options' +require 'rdoc/template' +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_html' +require 'cgi' + +module Generators + + # Name of sub-direcories that hold file and class/module descriptions + + FILE_DIR = "files" + CLASS_DIR = "classes" + CSS_NAME = "rdoc-style.css" + + + ## + # Build a hash of all items that can be cross-referenced. + # This is used when we output required and included names: + # if the names appear in this hash, we can generate + # an html cross reference to the appropriate description. + # We also use this when parsing comment blocks: any decorated + # words matching an entry in this list are hyperlinked. + + class AllReferences + @@refs = {} + + def AllReferences::reset + @@refs = {} + end + + def AllReferences.add(name, html_class) + @@refs[name] = html_class + end + + def AllReferences.[](name) + @@refs[name] + end + + def AllReferences.keys + @@refs.keys + end + end + + + ## + # Subclass of the SM::ToHtml class that supports looking + # up words in the AllReferences list. Those that are + # found (like AllReferences in this comment) will + # be hyperlinked + + class HyperlinkHtml < SM::ToHtml + # We need to record the html path of our caller so we can generate + # correct relative paths for any hyperlinks that we find + def initialize(from_path, context) + super() + @from_path = from_path + + @parent_name = context.parent_name + @parent_name += "::" if @parent_name + @context = context + end + + # We're invoked when any text matches the CROSSREF pattern + # (defined in MarkUp). If we fine the corresponding reference, + # generate a hyperlink. If the name we're looking for contains + # no punctuation, we look for it up the module/class chain. For + # example, HyperlinkHtml is found, even without the Generators:: + # prefix, because we look for it in module Generators first. + + def handle_special_CROSSREF(special) + name = special.text + if name[0,1] == '#' + lookup = name[1..-1] + name = lookup unless Options.instance.show_hash + else + lookup = name + end + + # Find class, module, or method in class or module. + if /([A-Z]\w*)[.\#](\w+[!?=]?)/ =~ lookup + container = $1 + method = $2 + ref = @context.find_symbol(container, method) + elsif /([A-Za-z]\w*)[.\#](\w+(\([\.\w+\*\/\+\-\=\<\>]+\))?)/ =~ lookup + container = $1 + method = $2 + ref = @context.find_symbol(container, method) + else + ref = @context.find_symbol(lookup) + end + + if ref and ref.document_self + "#{name}" + else + name + end + end + + + # Generate a hyperlink for url, labeled with text. Handle the + # special cases for img: and link: described under handle_special_HYPEDLINK + def gen_url(url, text) + if url =~ /([A-Za-z]+):(.*)/ + type = $1 + path = $2 + else + type = "http" + path = url + url = "http://#{url}" + end + + if type == "link" + if path[0,1] == '#' # is this meaningful? + url = path + else + url = HTMLGenerator.gen_url(@from_path, path) + end + end + + if (type == "http" || type == "link") && + url =~ /\.(gif|png|jpg|jpeg|bmp)$/ + + "" + else + "#{text.sub(%r{^#{type}:/*}, '')}" + end + end + + # And we're invoked with a potential external hyperlink mailto: + # just gets inserted. http: links are checked to see if they + # reference an image. If so, that image gets inserted using an + # tag. Otherwise a conventional is used. We also + # support a special type of hyperlink, link:, which is a reference + # to a local file whose path is relative to the --op directory. + + def handle_special_HYPERLINK(special) + url = special.text + gen_url(url, url) + end + + # HEre's a hypedlink where the label is different to the URL + #

/, '') + res.sub!(/<\/p>$/, '') + end + res + end + + # Qualify a stylesheet URL; if if +css_name+ does not begin with '/' or + # 'http[s]://', prepend a prefix relative to +path+. Otherwise, return it + # unmodified. + + def style_url(path, css_name=nil) +# $stderr.puts "style_url( #{path.inspect}, #{css_name.inspect} )" + css_name ||= CSS_NAME + if %r{^(https?:/)?/} =~ css_name + return css_name + else + return HTMLGenerator.gen_url(path, css_name) + end + end + + # Build a webcvs URL with the given 'url' argument. URLs with a '%s' in them + # get the file's path sprintfed into them; otherwise they're just catenated + # together. + + def cvs_url(url, full_path) + if /%s/ =~ url + return sprintf( url, full_path ) + else + return url + full_path + end + end + end + + + ##################################################################### + # + # A Context is built by the parser to represent a container: contexts + # hold classes, modules, methods, require lists and include lists. + # ClassModule and TopLevel are the context objects we process here + # + class ContextUser + + include MarkUp + + attr_reader :context + + def initialize(context, options) + @context = context + @options = options + end + + # convenience method to build a hyperlink + def href(link, cls, name) + %{#{name}} #" + end + + # return a reference to outselves to be used as an href= + # the form depends on whether we're all in one file + # or in multiple files + + def as_href(from_path) + if @options.all_one_file + "#" + path + else + HTMLGenerator.gen_url(from_path, path) + end + end + + # Create a list of HtmlMethod objects for each method + # in the corresponding context object. If the @options.show_all + # variable is set (corresponding to the --all option, + # we include all methods, otherwise just the public ones. + + def collect_methods + list = @context.method_list + unless @options.show_all + list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation } + end + @methods = list.collect {|m| HtmlMethod.new(m, self, @options) } + end + + # Build a summary list of all the methods in this context + def build_method_summary_list(path_prefix="") + collect_methods unless @methods + meths = @methods.sort + res = [] + meths.each do |meth| + res << { + "name" => CGI.escapeHTML(meth.name), + "aref" => "#{path_prefix}\##{meth.aref}" + } + end + res + end + + + # Build a list of aliases for which we couldn't find a + # corresponding method + def build_alias_summary_list(section) + values = [] + @context.aliases.each do |al| + next unless al.section == section + res = { + 'old_name' => al.old_name, + 'new_name' => al.new_name, + } + if al.comment && !al.comment.empty? + res['desc'] = markup(al.comment, true) + end + values << res + end + values + end + + # Build a list of constants + def build_constants_summary_list(section) + values = [] + @context.constants.each do |co| + next unless co.section == section + res = { + 'name' => co.name, + 'value' => CGI.escapeHTML(co.value) + } + res['desc'] = markup(co.comment, true) if co.comment && !co.comment.empty? + values << res + end + values + end + + def build_requires_list(context) + potentially_referenced_list(context.requires) {|fn| [fn + ".rb"] } + end + + def build_include_list(context) + potentially_referenced_list(context.includes) + end + + # Build a list from an array of Htmlxxx items. Look up each + # in the AllReferences hash: if we find a corresponding entry, + # we generate a hyperlink to it, otherwise just output the name. + # However, some names potentially need massaging. For example, + # you may require a Ruby file without the .rb extension, + # but the file names we know about may have it. To deal with + # this, we pass in a block which performs the massaging, + # returning an array of alternative names to match + + def potentially_referenced_list(array) + res = [] + array.each do |i| + ref = AllReferences[i.name] +# if !ref +# container = @context.parent +# while !ref && container +# name = container.name + "::" + i.name +# ref = AllReferences[name] +# container = container.parent +# end +# end + + ref = @context.find_symbol(i.name) + ref = ref.viewer if ref + + if !ref && block_given? + possibles = yield(i.name) + while !ref and !possibles.empty? + ref = AllReferences[possibles.shift] + end + end + h_name = CGI.escapeHTML(i.name) + if ref and ref.document_self + path = url(ref.path) + res << { "name" => h_name, "aref" => path } + else + res << { "name" => h_name } + end + end + res + end + + # Build an array of arrays of method details. The outer array has up + # to six entries, public, private, and protected for both class + # methods, the other for instance methods. The inner arrays contain + # a hash for each method + + def build_method_detail_list(section) + outer = [] + + methods = @methods.sort + for singleton in [true, false] + for vis in [ :public, :protected, :private ] + res = [] + methods.each do |m| + if m.section == section and + m.document_self and + m.visibility == vis and + m.singleton == singleton + row = {} + if m.call_seq + row["callseq"] = m.call_seq.gsub(/->/, '→') + else + row["name"] = CGI.escapeHTML(m.name) + row["params"] = m.params + end + desc = m.description.strip + row["m_desc"] = desc unless desc.empty? + row["aref"] = m.aref + row["visibility"] = m.visibility.to_s + + alias_names = [] + m.aliases.each do |other| + if other.viewer # won't be if the alias is private + alias_names << { + 'name' => other.name, + 'aref' => other.viewer.as_href(path) + } + end + end + unless alias_names.empty? + row["aka"] = alias_names + end + + if @options.inline_source + code = m.source_code + row["sourcecode"] = code if code + else + code = m.src_url + if code + row["codeurl"] = code + row["imgurl"] = m.img_url + end + end + res << row + end + end + if res.size > 0 + outer << { + "type" => vis.to_s.capitalize, + "category" => singleton ? "Class" : "Instance", + "methods" => res + } + end + end + end + outer + end + + # Build the structured list of classes and modules contained + # in this context. + + def build_class_list(level, from, section, infile=nil) + res = "" + prefix = "  ::" * level; + + from.modules.sort.each do |mod| + next unless mod.section == section + next if infile && !mod.defined_in?(infile) + if mod.document_self + res << + prefix << + "Module " << + href(url(mod.viewer.path), "link", mod.full_name) << + "
\n" << + build_class_list(level + 1, mod, section, infile) + end + end + + from.classes.sort.each do |cls| + next unless cls.section == section + next if infile && !cls.defined_in?(infile) + if cls.document_self + res << + prefix << + "Class " << + href(url(cls.viewer.path), "link", cls.full_name) << + "
\n" << + build_class_list(level + 1, cls, section, infile) + end + end + + res + end + + def url(target) + HTMLGenerator.gen_url(path, target) + end + + def aref_to(target) + if @options.all_one_file + "#" + target + else + url(target) + end + end + + def document_self + @context.document_self + end + + def diagram_reference(diagram) + res = diagram.gsub(/((?:src|href)=")(.*?)"/) { + $1 + url($2) + '"' + } + res + end + + + # Find a symbol in ourselves or our parent + def find_symbol(symbol, method=nil) + res = @context.find_symbol(symbol, method) + if res + res = res.viewer + end + res + end + + # create table of contents if we contain sections + + def add_table_of_sections + toc = [] + @context.sections.each do |section| + if section.title + toc << { + 'secname' => section.title, + 'href' => section.sequence + } + end + end + + @values['toc'] = toc unless toc.empty? + end + + + end + + ##################################################################### + # + # Wrap a ClassModule context + + class HtmlClass < ContextUser + + attr_reader :path + + def initialize(context, html_file, prefix, options) + super(context, options) + + @html_file = html_file + @is_module = context.is_module? + @values = {} + + context.viewer = self + + if options.all_one_file + @path = context.full_name + else + @path = http_url(context.full_name, prefix) + end + + collect_methods + + AllReferences.add(name, self) + end + + # return the relative file name to store this class in, + # which is also its url + def http_url(full_name, prefix) + path = full_name.dup + if path['<<'] + path.gsub!(/<<\s*(\w*)/) { "from-#$1" } + end + File.join(prefix, path.split("::")) + ".html" + end + + + def name + @context.full_name + end + + def parent_name + @context.parent.full_name + end + + def index_name + name + end + + def write_on(f) + value_hash + template = TemplatePage.new(RDoc::Page::BODY, + RDoc::Page::CLASS_PAGE, + RDoc::Page::METHOD_LIST) + template.write_html_on(f, @values) + end + + def value_hash + class_attribute_values + add_table_of_sections + + @values["charset"] = @options.charset + @values["style_url"] = style_url(path, @options.css) + + d = markup(@context.comment) + @values["description"] = d unless d.empty? + + ml = build_method_summary_list + @values["methods"] = ml unless ml.empty? + + il = build_include_list(@context) + @values["includes"] = il unless il.empty? + + @values["sections"] = @context.sections.map do |section| + + secdata = { + "sectitle" => section.title, + "secsequence" => section.sequence, + "seccomment" => markup(section.comment) + } + + al = build_alias_summary_list(section) + secdata["aliases"] = al unless al.empty? + + co = build_constants_summary_list(section) + secdata["constants"] = co unless co.empty? + + al = build_attribute_list(section) + secdata["attributes"] = al unless al.empty? + + cl = build_class_list(0, @context, section) + secdata["classlist"] = cl unless cl.empty? + + mdl = build_method_detail_list(section) + secdata["method_list"] = mdl unless mdl.empty? + + secdata + end + + @values + end + + def build_attribute_list(section) + atts = @context.attributes.sort + res = [] + atts.each do |att| + next unless att.section == section + if att.visibility == :public || att.visibility == :protected || @options.show_all + entry = { + "name" => CGI.escapeHTML(att.name), + "rw" => att.rw, + "a_desc" => markup(att.comment, true) + } + unless att.visibility == :public || att.visibility == :protected + entry["rw"] << "-" + end + res << entry + end + end + res + end + + def class_attribute_values + h_name = CGI.escapeHTML(name) + + @values["classmod"] = @is_module ? "Module" : "Class" + @values["title"] = "#{@values['classmod']}: #{h_name}" + + c = @context + c = c.parent while c and !c.diagram + if c && c.diagram + @values["diagram"] = diagram_reference(c.diagram) + end + + @values["full_name"] = h_name + + parent_class = @context.superclass + + if parent_class + @values["parent"] = CGI.escapeHTML(parent_class) + + if parent_name + lookup = parent_name + "::" + parent_class + else + lookup = parent_class + end + + parent_url = AllReferences[lookup] || AllReferences[parent_class] + + if parent_url and parent_url.document_self + @values["par_url"] = aref_to(parent_url.path) + end + end + + files = [] + @context.in_files.each do |f| + res = {} + full_path = CGI.escapeHTML(f.file_absolute_name) + + res["full_path"] = full_path + res["full_path_url"] = aref_to(f.viewer.path) if f.document_self + + if @options.webcvs + res["cvsurl"] = cvs_url( @options.webcvs, full_path ) + end + + files << res + end + + @values['infiles'] = files + end + + def <=>(other) + self.name <=> other.name + end + + end + + ##################################################################### + # + # Handles the mapping of a file's information to HTML. In reality, + # a file corresponds to a +TopLevel+ object, containing modules, + # classes, and top-level methods. In theory it _could_ contain + # attributes and aliases, but we ignore these for now. + + class HtmlFile < ContextUser + + attr_reader :path + attr_reader :name + + def initialize(context, options, file_dir) + super(context, options) + + @values = {} + + if options.all_one_file + @path = filename_to_label + else + @path = http_url(file_dir) + end + + @name = @context.file_relative_name + + collect_methods + AllReferences.add(name, self) + context.viewer = self + end + + def http_url(file_dir) + File.join(file_dir, @context.file_relative_name.tr('.', '_')) + + ".html" + end + + def filename_to_label + @context.file_relative_name.gsub(/%|\/|\?|\#/) {|s| '%' + ("%x" % s[0]) } + end + + def index_name + name + end + + def parent_name + nil + end + + def value_hash + file_attribute_values + add_table_of_sections + + @values["charset"] = @options.charset + @values["href"] = path + @values["style_url"] = style_url(path, @options.css) + + if @context.comment + d = markup(@context.comment) + @values["description"] = d if d.size > 0 + end + + ml = build_method_summary_list + @values["methods"] = ml unless ml.empty? + + il = build_include_list(@context) + @values["includes"] = il unless il.empty? + + rl = build_requires_list(@context) + @values["requires"] = rl unless rl.empty? + + if @options.promiscuous + file_context = nil + else + file_context = @context + end + + + @values["sections"] = @context.sections.map do |section| + + secdata = { + "sectitle" => section.title, + "secsequence" => section.sequence, + "seccomment" => markup(section.comment) + } + + cl = build_class_list(0, @context, section, file_context) + @values["classlist"] = cl unless cl.empty? + + mdl = build_method_detail_list(section) + secdata["method_list"] = mdl unless mdl.empty? + + al = build_alias_summary_list(section) + secdata["aliases"] = al unless al.empty? + + co = build_constants_summary_list(section) + @values["constants"] = co unless co.empty? + + secdata + end + + @values + end + + def write_on(f) + value_hash + template = TemplatePage.new(RDoc::Page::BODY, + RDoc::Page::FILE_PAGE, + RDoc::Page::METHOD_LIST) + template.write_html_on(f, @values) + end + + def file_attribute_values + full_path = @context.file_absolute_name + short_name = File.basename(full_path) + + @values["title"] = CGI.escapeHTML("File: #{short_name}") + + if @context.diagram + @values["diagram"] = diagram_reference(@context.diagram) + end + + @values["short_name"] = CGI.escapeHTML(short_name) + @values["full_path"] = CGI.escapeHTML(full_path) + @values["dtm_modified"] = @context.file_stat.mtime.to_s + + if @options.webcvs + @values["cvsurl"] = cvs_url( @options.webcvs, @values["full_path"] ) + end + end + + def <=>(other) + self.name <=> other.name + end + end + + ##################################################################### + + class HtmlMethod + include MarkUp + + attr_reader :context + attr_reader :src_url + attr_reader :img_url + attr_reader :source_code + + @@seq = "M000000" + + @@all_methods = [] + + def HtmlMethod::reset + @@all_methods = [] + end + + def initialize(context, html_class, options) + @context = context + @html_class = html_class + @options = options + @@seq = @@seq.succ + @seq = @@seq + @@all_methods << self + + context.viewer = self + + if (ts = @context.token_stream) + @source_code = markup_code(ts) + unless @options.inline_source + @src_url = create_source_code_file(@source_code) + @img_url = HTMLGenerator.gen_url(path, 'source.png') + end + end + + AllReferences.add(name, self) + end + + # return a reference to outselves to be used as an href= + # the form depends on whether we're all in one file + # or in multiple files + + def as_href(from_path) + if @options.all_one_file + "#" + path + else + HTMLGenerator.gen_url(from_path, path) + end + end + + def name + @context.name + end + + def section + @context.section + end + + def index_name + "#{@context.name} (#{@html_class.name})" + end + + def parent_name + if @context.parent.parent + @context.parent.parent.full_name + else + nil + end + end + + def aref + @seq + end + + def path + if @options.all_one_file + aref + else + @html_class.path + "#" + aref + end + end + + def description + markup(@context.comment) + end + + def visibility + @context.visibility + end + + def singleton + @context.singleton + end + + def call_seq + cs = @context.call_seq + if cs + cs.gsub(/\n/, "
\n") + else + nil + end + end + + def params + # params coming from a call-seq in 'C' will start with the + # method name + p = @context.params + if p !~ /^\w/ + p = @context.params.gsub(/\s*\#.*/, '') + p = p.tr("\n", " ").squeeze(" ") + p = "(" + p + ")" unless p[0] == ?( + + if (block = @context.block_params) + # If this method has explicit block parameters, remove any + # explicit &block + + p.sub!(/,?\s*&\w+/, '') + + block.gsub!(/\s*\#.*/, '') + block = block.tr("\n", " ").squeeze(" ") + if block[0] == ?( + block.sub!(/^\(/, '').sub!(/\)/, '') + end + p << " {|#{block.strip}| ...}" + end + end + CGI.escapeHTML(p) + end + + def create_source_code_file(code_body) + meth_path = @html_class.path.sub(/\.html$/, '.src') + File.makedirs(meth_path) + file_path = File.join(meth_path, @seq) + ".html" + + template = TemplatePage.new(RDoc::Page::SRC_PAGE) + File.open(file_path, "w") do |f| + values = { + 'title' => CGI.escapeHTML(index_name), + 'code' => code_body, + 'style_url' => style_url(file_path, @options.css), + 'charset' => @options.charset + } + template.write_html_on(f, values) + end + HTMLGenerator.gen_url(path, file_path) + end + + def HtmlMethod.all_methods + @@all_methods + end + + def <=>(other) + @context <=> other.context + end + + ## + # Given a sequence of source tokens, mark up the source code + # to make it look purty. + + + def markup_code(tokens) + src = "" + tokens.each do |t| + next unless t + # p t.class +# style = STYLE_MAP[t.class] + style = case t + when RubyToken::TkCONSTANT then "ruby-constant" + when RubyToken::TkKW then "ruby-keyword kw" + when RubyToken::TkIVAR then "ruby-ivar" + when RubyToken::TkOp then "ruby-operator" + when RubyToken::TkId then "ruby-identifier" + when RubyToken::TkNode then "ruby-node" + when RubyToken::TkCOMMENT then "ruby-comment cmt" + when RubyToken::TkREGEXP then "ruby-regexp re" + when RubyToken::TkSTRING then "ruby-value str" + when RubyToken::TkVal then "ruby-value" + else + nil + end + + text = CGI.escapeHTML(t.text) + + if style + src << "#{text}" + else + src << text + end + end + + add_line_numbers(src) if Options.instance.include_line_numbers + src + end + + # we rely on the fact that the first line of a source code + # listing has + # # File xxxxx, line dddd + + def add_line_numbers(src) + if src =~ /\A.*, line (\d+)/ + first = $1.to_i - 1 + last = first + src.count("\n") + size = last.to_s.length + real_fmt = "%#{size}d: " + fmt = " " * (size+2) + src.gsub!(/^/) do + res = sprintf(fmt, first) + first += 1 + fmt = real_fmt + res + end + end + end + + def document_self + @context.document_self + end + + def aliases + @context.aliases + end + + def find_symbol(symbol, method=nil) + res = @context.parent.find_symbol(symbol, method) + if res + res = res.viewer + end + res + end + end + + ##################################################################### + + class HTMLGenerator + + include MarkUp + + ## + # convert a target url to one that is relative to a given + # path + + def HTMLGenerator.gen_url(path, target) + from = File.dirname(path) + to, to_file = File.split(target) + + from = from.split("/") + to = to.split("/") + + while from.size > 0 and to.size > 0 and from[0] == to[0] + from.shift + to.shift + end + + from.fill("..") + from.concat(to) + from << to_file + File.join(*from) + end + + # Generators may need to return specific subclasses depending + # on the options they are passed. Because of this + # we create them using a factory + + def HTMLGenerator.for(options) + AllReferences::reset + HtmlMethod::reset + + if options.all_one_file + HTMLGeneratorInOne.new(options) + else + HTMLGenerator.new(options) + end + end + + class < RDoc::Page::FONTS } + template.write_html_on(f, values) + end + end + end + + ## + # See the comments at the top for a description of the + # directory structure + + def gen_sub_directories + File.makedirs(FILE_DIR, CLASS_DIR) + rescue + $stderr.puts $!.message + exit 1 + end + + ## + # Generate: + # + # * a list of HtmlFile objects for each TopLevel object. + # * a list of HtmlClass objects for each first level + # class or module in the TopLevel objects + # * a complete list of all hyperlinkable terms (file, + # class, module, and method names) + + def build_indices + + @toplevels.each do |toplevel| + @files << HtmlFile.new(toplevel, @options, FILE_DIR) + end + + RDoc::TopLevel.all_classes_and_modules.each do |cls| + build_class_list(cls, @files[0], CLASS_DIR) + end + end + + def build_class_list(from, html_file, class_dir) + @classes << HtmlClass.new(from, html_file, class_dir, @options) + from.each_classmodule do |mod| + build_class_list(mod, html_file, class_dir) + end + end + + ## + # Generate all the HTML + # + def generate_html + # the individual descriptions for files and classes + gen_into(@files) + gen_into(@classes) + # and the index files + gen_file_index + gen_class_index + gen_method_index + gen_main_index + + # this method is defined in the template file + write_extra_pages if defined? write_extra_pages + end + + def gen_into(list) + list.each do |item| + if item.document_self + op_file = item.path + File.makedirs(File.dirname(op_file)) + File.open(op_file, "w") { |file| item.write_on(file) } + end + end + + end + + def gen_file_index + gen_an_index(@files, 'Files', + RDoc::Page::FILE_INDEX, + "fr_file_index.html") + end + + def gen_class_index + gen_an_index(@classes, 'Classes', + RDoc::Page::CLASS_INDEX, + "fr_class_index.html") + end + + def gen_method_index + gen_an_index(HtmlMethod.all_methods, 'Methods', + RDoc::Page::METHOD_INDEX, + "fr_method_index.html") + end + + + def gen_an_index(collection, title, template, filename) + template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template) + res = [] + collection.sort.each do |f| + if f.document_self + res << { "href" => f.path, "name" => f.index_name } + end + end + + values = { + "entries" => res, + 'list_title' => CGI.escapeHTML(title), + 'index_url' => main_url, + 'charset' => @options.charset, + 'style_url' => style_url('', @options.css), + } + + File.open(filename, "w") do |f| + template.write_html_on(f, values) + end + end + + # The main index page is mostly a template frameset, but includes + # the initial page. If the --main option was given, + # we use this as our main page, otherwise we use the + # first file specified on the command line. + + def gen_main_index + template = TemplatePage.new(RDoc::Page::INDEX) + File.open("index.html", "w") do |f| + values = { + "initial_page" => main_url, + 'title' => CGI.escapeHTML(@options.title), + 'charset' => @options.charset + } + if @options.inline_source + values['inline_source'] = true + end + template.write_html_on(f, values) + end + end + + # return the url of the main page + def main_url + main_page = @options.main_page + ref = nil + if main_page + ref = AllReferences[main_page] + if ref + ref = ref.path + else + $stderr.puts "Could not find main page #{main_page}" + end + end + + unless ref + for file in @files + if file.document_self + ref = file.path + break + end + end + end + + unless ref + $stderr.puts "Couldn't find anything to document" + $stderr.puts "Perhaps you've used :stopdoc: in all classes" + exit(1) + end + + ref + end + + + end + + + ###################################################################### + + + class HTMLGeneratorInOne < HTMLGenerator + + def initialize(*args) + super + end + + ## + # Build the initial indices and output objects + # based on an array of TopLevel objects containing + # the extracted information. + + def generate(info) + @toplevels = info + @files = [] + @classes = [] + @hyperlinks = {} + + build_indices + generate_xml + end + + + ## + # Generate: + # + # * a list of HtmlFile objects for each TopLevel object. + # * a list of HtmlClass objects for each first level + # class or module in the TopLevel objects + # * a complete list of all hyperlinkable terms (file, + # class, module, and method names) + + def build_indices + + @toplevels.each do |toplevel| + @files << HtmlFile.new(toplevel, @options, FILE_DIR) + end + + RDoc::TopLevel.all_classes_and_modules.each do |cls| + build_class_list(cls, @files[0], CLASS_DIR) + end + end + + def build_class_list(from, html_file, class_dir) + @classes << HtmlClass.new(from, html_file, class_dir, @options) + from.each_classmodule do |mod| + build_class_list(mod, html_file, class_dir) + end + end + + ## + # Generate all the HTML. For the one-file case, we generate + # all the information in to one big hash + # + def generate_xml + values = { + 'charset' => @options.charset, + 'files' => gen_into(@files), + 'classes' => gen_into(@classes), + 'title' => CGI.escapeHTML(@options.title), + } + + # this method is defined in the template file + write_extra_pages if defined? write_extra_pages + + template = TemplatePage.new(RDoc::Page::ONE_PAGE) + + if @options.op_name + opfile = File.open(@options.op_name, "w") + else + opfile = $stdout + end + template.write_html_on(opfile, values) + end + + def gen_into(list) + res = [] + list.each do |item| + res << item.value_hash + end + res + end + + def gen_file_index + gen_an_index(@files, 'Files') + end + + def gen_class_index + gen_an_index(@classes, 'Classes') + end + + def gen_method_index + gen_an_index(HtmlMethod.all_methods, 'Methods') + end + + + def gen_an_index(collection, title) + res = [] + collection.sort.each do |f| + if f.document_self + res << { "href" => f.path, "name" => f.index_name } + end + end + + return { + "entries" => res, + 'list_title' => title, + 'index_url' => main_url, + } + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/ri_generator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/ri_generator.rb new file mode 100644 index 00000000..c7d0bbd8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/ri_generator.rb @@ -0,0 +1,268 @@ +# We're responsible for generating all the HTML files +# from the object tree defined in code_objects.rb. We +# generate: +# +# [files] an html file for each input file given. These +# input files appear as objects of class +# TopLevel +# +# [classes] an html file for each class or module encountered. +# These classes are not grouped by file: if a file +# contains four classes, we'll generate an html +# file for the file itself, and four html files +# for the individual classes. +# +# [indices] we generate three indices for files, classes, +# and methods. These are displayed in a browser +# like window with three index panes across the +# top and the selected description below +# +# Method descriptions appear in whatever entity (file, class, +# or module) that contains them. +# +# We generate files in a structure below a specified subdirectory, +# normally +doc+. +# +# opdir +# | +# |___ files +# | |__ per file summaries +# | +# |___ classes +# |__ per class/module descriptions +# +# HTML is generated using the Template class. +# + +require 'ftools' + +require 'rdoc/options' +require 'rdoc/template' +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_flow' +require 'cgi' + +require 'rdoc/ri/ri_cache' +require 'rdoc/ri/ri_reader' +require 'rdoc/ri/ri_writer' +require 'rdoc/ri/ri_descriptions' + +module Generators + + + class RIGenerator + + # Generators may need to return specific subclasses depending + # on the options they are passed. Because of this + # we create them using a factory + + def RIGenerator.for(options) + new(options) + end + + class <\s*)[^\#]/ + content = comment + else + content = comment.gsub(/^\s*(#+)/) { $1.tr('#',' ') } + end + @markup.convert(content, @to_flow) + end + + + # By default we replace existing classes with the + # same name. If the --merge option was given, we instead + # merge this definition into an existing class. We add + # our methods, aliases, etc to that class, but do not + # change the class's description. + + def update_or_replace(cls_desc) + old_cls = nil + + if @options.merge + rdr = RI::RiReader.new(RI::RiCache.new(@options.op_dir)) + + namespace = rdr.top_level_namespace + namespace = rdr.lookup_namespace_in(cls_desc.name, namespace) + if namespace.empty? + $stderr.puts "You asked me to merge this source into existing " + $stderr.puts "documentation. This file references a class or " + $stderr.puts "module called #{cls_desc.name} which I don't" + $stderr.puts "have existing documentation for." + $stderr.puts + $stderr.puts "Perhaps you need to generate its documentation first" + exit 1 + else + old_cls = namespace[0] + end + end + + if old_cls.nil? + # no merge: simply overwrite + @ri_writer.remove_class(cls_desc) + @ri_writer.add_class(cls_desc) + else + # existing class: merge in + old_desc = rdr.get_class(old_cls) + + old_desc.merge_in(cls_desc) + @ri_writer.add_class(old_desc) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/chm/chm.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/chm/chm.rb new file mode 100644 index 00000000..4a89c265 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/chm/chm.rb @@ -0,0 +1,87 @@ +module RDoc +module Page + +require "rdoc/generators/template/html/html" + +# This is a nasty little hack, but hhc doesn't support the /, '') +SRC_PAGE.sub!(/<\?xml.*\?>/, '') + +HPP_FILE = %{ +[OPTIONS] +Auto Index = Yes +Compatibility=1.1 or later +Compiled file=%opname%.chm +Contents file=contents.hhc +Full-text search=Yes +Index file=index.hhk +Language=0x409 English(United States) +Title=%title% + +[FILES] +START:all_html_files +%html_file_name% +END:all_html_files +} + +CONTENTS = %{ + + + + + + + + + + + +

    +START:contents +
  • + + + +IF:methods +
      +START:methods +
    • + + + +END:methods +
    +ENDIF:methods +
  • +END:contents +
+ +} + + +CHM_INDEX = %{ + + + + + + + + + + + +
    +START:index +
  • + + + +END:index +
+ +} +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/hefss.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/hefss.rb new file mode 100644 index 00000000..e68ca858 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/hefss.rb @@ -0,0 +1,418 @@ +module RDoc +module Page + + +FONTS = "Verdana, Arial, Helvetica, sans-serif" + +STYLE = %{ +body,p { font-family: Verdana, Arial, Helvetica, sans-serif; + color: #000040; background: #BBBBBB; +} + +td { font-family: Verdana, Arial, Helvetica, sans-serif; + color: #000040; +} + +.attr-rw { font-size: small; color: #444488 } + +.title-row {color: #eeeeff; + background: #BBBBDD; +} + +.big-title-font { color: white; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: large; + height: 50px} + +.small-title-font { color: purple; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: small; } + +.aqua { color: purple } + +.method-name, attr-name { + font-family: monospace; font-weight: bold; +} + +.tablesubtitle { + width: 100%; + margin-top: 1ex; + margin-bottom: .5ex; + padding: 5px 0px 5px 20px; + font-size: large; + color: purple; + background: #BBBBCC; +} + +.tablesubsubtitle { + width: 100%; + margin-top: 1ex; + margin-bottom: .5ex; + padding: 5px 0px 5px 20px; + font-size: medium; + color: white; + background: #BBBBCC; +} + +.name-list { + font-family: monospace; + margin-left: 40px; + margin-bottom: 2ex; + line-height: 140%; +} + +.description { + margin-left: 40px; + margin-bottom: 2ex; + line-height: 140%; +} + +.methodtitle { + font-size: medium; + text_decoration: none; + padding: 3px 3px 3px 20px; + color: #0000AA; +} + +.column-title { + font-size: medium; + font-weight: bold; + text_decoration: none; + padding: 3px 3px 3px 20px; + color: #3333CC; + } + +.variable-name { + font-family: monospace; + font-size: medium; + text_decoration: none; + padding: 3px 3px 3px 20px; + color: #0000AA; +} + +.row-name { + font-size: medium; + font-weight: medium; + font-family: monospace; + text_decoration: none; + padding: 3px 3px 3px 20px; +} + +.paramsig { + font-size: small; +} + +.srcbut { float: right } + +} + + +############################################################################ + + +BODY = %{ + + %title% + + + + + + +!INCLUDE! + +IF:diagram +
+%diagram% +
+ENDIF:diagram + +IF:description +
%description%
+ENDIF:description + +IF:requires + + +
Required files

+
+START:requires +HREF:aref:name: +END:requires +ENDIF:requires +
+ +IF:methods + + +
Subroutines and Functions

+
+START:methods +HREF:aref:name:, +END:methods +
+ENDIF:methods + +IF:attributes + + +
Arguments

+ +START:attributes + +IF:rw + +ENDIF:rw +IFNOT:rw + +ENDIF:rw + + + +END:attributes +
 [%rw%] %name%%a_desc%
+ENDIF:attributes + +IF:classlist + + +
Modules

+%classlist%
+ENDIF:classlist + + !INCLUDE! + + + +} + +############################################################################### + +FILE_PAGE = <<_FILE_PAGE_ + + + + +
+ +
File
%short_name%
+ + + + + + + + +
Path:%full_path% +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
Modified:%dtm_modified%
+

+_FILE_PAGE_ + +################################################################### + +CLASS_PAGE = %{ + + + + + +
+ %classmod%
%full_name% +
+ + + + + +IF:parent + + + + +ENDIF:parent +
In: +START:infiles +HREF:full_path_url:full_path: +IF:cvsurl + (CVS) +ENDIF:cvsurl +END:infiles +
Parent: +IF:par_url + +ENDIF:par_url +%parent% +IF:par_url + +ENDIF:par_url +
+

+} + +################################################################### + +METHOD_LIST = %{ +IF:includes +
Uses

+
+START:includes + HREF:aref:name: +END:includes +
+ENDIF:includes + +IF:method_list +START:method_list +IF:methods + + +
%type% %category% methods
+START:methods + + +
+ +%name%%params% +IF:codeurl +src +ENDIF:codeurl +
+IF:m_desc +
+%m_desc% +
+ENDIF:m_desc +END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +} + +=begin +=end + +########################## Source code ########################## + +SRC_PAGE = %{ + +%title% + + + + +
%code%
+ + +} + +########################## Index ################################ + +FR_INDEX_BODY = %{ +!INCLUDE! +} + +FILE_INDEX = %{ + + + + + + + + +START:entries +%name%
+END:entries + +} + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = %{ + + + %title% + + + + + + + + + + + + + + + <body bgcolor="#BBBBBB"> + Click <a href="html/index.html">here</a> for a non-frames + version of this page. + </body> + + + + +} + +# and a blank page to use as a target +BLANK = %{ + +} + +def write_extra_pages + template = TemplatePage.new(BLANK) + File.open("blank.html", "w") { |f| template.write_html_on(f, {}) } +end + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/html.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/html.rb new file mode 100644 index 00000000..7f9e5994 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/html.rb @@ -0,0 +1,711 @@ +# +# = CSS2 RDoc HTML template +# +# This is a template for RDoc that uses XHTML 1.0 Transitional and dictates a +# bit more of the appearance of the output to cascading stylesheets than the +# default. It was designed for clean inline code display, and uses DHTMl to +# toggle the visbility of each method's source with each click on the '[source]' +# link. +# +# == Authors +# +# * Michael Granger +# +# Copyright (c) 2002, 2003 The FaerieMUD Consortium. Some rights reserved. +# +# This work is licensed under the Creative Commons Attribution License. To view +# a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or +# send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California +# 94305, USA. +# + +module RDoc + module Page + + FONTS = "Verdana,Arial,Helvetica,sans-serif" + +STYLE = %{ +body { + font-family: Verdana,Arial,Helvetica,sans-serif; + font-size: 90%; + margin: 0; + margin-left: 40px; + padding: 0; + background: white; +} + +h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; } +h1 { font-size: 150%; } +h2,h3,h4 { margin-top: 1em; } + +a { background: #eef; color: #039; text-decoration: none; } +a:hover { background: #039; color: #eef; } + +/* Override the base stylesheet's Anchor inside a table cell */ +td > a { + background: transparent; + color: #039; + text-decoration: none; +} + +/* and inside a section title */ +.section-title > a { + background: transparent; + color: #eee; + text-decoration: none; +} + +/* === Structural elements =================================== */ + +div#index { + margin: 0; + margin-left: -40px; + padding: 0; + font-size: 90%; +} + + +div#index a { + margin-left: 0.7em; +} + +div#index .section-bar { + margin-left: 0px; + padding-left: 0.7em; + background: #ccc; + font-size: small; +} + + +div#classHeader, div#fileHeader { + width: auto; + color: white; + padding: 0.5em 1.5em 0.5em 1.5em; + margin: 0; + margin-left: -40px; + border-bottom: 3px solid #006; +} + +div#classHeader a, div#fileHeader a { + background: inherit; + color: white; +} + +div#classHeader td, div#fileHeader td { + background: inherit; + color: white; +} + + +div#fileHeader { + background: #057; +} + +div#classHeader { + background: #048; +} + + +.class-name-in-header { + font-size: 180%; + font-weight: bold; +} + + +div#bodyContent { + padding: 0 1.5em 0 1.5em; +} + +div#description { + padding: 0.5em 1.5em; + background: #efefef; + border: 1px dotted #999; +} + +div#description h1,h2,h3,h4,h5,h6 { + color: #125;; + background: transparent; +} + +div#validator-badges { + text-align: center; +} +div#validator-badges img { border: 0; } + +div#copyright { + color: #333; + background: #efefef; + font: 0.75em sans-serif; + margin-top: 5em; + margin-bottom: 0; + padding: 0.5em 2em; +} + + +/* === Classes =================================== */ + +table.header-table { + color: white; + font-size: small; +} + +.type-note { + font-size: small; + color: #DEDEDE; +} + +.xxsection-bar { + background: #eee; + color: #333; + padding: 3px; +} + +.section-bar { + color: #333; + border-bottom: 1px solid #999; + margin-left: -20px; +} + + +.section-title { + background: #79a; + color: #eee; + padding: 3px; + margin-top: 2em; + margin-left: -30px; + border: 1px solid #999; +} + +.top-aligned-row { vertical-align: top } +.bottom-aligned-row { vertical-align: bottom } + +/* --- Context section classes ----------------------- */ + +.context-row { } +.context-item-name { font-family: monospace; font-weight: bold; color: black; } +.context-item-value { font-size: small; color: #448; } +.context-item-desc { color: #333; padding-left: 2em; } + +/* --- Method classes -------------------------- */ +.method-detail { + background: #efefef; + padding: 0; + margin-top: 0.5em; + margin-bottom: 1em; + border: 1px dotted #ccc; +} +.method-heading { + color: black; + background: #ccc; + border-bottom: 1px solid #666; + padding: 0.2em 0.5em 0 0.5em; +} +.method-signature { color: black; background: inherit; } +.method-name { font-weight: bold; } +.method-args { font-style: italic; } +.method-description { padding: 0 0.5em 0 0.5em; } + +/* --- Source code sections -------------------- */ + +a.source-toggle { font-size: 90%; } +div.method-source-code { + background: #262626; + color: #ffdead; + margin: 1em; + padding: 0.5em; + border: 1px dashed #999; + overflow: hidden; +} + +div.method-source-code pre { color: #ffdead; overflow: hidden; } + +/* --- Ruby keyword styles --------------------- */ + +.standalone-code { background: #221111; color: #ffdead; overflow: hidden; } + +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } +.ruby-identifier { color: #ffdead; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } +} + + +##################################################################### +### H E A D E R T E M P L A T E +##################################################################### + +XHTML_PREAMBLE = %{ + +} + +HEADER = XHTML_PREAMBLE + %{ + + + %title% + + + + + + + +} + + +##################################################################### +### C O N T E X T C O N T E N T T E M P L A T E +##################################################################### + +CONTEXT_CONTENT = %{ +} + + +##################################################################### +### F O O T E R T E M P L A T E +##################################################################### +FOOTER = %{ + + + + +} + + +##################################################################### +### F I L E P A G E H E A D E R T E M P L A T E +##################################################################### + +FILE_PAGE = %{ +
+

%short_name%

+ + + + + + + + + +
Path:%full_path% +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
Last Update:%dtm_modified%
+
+} + + +##################################################################### +### C L A S S P A G E H E A D E R T E M P L A T E +##################################################################### + +CLASS_PAGE = %{ +
+ + + + + + + + + + +IF:parent + + + + +ENDIF:parent +
%classmod%%full_name%
In: +START:infiles +IF:full_path_url + +ENDIF:full_path_url + %full_path% +IF:full_path_url + +ENDIF:full_path_url +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
+END:infiles +
Parent: +IF:par_url + +ENDIF:par_url + %parent% +IF:par_url + +ENDIF:par_url +
+
+} + + +##################################################################### +### M E T H O D L I S T T E M P L A T E +##################################################################### + +METHOD_LIST = %{ + +
+IF:diagram +
+ %diagram% +
+ENDIF:diagram + +IF:description +
+ %description% +
+ENDIF:description + +IF:requires +
+

Required files

+ +
+START:requires + HREF:aref:name:   +END:requires +
+
+ENDIF:requires + +IF:toc +
+

Contents

+ +ENDIF:toc +
+ +IF:methods +
+

Methods

+ +
+START:methods + HREF:aref:name:   +END:methods +
+
+ENDIF:methods + +
+ + + +IF:includes +
+

Included Modules

+ +
+START:includes + HREF:aref:name: +END:includes +
+
+ENDIF:includes + +START:sections +
+IF:sectitle +

%sectitle%

+IF:seccomment +
+ %seccomment% +
+ENDIF:seccomment +ENDIF:sectitle + +IF:classlist +
+

Classes and Modules

+ + %classlist% +
+ENDIF:classlist + +IF:constants +
+

Constants

+ +
+ +START:constants + + + + +IF:desc + + +ENDIF:desc + +END:constants +
%name%=%value% %desc%
+
+
+ENDIF:constants + +IF:aliases +
+

External Aliases

+ +
+ +START:aliases + + + + + +IF:desc + + + + +ENDIF:desc +END:aliases +
%old_name%->%new_name%
 %desc%
+
+
+ENDIF:aliases + + +IF:attributes +
+

Attributes

+ +
+ +START:attributes + + +IF:rw + +ENDIF:rw +IFNOT:rw + +ENDIF:rw + + +END:attributes +
%name% [%rw%]   %a_desc%
+
+
+ENDIF:attributes + + + + +IF:method_list +
+START:method_list +IF:methods +

%type% %category% methods

+ +START:methods +
+ + + + +
+IF:m_desc + %m_desc% +ENDIF:m_desc +IF:sourcecode +

[Source]

+
+
+%sourcecode%
+
+
+ENDIF:sourcecode +
+
+ +END:methods +ENDIF:methods +END:method_list + +
+ENDIF:method_list +END:sections +} + + +##################################################################### +### B O D Y T E M P L A T E +##################################################################### + +BODY = HEADER + %{ + +!INCLUDE! + +
+ +} + METHOD_LIST + %{ + +
+ +} + FOOTER + + + +##################################################################### +### S O U R C E C O D E T E M P L A T E +##################################################################### + +SRC_PAGE = XHTML_PREAMBLE + %{ + + + %title% + + + + +
%code%
+ + +} + + +##################################################################### +### I N D E X F I L E T E M P L A T E S +##################################################################### + +FR_INDEX_BODY = %{ +!INCLUDE! +} + +FILE_INDEX = XHTML_PREAMBLE + %{ + + + + %list_title% + + + + + +
+

%list_title%

+
+START:entries + %name%
+END:entries +
+
+ + +} + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = %{ + + + + + + %title% + + + + + + + + + + + +} + + + + end # module Page +end # class RDoc + +require 'rdoc/generators/template/html/one_page_html' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/kilmer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/kilmer.rb new file mode 100644 index 00000000..55071fc0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/kilmer.rb @@ -0,0 +1,435 @@ +module RDoc +module Page + + +FONTS = "Verdana, Arial, Helvetica, sans-serif" + +STYLE = %{ +body,td,p { font-family: %fonts%; + color: #000040; +} + +.attr-rw { font-size: xx-small; color: #444488 } + +.title-row { background-color: #CCCCFF; + color: #000010; +} + +.big-title-font { + color: black; + font-weight: bold; + font-family: %fonts%; + font-size: large; + height: 60px; + padding: 10px 3px 10px 3px; +} + +.small-title-font { color: black; + font-family: %fonts%; + font-size:10; } + +.aqua { color: black } + +.method-name, .attr-name { + font-family: font-family: %fonts%; + font-weight: bold; + font-size: small; + margin-left: 20px; + color: #000033; +} + +.tablesubtitle, .tablesubsubtitle { + width: 100%; + margin-top: 1ex; + margin-bottom: .5ex; + padding: 5px 0px 5px 3px; + font-size: large; + color: black; + background-color: #CCCCFF; + border: thin; +} + +.name-list { + margin-left: 5px; + margin-bottom: 2ex; + line-height: 105%; +} + +.description { + margin-left: 5px; + margin-bottom: 2ex; + line-height: 105%; + font-size: small; +} + +.methodtitle { + font-size: small; + font-weight: bold; + text-decoration: none; + color: #000033; + background-color: white; +} + +.srclink { + font-size: small; + font-weight: bold; + text-decoration: none; + color: #0000DD; + background-color: white; +} + +.paramsig { + font-size: small; +} + +.srcbut { float: right } + +} + + +############################################################################ + + +BODY = %{ + + %title% + + + + + + +!INCLUDE! + +IF:diagram +
+%diagram% +
+ENDIF:diagram + +IF:description +
%description%
+ENDIF:description + +IF:requires + + +
Required files

+
+START:requires +HREF:aref:name: +END:requires +ENDIF:requires +
+ +IF:methods + + +
Methods

+
+START:methods +HREF:aref:name:, +END:methods +
+ENDIF:methods + + +START:sections +
+IF:sectitle +

%sectitle%

+IF:seccomment +
+ %seccomment% +
+ENDIF:seccomment +ENDIF:sectitle + +IF:attributes + + +
Attributes

+ +START:attributes + +IF:rw + +ENDIF:rw +IFNOT:rw + +ENDIF:rw + + + +END:attributes +
 [%rw%] %name%%a_desc%
+ENDIF:attributes + +IF:classlist + + +
Classes and Modules

+%classlist%
+ENDIF:classlist + + !INCLUDE! + +END:sections + + + +} + +############################################################################### + +FILE_PAGE = <<_FILE_PAGE_ + + + + +
+ +
File
%short_name%
+ + + + + + + + +
Path:%full_path% +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
Modified:%dtm_modified%
+

+_FILE_PAGE_ + +################################################################### + +CLASS_PAGE = %{ + + + + + +
+ %classmod%
%full_name% +
+ + + + + +IF:parent + + + + +ENDIF:parent +
In: +START:infiles +HREF:full_path_url:full_path: +IF:cvsurl + (CVS) +ENDIF:cvsurl +END:infiles +
Parent: +IF:par_url + +ENDIF:par_url +%parent% +IF:par_url + +ENDIF:par_url +
+

+} + +################################################################### + +METHOD_LIST = %{ +IF:includes +
Included modules

+
+START:includes + HREF:aref:name: +END:includes +
+ENDIF:includes + +IF:method_list +START:method_list +IF:methods + + +
%type% %category% methods
+START:methods + + +
+ +IF:callseq +%callseq% +ENDIF:callseq +IFNOT:callseq + %name%%params% +ENDIF:callseq +IF:codeurl +src +ENDIF:codeurl +
+IF:m_desc +
+%m_desc% +
+ENDIF:m_desc +IF:aka +
+This method is also aliased as +START:aka +%name% +END:aka +
+ENDIF:aka +IF:sourcecode +
+%sourcecode%
+
+ENDIF:sourcecode +END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +} + +=begin +=end + +########################## Source code ########################## + +SRC_PAGE = %{ + +%title% + + + + +
%code%
+ + +} + +########################## Index ################################ + +FR_INDEX_BODY = %{ +!INCLUDE! +} + +FILE_INDEX = %{ + + + + + + + + +START:entries +%name%
+END:entries + +} + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = %{ + + + %title% + + + + + + + + + +IF:inline_source + +ENDIF:inline_source +IFNOT:inline_source + + + + +ENDIF:inline_source + + <body bgcolor="white"> + Click <a href="html/index.html">here</a> for a non-frames + version of this page. + </body> + + + + +} + +# and a blank page to use as a target +BLANK = %{ + +} + +def write_extra_pages + template = TemplatePage.new(BLANK) + File.open("blank.html", "w") { |f| template.write_html_on(f, {}) } +end + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/old_html.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/old_html.rb new file mode 100644 index 00000000..ca66302a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/old_html.rb @@ -0,0 +1,728 @@ +module RDoc + +# This is how you define the HTML that RDoc generates. Simply create +# a file in rdoc/generators/html_templates that creates the +# module RDoc::Page and populate it as described below. Then invoke +# rdoc using the --template option, and +# your template will be used. +# +# The constants defining pages use a simple templating system: +# +# * The templating system is passed a hash. Keys in the hash correspond +# to tags on this page. The tag %abc% is looked up in the hash, +# and is replaced by the corresponding hash value. +# +# * Some tags are optional. You can detect this using IF/ENDIF +# +# IF: title +# The value of title is %title% +# ENDIF: title +# +# * Some entries in the hash have values that are arrays, where each +# entry in the array is itself a hash. These are used to generate +# lists using the START: construct. For example, given a hash +# containing +# +# { 'people' => [ { 'name' => 'Fred', 'age' => '12' }, +# { 'name' => 'Mary', 'age' => '21' } ] +# +# You could generate a simple table using +# +# +# START:people +# +# END:people +#
%name%%age%
+# +# These lists can be nested to an arbitrary depth +# +# * the construct HREF:url:name: generates %name% +# if +url+ is defined in the hash, or %name% otherwise. +# +# +# Your file must contain the following constants +# +# [*FONTS*] a list of fonts to be used +# [*STYLE*] a CSS section (without the + + + + +START:entries +%name%
+END:entries + +} + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = %{ + + + + +%title% + + + + + + + + + + <body bgcolor="white"> + Sorry, RDoc currently only generates HTML using frames. + </body> + + + + +} + +###################################################################### +# +# The following is used for the -1 option +# + +CONTENTS_XML = %{ +IF:description +%description% +ENDIF:description + +IF:requires +

Requires:

+
    +START:requires +IF:aref +
  • %name%
  • +ENDIF:aref +IFNOT:aref +
  • %name%
  • +ENDIF:aref +END:requires +
+ENDIF:requires + +IF:attributes +

Attributes

+ +START:attributes + +END:attributes +
%name%%rw%%a_desc%
+ENDIF:attributes + +IF:includes +

Includes

+
    +START:includes +IF:aref +
  • %name%
  • +ENDIF:aref +IFNOT:aref +
  • %name%
  • +ENDIF:aref +END:includes +
+ENDIF:includes + +IF:method_list +

Methods

+START:method_list +IF:methods +START:methods +

%type% %category% method: %name%%params%

+ +IF:m_desc +%m_desc% +ENDIF:m_desc + +IF:sourcecode +
+%sourcecode%
+
+ENDIF:sourcecode +END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +} + + +end +end + +require 'rdoc/generators/template/html/one_page_html' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/one_page_html.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/one_page_html.rb new file mode 100644 index 00000000..19441f47 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/html/one_page_html.rb @@ -0,0 +1,122 @@ +module RDoc +module Page +###################################################################### +# +# The following is used for the -1 option +# + +CONTENTS_XML = %{ +IF:description +%description% +ENDIF:description + +IF:requires +

Requires:

+
    +START:requires +IF:aref +
  • %name%
  • +ENDIF:aref +IFNOT:aref +
  • %name%
  • +ENDIF:aref +END:requires +
+ENDIF:requires + +IF:attributes +

Attributes

+ +START:attributes + +END:attributes +
%name%%rw%%a_desc%
+ENDIF:attributes + +IF:includes +

Includes

+
    +START:includes +IF:aref +
  • %name%
  • +ENDIF:aref +IFNOT:aref +
  • %name%
  • +ENDIF:aref +END:includes +
+ENDIF:includes + +IF:method_list +

Methods

+START:method_list +IF:methods +START:methods +

%type% %category% method: +IF:callseq +%callseq% +ENDIF:callseq +IFNOT:callseq +%name%%params%

+ENDIF:callseq + +IF:m_desc +%m_desc% +ENDIF:m_desc + +IF:sourcecode +
+%sourcecode%
+
+ENDIF:sourcecode +END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +} + +######################################################################## + +ONE_PAGE = %{ + + + + %title% + + + +START:files +

File: %short_name%

+ + + +
Path:%full_path%
Modified:%dtm_modified%
+} + CONTENTS_XML + %{ +END:files + +IF:classes +

Classes

+START:classes +IF:parent +

%classmod% %full_name% < HREF:par_url:parent:

+ENDIF:parent +IFNOT:parent +

%classmod% %full_name%

+ENDIF:parent + +IF:infiles +(in files +START:infiles +HREF:full_path_url:full_path: +END:infiles +) +ENDIF:infiles +} + CONTENTS_XML + %{ +END:classes +ENDIF:classes + + +} + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/xml/rdf.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/xml/rdf.rb new file mode 100644 index 00000000..1545d81a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/xml/rdf.rb @@ -0,0 +1,112 @@ +module RDoc +module Page + + + +CONTENTS_RDF = %{ +IF:description + +%description% + +ENDIF:description + +IF:requires +START:requires + +END:requires +ENDIF:requires + +IF:attributes +START:attributes + + +IF:rw + %rw% +ENDIF:rw + %a_desc% + + +END:attributes +ENDIF:attributes + +IF:includes + +START:includes + +END:includes + +ENDIF:includes + +IF:method_list +START:method_list +IF:methods +START:methods + + + %params% +IF:m_desc + +%m_desc% + +ENDIF:m_desc +IF:sourcecode + +%sourcecode% + +ENDIF:sourcecode + + +END:methods +ENDIF:methods +END:method_list +ENDIF:method_list + +} + +######################################################################## + +ONE_PAGE = %{ + + + +START:files + + %full_path% + %dtm_modified% +} + CONTENTS_RDF + %{ + +END:files +START:classes + <%classmod% rd:name="%full_name%" rd:id="%full_name%"> + +IF:infiles + +START:infiles + + + +END:infiles + +ENDIF:infiles +IF:parent + HREF:par_url:parent: +ENDIF:parent + +} + CONTENTS_RDF + %{ + +END:classes + + +} + + +end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/xml/xml.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/xml/xml.rb new file mode 100644 index 00000000..4a0c8c9a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/template/xml/xml.rb @@ -0,0 +1,112 @@ +module RDoc +module Page + + + +CONTENTS_XML = %{ +IF:description + +%description% + +ENDIF:description + +IF:requires + +START:requires + +END:requires + +ENDIF:requires +IF:attributes + +START:attributes + +IF:rw + %rw% +ENDIF:rw + %a_desc% + +END:attributes + +ENDIF:attributes +IF:includes + +START:includes + +END:includes + +ENDIF:includes +IF:method_list + +START:method_list +IF:methods +START:methods + + %params% +IF:m_desc + +%m_desc% + +ENDIF:m_desc +IF:sourcecode + +%sourcecode% + +ENDIF:sourcecode + +END:methods +ENDIF:methods +END:method_list + +ENDIF:method_list + +} + +######################################################################## + +ONE_PAGE = %{ + + +START:files + + + %full_path% + %dtm_modified% + +} + CONTENTS_XML + %{ + +END:files + + +START:classes + <%classmod% name="%full_name%" id="%full_name%"> + +IF:infiles + +START:infiles + HREF:full_path_url:full_path: +END:infiles + +ENDIF:infiles +IF:parent + HREF:par_url:parent: +ENDIF:parent + +} + CONTENTS_XML + %{ + +END:classes + + +} + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/xml_generator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/xml_generator.rb new file mode 100644 index 00000000..8c1a76d6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/generators/xml_generator.rb @@ -0,0 +1,130 @@ + +require 'ftools' + +require 'rdoc/options' +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_html' +require 'rdoc/generators/html_generator' + +module Generators + + # Generate XML output as one big file + + class XMLGenerator < HTMLGenerator + + # Standard generator factory + def XMLGenerator.for(options) + XMLGenerator.new(options) + end + + + def initialize(*args) + super + end + + ## + # Build the initial indices and output objects + # based on an array of TopLevel objects containing + # the extracted information. + + def generate(info) + @info = info + @files = [] + @classes = [] + @hyperlinks = {} + + build_indices + generate_xml + end + + + ## + # Generate: + # + # * a list of HtmlFile objects for each TopLevel object. + # * a list of HtmlClass objects for each first level + # class or module in the TopLevel objects + # * a complete list of all hyperlinkable terms (file, + # class, module, and method names) + + def build_indices + + @info.each do |toplevel| + @files << HtmlFile.new(toplevel, @options, FILE_DIR) + end + + RDoc::TopLevel.all_classes_and_modules.each do |cls| + build_class_list(cls, @files[0], CLASS_DIR) + end + end + + def build_class_list(from, html_file, class_dir) + @classes << HtmlClass.new(from, html_file, class_dir, @options) + from.each_classmodule do |mod| + build_class_list(mod, html_file, class_dir) + end + end + + ## + # Generate all the HTML. For the one-file case, we generate + # all the information in to one big hash + # + def generate_xml + values = { + 'charset' => @options.charset, + 'files' => gen_into(@files), + 'classes' => gen_into(@classes) + } + + # this method is defined in the template file + write_extra_pages if defined? write_extra_pages + + template = TemplatePage.new(RDoc::Page::ONE_PAGE) + + if @options.op_name + opfile = File.open(@options.op_name, "w") + else + opfile = $stdout + end + template.write_html_on(opfile, values) + end + + def gen_into(list) + res = [] + list.each do |item| + res << item.value_hash + end + res + end + + def gen_file_index + gen_an_index(@files, 'Files') + end + + def gen_class_index + gen_an_index(@classes, 'Classes') + end + + def gen_method_index + gen_an_index(HtmlMethod.all_methods, 'Methods') + end + + + def gen_an_index(collection, title) + res = [] + collection.sort.each do |f| + if f.document_self + res << { "href" => f.path, "name" => f.index_name } + end + end + + return { + "entries" => res, + 'list_title' => title, + 'index_url' => main_url, + } + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/sample/rdoc2latex.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/sample/rdoc2latex.rb new file mode 100644 index 00000000..26563b75 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/sample/rdoc2latex.rb @@ -0,0 +1,16 @@ +#!/usr/local/bin/ruby +# Illustration of a script to convert an RDoc-style file to a LaTeX +# document + +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_latex' + +p = SM::SimpleMarkup.new +h = SM::ToLaTeX.new + +#puts "\\documentclass{report}" +#puts "\\usepackage{tabularx}" +#puts "\\usepackage{parskip}" +#puts "\\begin{document}" +puts p.convert(ARGF.read, h) +#puts "\\end{document}" diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/sample/sample.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/sample/sample.rb new file mode 100644 index 00000000..a375b545 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/sample/sample.rb @@ -0,0 +1,42 @@ +# This program illustrates the basic use of the SimpleMarkup +# class. It extracts the first comment block from the +# simple_markup.rb file and converts it into HTML on +# standard output. Run it using +# +# % ruby sample.rb +# +# You should be in the sample/ directory when you do this, +# as it hardwires the path to the files it needs to require. +# This isn't necessary in the code you write once you've +# installed the package. +# +# For a better way of formatting code comment blocks (and more) +# see the rdoc package. +# + +$:.unshift "../../.." + +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_html' + +# Extract the comment block from the source file + +input_string = "" + +File.foreach("../simple_markup.rb") do |line| + break unless line.gsub!(/^\# ?/, '') + input_string << line +end + +# Create a markup object +markup = SM::SimpleMarkup.new + +# Attach it to an HTML formatter +h = SM::ToHtml.new + +# And convert out comment block to html. Wrap it a body +# tag pair to let browsers view it + +puts "" +puts markup.convert(input_string, h) +puts "" diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup.rb new file mode 100644 index 00000000..8193ca02 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup.rb @@ -0,0 +1,476 @@ +# = Introduction +# +# SimpleMarkup parses plain text documents and attempts to decompose +# them into their constituent parts. Some of these parts are high-level: +# paragraphs, chunks of verbatim text, list entries and the like. Other +# parts happen at the character level: a piece of bold text, a word in +# code font. This markup is similar in spirit to that used on WikiWiki +# webs, where folks create web pages using a simple set of formatting +# rules. +# +# SimpleMarkup itself does no output formatting: this is left to a +# different set of classes. +# +# SimpleMarkup is extendable at runtime: you can add new markup +# elements to be recognised in the documents that SimpleMarkup parses. +# +# SimpleMarkup is intended to be the basis for a family of tools which +# share the common requirement that simple, plain-text should be +# rendered in a variety of different output formats and media. It is +# envisaged that SimpleMarkup could be the basis for formating RDoc +# style comment blocks, Wiki entries, and online FAQs. +# +# = Basic Formatting +# +# * SimpleMarkup looks for a document's natural left margin. This is +# used as the initial margin for the document. +# +# * Consecutive lines starting at this margin are considered to be a +# paragraph. +# +# * If a paragraph starts with a "*", "-", or with ".", then it is +# taken to be the start of a list. The margin in increased to be the +# first non-space following the list start flag. Subsequent lines +# should be indented to this new margin until the list ends. For +# example: +# +# * this is a list with three paragraphs in +# the first item. This is the first paragraph. +# +# And this is the second paragraph. +# +# 1. This is an indented, numbered list. +# 2. This is the second item in that list +# +# This is the third conventional paragraph in the +# first list item. +# +# * This is the second item in the original list +# +# * You can also construct labeled lists, sometimes called description +# or definition lists. Do this by putting the label in square brackets +# and indenting the list body: +# +# [cat] a small furry mammal +# that seems to sleep a lot +# +# [ant] a little insect that is known +# to enjoy picnics +# +# A minor variation on labeled lists uses two colons to separate the +# label from the list body: +# +# cat:: a small furry mammal +# that seems to sleep a lot +# +# ant:: a little insect that is known +# to enjoy picnics +# +# This latter style guarantees that the list bodies' left margins are +# aligned: think of them as a two column table. +# +# * Any line that starts to the right of the current margin is treated +# as verbatim text. This is useful for code listings. The example of a +# list above is also verbatim text. +# +# * A line starting with an equals sign (=) is treated as a +# heading. Level one headings have one equals sign, level two headings +# have two,and so on. +# +# * A line starting with three or more hyphens (at the current indent) +# generates a horizontal rule. THe more hyphens, the thicker the rule +# (within reason, and if supported by the output device) +# +# * You can use markup within text (except verbatim) to change the +# appearance of parts of that text. Out of the box, SimpleMarkup +# supports word-based and general markup. +# +# Word-based markup uses flag characters around individual words: +# +# [\*word*] displays word in a *bold* font +# [\_word_] displays word in an _emphasized_ font +# [\+word+] displays word in a +code+ font +# +# General markup affects text between a start delimiter and and end +# delimiter. Not surprisingly, these delimiters look like HTML markup. +# +# [\text...] displays word in a *bold* font +# [\text...] displays word in an _emphasized_ font +# [\text...] displays word in an _emphasized_ font +# [\text...] displays word in a +code+ font +# +# Unlike conventional Wiki markup, general markup can cross line +# boundaries. You can turn off the interpretation of markup by +# preceding the first character with a backslash, so \\\bold +# text and \\\*bold* produce \bold text and \*bold +# respectively. +# +# = Using SimpleMarkup +# +# For information on using SimpleMarkup programatically, +# see SM::SimpleMarkup. +# +# Author:: Dave Thomas, dave@pragmaticprogrammer.com +# Version:: 0.0 +# License:: Ruby license + + + +require 'rdoc/markup/simple_markup/fragments' +require 'rdoc/markup/simple_markup/lines.rb' + +module SM #:nodoc: + + # == Synopsis + # + # This code converts input_string, which is in the format + # described in markup/simple_markup.rb, to HTML. The conversion + # takes place in the +convert+ method, so you can use the same + # SimpleMarkup object to convert multiple input strings. + # + # require 'rdoc/markup/simple_markup' + # require 'rdoc/markup/simple_markup/to_html' + # + # p = SM::SimpleMarkup.new + # h = SM::ToHtml.new + # + # puts p.convert(input_string, h) + # + # You can extend the SimpleMarkup parser to recognise new markup + # sequences, and to add special processing for text that matches a + # regular epxression. Here we make WikiWords significant to the parser, + # and also make the sequences {word} and \text... signify + # strike-through text. When then subclass the HTML output class to deal + # with these: + # + # require 'rdoc/markup/simple_markup' + # require 'rdoc/markup/simple_markup/to_html' + # + # class WikiHtml < SM::ToHtml + # def handle_special_WIKIWORD(special) + # "" + special.text + "" + # end + # end + # + # p = SM::SimpleMarkup.new + # p.add_word_pair("{", "}", :STRIKE) + # p.add_html("no", :STRIKE) + # + # p.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD) + # + # h = WikiHtml.new + # h.add_tag(:STRIKE, "", "") + # + # puts "" + p.convert(ARGF.read, h) + "" + # + # == Output Formatters + # + # _missing_ + # + # + + class SimpleMarkup + + SPACE = ?\s + + # List entries look like: + # * text + # 1. text + # [label] text + # label:: text + # + # Flag it as a list entry, and + # work out the indent for subsequent lines + + SIMPLE_LIST_RE = /^( + ( \* (?# bullet) + |- (?# bullet) + |\d+\. (?# numbered ) + |[A-Za-z]\. (?# alphabetically numbered ) + ) + \s+ + )\S/x + + LABEL_LIST_RE = /^( + ( \[.*?\] (?# labeled ) + |\S.*:: (?# note ) + )(?:\s+|$) + )/x + + + ## + # take a block of text and use various heuristics to determine + # it's structure (paragraphs, lists, and so on). Invoke an + # event handler as we identify significant chunks. + # + + def initialize + @am = AttributeManager.new + @output = nil + end + + ## + # Add to the sequences used to add formatting to an individual word + # (such as *bold*). Matching entries will generate attibutes + # that the output formatters can recognize by their +name+ + + def add_word_pair(start, stop, name) + @am.add_word_pair(start, stop, name) + end + + ## + # Add to the sequences recognized as general markup + # + + def add_html(tag, name) + @am.add_html(tag, name) + end + + ## + # Add to other inline sequences. For example, we could add + # WikiWords using something like: + # + # parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD) + # + # Each wiki word will be presented to the output formatter + # via the accept_special method + # + + def add_special(pattern, name) + @am.add_special(pattern, name) + end + + + # We take a string, split it into lines, work out the type of + # each line, and from there deduce groups of lines (for example + # all lines in a paragraph). We then invoke the output formatter + # using a Visitor to display the result + + def convert(str, op) + @lines = Lines.new(str.split(/\r?\n/).collect { |aLine| + Line.new(aLine) }) + return "" if @lines.empty? + @lines.normalize + assign_types_to_lines + group = group_lines + # call the output formatter to handle the result + # group.to_a.each {|i| p i} + group.accept(@am, op) + end + + + ####### + private + ####### + + + ## + # Look through the text at line indentation. We flag each line as being + # Blank, a paragraph, a list element, or verbatim text + # + + def assign_types_to_lines(margin = 0, level = 0) + + while line = @lines.next + if line.isBlank? + line.stamp(Line::BLANK, level) + next + end + + # if a line contains non-blanks before the margin, then it must belong + # to an outer level + + text = line.text + + for i in 0...margin + if text[i] != SPACE + @lines.unget + return + end + end + + active_line = text[margin..-1] + + # Rules (horizontal lines) look like + # + # --- (three or more hyphens) + # + # The more hyphens, the thicker the rule + # + + if /^(---+)\s*$/ =~ active_line + line.stamp(Line::RULE, level, $1.length-2) + next + end + + # Then look for list entries. First the ones that have to have + # text following them (* xxx, - xxx, and dd. xxx) + + if SIMPLE_LIST_RE =~ active_line + + offset = margin + $1.length + prefix = $2 + prefix_length = prefix.length + + flag = case prefix + when "*","-" then ListBase::BULLET + when /^\d/ then ListBase::NUMBER + when /^[A-Z]/ then ListBase::UPPERALPHA + when /^[a-z]/ then ListBase::LOWERALPHA + else raise "Invalid List Type: #{self.inspect}" + end + + line.stamp(Line::LIST, level+1, prefix, flag) + text[margin, prefix_length] = " " * prefix_length + assign_types_to_lines(offset, level + 1) + next + end + + + if LABEL_LIST_RE =~ active_line + offset = margin + $1.length + prefix = $2 + prefix_length = prefix.length + + next if handled_labeled_list(line, level, margin, offset, prefix) + end + + # Headings look like + # = Main heading + # == Second level + # === Third + # + # Headings reset the level to 0 + + if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/ + prefix_length = $1.length + prefix_length = 6 if prefix_length > 6 + line.stamp(Line::HEADING, 0, prefix_length) + line.strip_leading(margin + prefix_length) + next + end + + # If the character's a space, then we have verbatim text, + # otherwise + + if active_line[0] == SPACE + line.strip_leading(margin) if margin > 0 + line.stamp(Line::VERBATIM, level) + else + line.stamp(Line::PARAGRAPH, level) + end + end + end + + # Handle labeled list entries, We have a special case + # to deal with. Because the labels can be long, they force + # the remaining block of text over the to right: + # + # this is a long label that I wrote:: and here is the + # block of text with + # a silly margin + # + # So we allow the special case. If the label is followed + # by nothing, and if the following line is indented, then + # we take the indent of that line as the new margin + # + # this is a long label that I wrote:: + # here is a more reasonably indented block which + # will ab attached to the label. + # + + def handled_labeled_list(line, level, margin, offset, prefix) + prefix_length = prefix.length + text = line.text + flag = nil + case prefix + when /^\[/ + flag = ListBase::LABELED + prefix = prefix[1, prefix.length-2] + when /:$/ + flag = ListBase::NOTE + prefix.chop! + else raise "Invalid List Type: #{self.inspect}" + end + + # body is on the next line + + if text.length <= offset + original_line = line + line = @lines.next + return(false) unless line + text = line.text + + for i in 0..margin + if text[i] != SPACE + @lines.unget + return false + end + end + i = margin + i += 1 while text[i] == SPACE + if i >= text.length + @lines.unget + return false + else + offset = i + prefix_length = 0 + @lines.delete(original_line) + end + end + + line.stamp(Line::LIST, level+1, prefix, flag) + text[margin, prefix_length] = " " * prefix_length + assign_types_to_lines(offset, level + 1) + return true + end + + # Return a block consisting of fragments which are + # paragraphs, list entries or verbatim text. We merge consecutive + # lines of the same type and level together. We are also slightly + # tricky with lists: the lines following a list introduction + # look like paragraph lines at the next level, and we remap them + # into list entries instead + + def group_lines + @lines.rewind + + inList = false + wantedType = wantedLevel = nil + + block = LineCollection.new + group = nil + + while line = @lines.next + if line.level == wantedLevel and line.type == wantedType + group.add_text(line.text) + else + group = block.fragment_for(line) + block.add(group) + if line.type == Line::LIST + wantedType = Line::PARAGRAPH + else + wantedType = line.type + end + wantedLevel = line.type == Line::HEADING ? line.param : line.level + end + end + + block.normalize + block + end + + ## for debugging, we allow access to our line contents as text + def content + @lines.as_text + end + public :content + + ## for debugging, return the list of line types + def get_line_types + @lines.line_types + end + public :get_line_types + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/fragments.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/fragments.rb new file mode 100644 index 00000000..6ca06382 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/fragments.rb @@ -0,0 +1,328 @@ +require 'rdoc/markup/simple_markup/lines.rb' +#require 'rdoc/markup/simple_markup/to_flow.rb' + +module SM + + ## + # A Fragment is a chunk of text, subclassed as a paragraph, a list + # entry, or verbatim text + + class Fragment + attr_reader :level, :param, :txt + attr_accessor :type + + def initialize(level, param, type, txt) + @level = level + @param = param + @type = type + @txt = "" + add_text(txt) if txt + end + + def add_text(txt) + @txt << " " if @txt.length > 0 + @txt << txt.tr_s("\n ", " ").strip + end + + def to_s + "L#@level: #{self.class.name.split('::')[-1]}\n#@txt" + end + + ###### + # This is a simple factory system that lets us associate fragement + # types (a string) with a subclass of fragment + + TYPE_MAP = {} + + def Fragment.type_name(name) + TYPE_MAP[name] = self + end + + def Fragment.for(line) + klass = TYPE_MAP[line.type] || + raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'") + return klass.new(line.level, line.param, line.flag, line.text) + end + end + + ## + # A paragraph is a fragment which gets wrapped to fit. We remove all + # newlines when we're created, and have them put back on output + + class Paragraph < Fragment + type_name Line::PARAGRAPH + end + + class BlankLine < Paragraph + type_name Line::BLANK + end + + class Heading < Paragraph + type_name Line::HEADING + + def head_level + @param.to_i + end + end + + ## + # A List is a fragment with some kind of label + # + + class ListBase < Paragraph + # List types + BULLET = :BULLET + NUMBER = :NUMBER + UPPERALPHA = :UPPERALPHA + LOWERALPHA = :LOWERALPHA + LABELED = :LABELED + NOTE = :NOTE + end + + class ListItem < ListBase + type_name Line::LIST + + # def label + # am = AttributeManager.new(@param) + # am.flow + # end + end + + class ListStart < ListBase + def initialize(level, param, type) + super(level, param, type, nil) + end + end + + class ListEnd < ListBase + def initialize(level, type) + super(level, "", type, nil) + end + end + + ## + # Verbatim code contains lines that don't get wrapped. + + class Verbatim < Fragment + type_name Line::VERBATIM + + def add_text(txt) + @txt << txt.chomp << "\n" + end + + end + + ## + # A horizontal rule + class Rule < Fragment + type_name Line::RULE + end + + + # Collect groups of lines together. Each group + # will end up containing a flow of text + + class LineCollection + + def initialize + @fragments = [] + end + + def add(fragment) + @fragments << fragment + end + + def each(&b) + @fragments.each(&b) + end + + # For testing + def to_a + @fragments.map {|fragment| fragment.to_s} + end + + # Factory for different fragment types + def fragment_for(*args) + Fragment.for(*args) + end + + # tidy up at the end + def normalize + change_verbatim_blank_lines + add_list_start_and_ends + add_list_breaks + tidy_blank_lines + end + + def to_s + @fragments.join("\n----\n") + end + + def accept(am, visitor) + + visitor.start_accepting + + @fragments.each do |fragment| + case fragment + when Verbatim + visitor.accept_verbatim(am, fragment) + when Rule + visitor.accept_rule(am, fragment) + when ListStart + visitor.accept_list_start(am, fragment) + when ListEnd + visitor.accept_list_end(am, fragment) + when ListItem + visitor.accept_list_item(am, fragment) + when BlankLine + visitor.accept_blank_line(am, fragment) + when Heading + visitor.accept_heading(am, fragment) + when Paragraph + visitor.accept_paragraph(am, fragment) + end + end + + visitor.end_accepting + end + ####### + private + ####### + + # If you have: + # + # normal paragraph text. + # + # this is code + # + # and more code + # + # You'll end up with the fragments Paragraph, BlankLine, + # Verbatim, BlankLine, Verbatim, BlankLine, etc + # + # The BlankLine in the middle of the verbatim chunk needs to + # be changed to a real verbatim newline, and the two + # verbatim blocks merged + # + # + def change_verbatim_blank_lines + frag_block = nil + blank_count = 0 + @fragments.each_with_index do |frag, i| + if frag_block.nil? + frag_block = frag if Verbatim === frag + else + case frag + when Verbatim + blank_count.times { frag_block.add_text("\n") } + blank_count = 0 + frag_block.add_text(frag.txt) + @fragments[i] = nil # remove out current fragment + when BlankLine + if frag_block + blank_count += 1 + @fragments[i] = nil + end + else + frag_block = nil + blank_count = 0 + end + end + end + @fragments.compact! + end + + # List nesting is implicit given the level of + # Make it explicit, just to make life a tad + # easier for the output processors + + def add_list_start_and_ends + level = 0 + res = [] + type_stack = [] + + @fragments.each do |fragment| + # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}" + new_level = fragment.level + while (level < new_level) + level += 1 + type = fragment.type + res << ListStart.new(level, fragment.param, type) if type + type_stack.push type + # $stderr.puts "Start: #{level}" + end + + while level > new_level + type = type_stack.pop + res << ListEnd.new(level, type) if type + level -= 1 + # $stderr.puts "End: #{level}, #{type}" + end + + res << fragment + level = fragment.level + end + level.downto(1) do |i| + type = type_stack.pop + res << ListEnd.new(i, type) if type + end + + @fragments = res + end + + # now insert start/ends between list entries at the + # same level that have different element types + + def add_list_breaks + res = @fragments + + @fragments = [] + list_stack = [] + + res.each do |fragment| + case fragment + when ListStart + list_stack.push fragment + when ListEnd + start = list_stack.pop + fragment.type = start.type + when ListItem + l = list_stack.last + if fragment.type != l.type + @fragments << ListEnd.new(l.level, l.type) + start = ListStart.new(l.level, fragment.param, fragment.type) + @fragments << start + list_stack.pop + list_stack.push start + end + else + ; + end + @fragments << fragment + end + end + + # Finally tidy up the blank lines: + # * change Blank/ListEnd into ListEnd/Blank + # * remove blank lines at the front + + def tidy_blank_lines + (@fragments.size - 1).times do |i| + if @fragments[i].kind_of?(BlankLine) and + @fragments[i+1].kind_of?(ListEnd) + @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] + end + end + + # remove leading blanks + @fragments.each_with_index do |f, i| + break unless f.kind_of? BlankLine + @fragments[i] = nil + end + + @fragments.compact! + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/inline.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/inline.rb new file mode 100644 index 00000000..d54fe1e6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/inline.rb @@ -0,0 +1,340 @@ +module SM + + # We manage a set of attributes. Each attribute has a symbol name + # and a bit value + + class Attribute + SPECIAL = 1 + + @@name_to_bitmap = { :_SPECIAL_ => SPECIAL } + @@next_bitmap = 2 + + def Attribute.bitmap_for(name) + bitmap = @@name_to_bitmap[name] + if !bitmap + bitmap = @@next_bitmap + @@next_bitmap <<= 1 + @@name_to_bitmap[name] = bitmap + end + bitmap + end + + def Attribute.as_string(bitmap) + return "none" if bitmap.zero? + res = [] + @@name_to_bitmap.each do |name, bit| + res << name if (bitmap & bit) != 0 + end + res.join(",") + end + + def Attribute.each_name_of(bitmap) + @@name_to_bitmap.each do |name, bit| + next if bit == SPECIAL + yield name.to_s if (bitmap & bit) != 0 + end + end + end + + + # An AttrChanger records a change in attributes. It contains + # a bitmap of the attributes to turn on, and a bitmap of those to + # turn off + + AttrChanger = Struct.new(:turn_on, :turn_off) + class AttrChanger + def to_s + "Attr: +#{Attribute.as_string(@turn_on)}/-#{Attribute.as_string(@turn_on)}" + end + end + + # An array of attributes which parallels the characters in a string + class AttrSpan + def initialize(length) + @attrs = Array.new(length, 0) + end + + def set_attrs(start, length, bits) + for i in start ... (start+length) + @attrs[i] |= bits + end + end + + def [](n) + @attrs[n] + end + end + + ## + # Hold details of a special sequence + + class Special + attr_reader :type + attr_accessor :text + + def initialize(type, text) + @type, @text = type, text + end + + def ==(o) + self.text == o.text && self.type == o.type + end + + def to_s + "Special: type=#{type}, text=#{text.dump}" + end + end + + class AttributeManager + + NULL = "\000".freeze + + ## + # We work by substituting non-printing characters in to the + # text. For now I'm assuming that I can substitute + # a character in the range 0..8 for a 7 bit character + # without damaging the encoded string, but this might + # be optimistic + # + + A_PROTECT = 004 + PROTECT_ATTR = A_PROTECT.chr + + # This maps delimiters that occur around words (such as + # *bold* or +tt+) where the start and end delimiters + # and the same. This lets us optimize the regexp + MATCHING_WORD_PAIRS = {} + + # And this is used when the delimiters aren't the same. In this + # case the hash maps a pattern to the attribute character + WORD_PAIR_MAP = {} + + # This maps HTML tags to the corresponding attribute char + HTML_TAGS = {} + + # And this maps _special_ sequences to a name. A special sequence + # is something like a WikiWord + SPECIAL = {} + + # Return an attribute object with the given turn_on + # and turn_off bits set + + def attribute(turn_on, turn_off) + AttrChanger.new(turn_on, turn_off) + end + + + def change_attribute(current, new) + diff = current ^ new + attribute(new & diff, current & diff) + end + + def changed_attribute_by_name(current_set, new_set) + current = new = 0 + current_set.each {|name| current |= Attribute.bitmap_for(name) } + new_set.each {|name| new |= Attribute.bitmap_for(name) } + change_attribute(current, new) + end + + def copy_string(start_pos, end_pos) + res = @str[start_pos...end_pos] + res.gsub!(/\000/, '') + res + end + + # Map attributes like textto the sequence \001\002\001\003, + # where is a per-attribute specific character + + def convert_attrs(str, attrs) + # first do matching ones + tags = MATCHING_WORD_PAIRS.keys.join("") + re = "(^|\\W)([#{tags}])([A-Za-z_]+?)\\2(\\W|\$)" +# re = "(^|\\W)([#{tags}])(\\S+?)\\2(\\W|\$)" + 1 while str.gsub!(Regexp.new(re)) { + attr = MATCHING_WORD_PAIRS[$2]; + attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr) + $1 + NULL*$2.length + $3 + NULL*$2.length + $4 + } + + # then non-matching + unless WORD_PAIR_MAP.empty? + WORD_PAIR_MAP.each do |regexp, attr| + str.gsub!(regexp) { + attrs.set_attrs($`.length + $1.length, $2.length, attr) + NULL*$1.length + $2 + NULL*$3.length + } + end + end + end + + def convert_html(str, attrs) + tags = HTML_TAGS.keys.join("|") + re = "<(#{tags})>(.*?)" + 1 while str.gsub!(Regexp.new(re, Regexp::IGNORECASE)) { + attr = HTML_TAGS[$1.downcase] + html_length = $1.length + 2 + seq = NULL * html_length + attrs.set_attrs($`.length + html_length, $2.length, attr) + seq + $2 + seq + NULL + } + end + + def convert_specials(str, attrs) + unless SPECIAL.empty? + SPECIAL.each do |regexp, attr| + str.scan(regexp) do + attrs.set_attrs($`.length, $&.length, attr | Attribute::SPECIAL) + end + end + end + end + + # A \ in front of a character that would normally be + # processed turns off processing. We do this by turning + # \< into <#{PROTECT} + + PROTECTABLE = [ "<" << "\\" ] #" + + + def mask_protected_sequences + protect_pattern = Regexp.new("\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])") + @str.gsub!(protect_pattern, "\\1#{PROTECT_ATTR}") + end + + def unmask_protected_sequences + @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000") + end + + def initialize + add_word_pair("*", "*", :BOLD) + add_word_pair("_", "_", :EM) + add_word_pair("+", "+", :TT) + + add_html("em", :EM) + add_html("i", :EM) + add_html("b", :BOLD) + add_html("tt", :TT) + add_html("code", :TT) + + add_special(//, :COMMENT) + end + + def add_word_pair(start, stop, name) + raise "Word flags may not start '<'" if start[0] == ?< + bitmap = Attribute.bitmap_for(name) + if start == stop + MATCHING_WORD_PAIRS[start] = bitmap + else + pattern = Regexp.new("(" + Regexp.escape(start) + ")" + +# "([A-Za-z]+)" + + "(\\S+)" + + "(" + Regexp.escape(stop) +")") + WORD_PAIR_MAP[pattern] = bitmap + end + PROTECTABLE << start[0,1] + PROTECTABLE.uniq! + end + + def add_html(tag, name) + HTML_TAGS[tag.downcase] = Attribute.bitmap_for(name) + end + + def add_special(pattern, name) + SPECIAL[pattern] = Attribute.bitmap_for(name) + end + + def flow(str) + @str = str + + puts("Before flow, str='#{@str.dump}'") if $DEBUG + mask_protected_sequences + + @attrs = AttrSpan.new(@str.length) + + puts("After protecting, str='#{@str.dump}'") if $DEBUG + convert_attrs(@str, @attrs) + convert_html(@str, @attrs) + convert_specials(str, @attrs) + unmask_protected_sequences + puts("After flow, str='#{@str.dump}'") if $DEBUG + return split_into_flow + end + + def display_attributes + puts + puts @str.tr(NULL, "!") + bit = 1 + 16.times do |bno| + line = "" + @str.length.times do |i| + if (@attrs[i] & bit) == 0 + line << " " + else + if bno.zero? + line << "S" + else + line << ("%d" % (bno+1)) + end + end + end + puts(line) unless line =~ /^ *$/ + bit <<= 1 + end + end + + def split_into_flow + + display_attributes if $DEBUG + + res = [] + current_attr = 0 + str = "" + + + str_len = @str.length + + # skip leading invisible text + i = 0 + i += 1 while i < str_len and @str[i].zero? + start_pos = i + + # then scan the string, chunking it on attribute changes + while i < str_len + new_attr = @attrs[i] + if new_attr != current_attr + if i > start_pos + res << copy_string(start_pos, i) + start_pos = i + end + + res << change_attribute(current_attr, new_attr) + current_attr = new_attr + + if (current_attr & Attribute::SPECIAL) != 0 + i += 1 while i < str_len and (@attrs[i] & Attribute::SPECIAL) != 0 + res << Special.new(current_attr, copy_string(start_pos, i)) + start_pos = i + next + end + end + + # move on, skipping any invisible characters + begin + i += 1 + end while i < str_len and @str[i].zero? + end + + # tidy up trailing text + if start_pos < str_len + res << copy_string(start_pos, str_len) + end + + # and reset to all attributes off + res << change_attribute(current_attr, 0) if current_attr != 0 + + return res + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/lines.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/lines.rb new file mode 100644 index 00000000..4e294f27 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/lines.rb @@ -0,0 +1,151 @@ +########################################################################## +# +# We store the lines we're working on as objects of class Line. +# These contain the text of the line, along with a flag indicating the +# line type, and an indentation level + +module SM + + class Line + INFINITY = 9999 + + BLANK = :BLANK + HEADING = :HEADING + LIST = :LIST + RULE = :RULE + PARAGRAPH = :PARAGRAPH + VERBATIM = :VERBATIM + + # line type + attr_accessor :type + + # The indentation nesting level + attr_accessor :level + + # The contents + attr_accessor :text + + # A prefix or parameter. For LIST lines, this is + # the text that introduced the list item (the label) + attr_accessor :param + + # A flag. For list lines, this is the type of the list + attr_accessor :flag + + # the number of leading spaces + attr_accessor :leading_spaces + + # true if this line has been deleted from the list of lines + attr_accessor :deleted + + + def initialize(text) + @text = text.dup + @deleted = false + + # expand tabs + 1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)} && $~ #` + + # Strip trailing whitespace + @text.sub!(/\s+$/, '') + + # and look for leading whitespace + if @text.length > 0 + @text =~ /^(\s*)/ + @leading_spaces = $1.length + else + @leading_spaces = INFINITY + end + end + + # Return true if this line is blank + def isBlank? + @text.length.zero? + end + + # stamp a line with a type, a level, a prefix, and a flag + def stamp(type, level, param="", flag=nil) + @type, @level, @param, @flag = type, level, param, flag + end + + ## + # Strip off the leading margin + # + + def strip_leading(size) + if @text.size > size + @text[0,size] = "" + else + @text = "" + end + end + + def to_s + "#@type#@level: #@text" + end + end + + ############################################################################### + # + # A container for all the lines + # + + class Lines + include Enumerable + + attr_reader :lines # for debugging + + def initialize(lines) + @lines = lines + rewind + end + + def empty? + @lines.size.zero? + end + + def each + @lines.each do |line| + yield line unless line.deleted + end + end + +# def [](index) +# @lines[index] +# end + + def rewind + @nextline = 0 + end + + def next + begin + res = @lines[@nextline] + @nextline += 1 if @nextline < @lines.size + end while res and res.deleted and @nextline < @lines.size + res + end + + def unget + @nextline -= 1 + end + + def delete(a_line) + a_line.deleted = true + end + + def normalize + margin = @lines.collect{|l| l.leading_spaces}.min + margin = 0 if margin == Line::INFINITY + @lines.each {|line| line.strip_leading(margin) } if margin > 0 + end + + def as_text + @lines.map {|l| l.text}.join("\n") + end + + def line_types + @lines.map {|l| l.type } + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/preprocess.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/preprocess.rb new file mode 100644 index 00000000..101c9bde --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/preprocess.rb @@ -0,0 +1,73 @@ +module SM + + ## + # Handle common directives that can occur in a block of text: + # + # : include : filename + # + + class PreProcess + + def initialize(input_file_name, include_path) + @input_file_name = input_file_name + @include_path = include_path + end + + # Look for common options in a chunk of text. Options that + # we don't handle are passed back to our caller + # as |directive, param| + + def handle(text) + text.gsub!(/^([ \t#]*):(\w+):\s*(.+)?\n/) do + prefix = $1 + directive = $2.downcase + param = $3 + + case directive + when "include" + filename = param.split[0] + include_file(filename, prefix) + + else + yield(directive, param) + end + end + end + + ####### + private + ####### + + # Include a file, indenting it correctly + + def include_file(name, indent) + if (full_name = find_include_file(name)) + content = File.open(full_name) {|f| f.read} + # strip leading '#'s, but only if all lines start with them + if content =~ /^[^#]/ + content.gsub(/^/, indent) + else + content.gsub(/^#?/, indent) + end + else + $stderr.puts "Couldn't find file to include: '#{name}'" + '' + end + end + + # Look for the given file in the directory containing the current + # file, and then in each of the directories specified in the + # RDOC_INCLUDE path + + def find_include_file(name) + to_search = [ File.dirname(@input_file_name) ].concat @include_path + to_search.each do |dir| + full_name = File.join(dir, name) + stat = File.stat(full_name) rescue next + return full_name if stat.readable? + end + nil + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_flow.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_flow.rb new file mode 100644 index 00000000..048e71ab --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_flow.rb @@ -0,0 +1,188 @@ +require 'rdoc/markup/simple_markup/fragments' +require 'rdoc/markup/simple_markup/inline' +require 'cgi' + +module SM + + module Flow + P = Struct.new(:body) + VERB = Struct.new(:body) + RULE = Struct.new(:width) + class LIST + attr_reader :type, :contents + def initialize(type) + @type = type + @contents = [] + end + def <<(stuff) + @contents << stuff + end + end + LI = Struct.new(:label, :body) + H = Struct.new(:level, :text) + end + + class ToFlow + LIST_TYPE_TO_HTML = { + SM::ListBase::BULLET => [ "
    ", "
" ], + SM::ListBase::NUMBER => [ "
    ", "
" ], + SM::ListBase::UPPERALPHA => [ "
    ", "
" ], + SM::ListBase::LOWERALPHA => [ "
    ", "
" ], + SM::ListBase::LABELED => [ "
", "
" ], + SM::ListBase::NOTE => [ "", "
" ], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + init_tags + end + + ## + # Set up the standard mapping of attributes to HTML tags + # + def init_tags + @attr_tags = [ + InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "", ""), + InlineTag.new(SM::Attribute.bitmap_for(:TT), "", ""), + InlineTag.new(SM::Attribute.bitmap_for(:EM), "", ""), + ] + end + + ## + # Add a new set of HTML tags for an attribute. We allow + # separate start and end tags for flexibility + # + def add_tag(name, start, stop) + @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop) + end + + ## + # Given an HTML tag, decorate it with class information + # and the like if required. This is a no-op in the base + # class, but is overridden in HTML output classes that + # implement style sheets + + def annotate(tag) + tag + end + + ## + # Here's the client side of the visitor pattern + + def start_accepting + @res = [] + @list_stack = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << Flow::P.new((convert_flow(am.flow(fragment.txt)))) + end + + def accept_verbatim(am, fragment) + @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt)))) + end + + def accept_rule(am, fragment) + size = fragment.param + size = 10 if size > 10 + @res << Flow::RULE.new(size) + end + + def accept_list_start(am, fragment) + @list_stack.push(@res) + list = Flow::LIST.new(fragment.type) + @res << list + @res = list + end + + def accept_list_end(am, fragment) + @res = @list_stack.pop + end + + def accept_list_item(am, fragment) + @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt))) + end + + def accept_blank_line(am, fragment) + # @res << annotate("

") << "\n" + end + + def accept_heading(am, fragment) + @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt))) + end + + + ####################################################################### + + private + + ####################################################################### + + def on_tags(res, item) + attr_mask = item.turn_on + return if attr_mask.zero? + + @attr_tags.each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.on) + end + end + end + + def off_tags(res, item) + attr_mask = item.turn_off + return if attr_mask.zero? + + @attr_tags.reverse_each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.off) + end + end + end + + def convert_flow(flow) + res = "" + flow.each do |item| + case item + when String + res << convert_string(item) + when AttrChanger + off_tags(res, item) + on_tags(res, item) + when Special + res << convert_special(item) + else + raise "Unknown flow element: #{item.inspect}" + end + end + res + end + + # some of these patterns are taken from SmartyPants... + + def convert_string(item) + CGI.escapeHTML(item) + end + + def convert_special(special) + handled = false + Attribute.each_name_of(special.type) do |name| + method_name = "handle_special_#{name}" + if self.respond_to? method_name + special.text = send(method_name, special) + handled = true + end + end + raise "Unhandled special: #{special}" unless handled + special.text + end + + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_html.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_html.rb new file mode 100644 index 00000000..26b5f4ce --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_html.rb @@ -0,0 +1,289 @@ +require 'rdoc/markup/simple_markup/fragments' +require 'rdoc/markup/simple_markup/inline' + +require 'cgi' + +module SM + + class ToHtml + + LIST_TYPE_TO_HTML = { + ListBase::BULLET => [ "

    ", "
" ], + ListBase::NUMBER => [ "
    ", "
" ], + ListBase::UPPERALPHA => [ "
    ", "
" ], + ListBase::LOWERALPHA => [ "
    ", "
" ], + ListBase::LABELED => [ "
", "
" ], + ListBase::NOTE => [ "", "
" ], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + init_tags + end + + ## + # Set up the standard mapping of attributes to HTML tags + # + def init_tags + @attr_tags = [ + InlineTag.new(SM::Attribute.bitmap_for(:BOLD), "", ""), + InlineTag.new(SM::Attribute.bitmap_for(:TT), "", ""), + InlineTag.new(SM::Attribute.bitmap_for(:EM), "", ""), + ] + end + + ## + # Add a new set of HTML tags for an attribute. We allow + # separate start and end tags for flexibility + # + def add_tag(name, start, stop) + @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop) + end + + ## + # Given an HTML tag, decorate it with class information + # and the like if required. This is a no-op in the base + # class, but is overridden in HTML output classes that + # implement style sheets + + def annotate(tag) + tag + end + + ## + # Here's the client side of the visitor pattern + + def start_accepting + @res = "" + @in_list_entry = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << annotate("

") + "\n" + @res << wrap(convert_flow(am.flow(fragment.txt))) + @res << annotate("

") + "\n" + end + + def accept_verbatim(am, fragment) + @res << annotate("
") + "\n"
+      @res << CGI.escapeHTML(fragment.txt)
+      @res << annotate("
") << "\n" + end + + def accept_rule(am, fragment) + size = fragment.param + size = 10 if size > 10 + @res << "
" + end + + def accept_list_start(am, fragment) + @res << html_list_name(fragment.type, true) <<"\n" + @in_list_entry.push false + end + + def accept_list_end(am, fragment) + if tag = @in_list_entry.pop + @res << annotate(tag) << "\n" + end + @res << html_list_name(fragment.type, false) <<"\n" + end + + def accept_list_item(am, fragment) + if tag = @in_list_entry.last + @res << annotate(tag) << "\n" + end + @res << list_item_start(am, fragment) + @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n" + @in_list_entry[-1] = list_end_for(fragment.type) + end + + def accept_blank_line(am, fragment) + # @res << annotate("

") << "\n" + end + + def accept_heading(am, fragment) + @res << convert_heading(fragment.head_level, am.flow(fragment.txt)) + end + + # This is a higher speed (if messier) version of wrap + + def wrap(txt, line_len = 76) + res = "" + sp = 0 + ep = txt.length + while sp < ep + # scan back for a space + p = sp + line_len - 1 + if p >= ep + p = ep + else + while p > sp and txt[p] != ?\s + p -= 1 + end + if p <= sp + p = sp + line_len + while p < ep and txt[p] != ?\s + p += 1 + end + end + end + res << txt[sp...p] << "\n" + sp = p + sp += 1 while sp < ep and txt[sp] == ?\s + end + res + end + + ####################################################################### + + private + + ####################################################################### + + def on_tags(res, item) + attr_mask = item.turn_on + return if attr_mask.zero? + + @attr_tags.each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.on) + end + end + end + + def off_tags(res, item) + attr_mask = item.turn_off + return if attr_mask.zero? + + @attr_tags.reverse_each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.off) + end + end + end + + def convert_flow(flow) + res = "" + flow.each do |item| + case item + when String + res << convert_string(item) + when AttrChanger + off_tags(res, item) + on_tags(res, item) + when Special + res << convert_special(item) + else + raise "Unknown flow element: #{item.inspect}" + end + end + res + end + + # some of these patterns are taken from SmartyPants... + + def convert_string(item) + CGI.escapeHTML(item). + + + # convert -- to em-dash, (-- to en-dash) + gsub(/---?/, '—'). #gsub(/--/, '–'). + + # convert ... to elipsis (and make sure .... becomes .) + gsub(/\.\.\.\./, '.…').gsub(/\.\.\./, '…'). + + # convert single closing quote + gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1’" }. + gsub(%r{\'(?=\W|s\b)}) { "’" }. + + # convert single opening quote + gsub(/'/, '‘'). + + # convert double closing quote + gsub(%r{([^ \t\r\n\[\{\(])\'(?=\W)}) { "#$1”" }. + + # convert double opening quote + gsub(/'/, '“'). + + # convert copyright + gsub(/\(c\)/, '©'). + + # convert and registered trademark + gsub(/\(r\)/, '®') + + end + + def convert_special(special) + handled = false + Attribute.each_name_of(special.type) do |name| + method_name = "handle_special_#{name}" + if self.respond_to? method_name + special.text = send(method_name, special) + handled = true + end + end + raise "Unhandled special: #{special}" unless handled + special.text + end + + def convert_heading(level, flow) + res = + annotate("") + + convert_flow(flow) + + annotate("\n") + end + + def html_list_name(list_type, is_open_tag) + tags = LIST_TYPE_TO_HTML[list_type] || raise("Invalid list type: #{list_type.inspect}") + annotate(tags[ is_open_tag ? 0 : 1]) + end + + def list_item_start(am, fragment) + case fragment.type + when ListBase::BULLET, ListBase::NUMBER + annotate("

  • ") + + when ListBase::UPPERALPHA + annotate("
  • ") + + when ListBase::LOWERALPHA + annotate("
  • ") + + when ListBase::LABELED + annotate("
    ") + + convert_flow(am.flow(fragment.param)) + + annotate("
    ") + + annotate("
    ") + + when ListBase::NOTE + annotate("") + + annotate("") + + convert_flow(am.flow(fragment.param)) + + annotate("") + + annotate("") + else + raise "Invalid list type" + end + end + + def list_end_for(fragment_type) + case fragment_type + when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA + "
  • " + when ListBase::LABELED + "" + when ListBase::NOTE + "" + else + raise "Invalid list type" + end + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_latex.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_latex.rb new file mode 100644 index 00000000..6c162786 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/simple_markup/to_latex.rb @@ -0,0 +1,333 @@ +require 'rdoc/markup/simple_markup/fragments' +require 'rdoc/markup/simple_markup/inline' + +require 'cgi' + +module SM + + # Convert SimpleMarkup to basic LaTeX report format + + class ToLaTeX + + BS = "\020" # \ + OB = "\021" # { + CB = "\022" # } + DL = "\023" # Dollar + + BACKSLASH = "#{BS}symbol#{OB}92#{CB}" + HAT = "#{BS}symbol#{OB}94#{CB}" + BACKQUOTE = "#{BS}symbol#{OB}0#{CB}" + TILDE = "#{DL}#{BS}sim#{DL}" + LESSTHAN = "#{DL}<#{DL}" + GREATERTHAN = "#{DL}>#{DL}" + + def self.l(str) + str.tr('\\', BS).tr('{', OB).tr('}', CB).tr('$', DL) + end + + def l(arg) + SM::ToLaTeX.l(arg) + end + + LIST_TYPE_TO_LATEX = { + ListBase::BULLET => [ l("\\begin{itemize}"), l("\\end{itemize}") ], + ListBase::NUMBER => [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\arabic" ], + ListBase::UPPERALPHA => [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\Alph" ], + ListBase::LOWERALPHA => [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\alph" ], + ListBase::LABELED => [ l("\\begin{description}"), l("\\end{description}") ], + ListBase::NOTE => [ + l("\\begin{tabularx}{\\linewidth}{@{} l X @{}}"), + l("\\end{tabularx}") ], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + init_tags + @list_depth = 0 + @prev_list_types = [] + end + + ## + # Set up the standard mapping of attributes to LaTeX + # + def init_tags + @attr_tags = [ + InlineTag.new(SM::Attribute.bitmap_for(:BOLD), l("\\textbf{"), l("}")), + InlineTag.new(SM::Attribute.bitmap_for(:TT), l("\\texttt{"), l("}")), + InlineTag.new(SM::Attribute.bitmap_for(:EM), l("\\emph{"), l("}")), + ] + end + + ## + # Escape a LaTeX string + def escape(str) +# $stderr.print "FE: ", str + s = str. +# sub(/\s+$/, ''). + gsub(/([_\${}&%#])/, "#{BS}\\1"). + gsub(/\\/, BACKSLASH). + gsub(/\^/, HAT). + gsub(/~/, TILDE). + gsub(//, GREATERTHAN). + gsub(/,,/, ",{},"). + gsub(/\`/, BACKQUOTE) +# $stderr.print "-> ", s, "\n" + s + end + + ## + # Add a new set of LaTeX tags for an attribute. We allow + # separate start and end tags for flexibility + # + def add_tag(name, start, stop) + @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop) + end + + + ## + # Here's the client side of the visitor pattern + + def start_accepting + @res = "" + @in_list_entry = [] + end + + def end_accepting + @res.tr(BS, '\\').tr(OB, '{').tr(CB, '}').tr(DL, '$') + end + + def accept_paragraph(am, fragment) + @res << wrap(convert_flow(am.flow(fragment.txt))) + @res << "\n" + end + + def accept_verbatim(am, fragment) + @res << "\n\\begin{code}\n" + @res << fragment.txt.sub(/[\n\s]+\Z/, '') + @res << "\n\\end{code}\n\n" + end + + def accept_rule(am, fragment) + size = fragment.param + size = 10 if size > 10 + @res << "\n\n\\rule{\\linewidth}{#{size}pt}\n\n" + end + + def accept_list_start(am, fragment) + @res << list_name(fragment.type, true) <<"\n" + @in_list_entry.push false + end + + def accept_list_end(am, fragment) + if tag = @in_list_entry.pop + @res << tag << "\n" + end + @res << list_name(fragment.type, false) <<"\n" + end + + def accept_list_item(am, fragment) + if tag = @in_list_entry.last + @res << tag << "\n" + end + @res << list_item_start(am, fragment) + @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n" + @in_list_entry[-1] = list_end_for(fragment.type) + end + + def accept_blank_line(am, fragment) + # @res << "\n" + end + + def accept_heading(am, fragment) + @res << convert_heading(fragment.head_level, am.flow(fragment.txt)) + end + + # This is a higher speed (if messier) version of wrap + + def wrap(txt, line_len = 76) + res = "" + sp = 0 + ep = txt.length + while sp < ep + # scan back for a space + p = sp + line_len - 1 + if p >= ep + p = ep + else + while p > sp and txt[p] != ?\s + p -= 1 + end + if p <= sp + p = sp + line_len + while p < ep and txt[p] != ?\s + p += 1 + end + end + end + res << txt[sp...p] << "\n" + sp = p + sp += 1 while sp < ep and txt[sp] == ?\s + end + res + end + + ####################################################################### + + private + + ####################################################################### + + def on_tags(res, item) + attr_mask = item.turn_on + return if attr_mask.zero? + + @attr_tags.each do |tag| + if attr_mask & tag.bit != 0 + res << tag.on + end + end + end + + def off_tags(res, item) + attr_mask = item.turn_off + return if attr_mask.zero? + + @attr_tags.reverse_each do |tag| + if attr_mask & tag.bit != 0 + res << tag.off + end + end + end + + def convert_flow(flow) + res = "" + flow.each do |item| + case item + when String +# $stderr.puts "Converting '#{item}'" + res << convert_string(item) + when AttrChanger + off_tags(res, item) + on_tags(res, item) + when Special + res << convert_special(item) + else + raise "Unknown flow element: #{item.inspect}" + end + end + res + end + + # some of these patterns are taken from SmartyPants... + + def convert_string(item) + + escape(item). + + + # convert ... to elipsis (and make sure .... becomes .) + gsub(/\.\.\.\./, '.\ldots{}').gsub(/\.\.\./, '\ldots{}'). + + # convert single closing quote + gsub(%r{([^ \t\r\n\[\{\(])\'}) { "#$1'" }. + gsub(%r{\'(?=\W|s\b)}) { "'" }. + + # convert single opening quote + gsub(/'/, '`'). + + # convert double closing quote + gsub(%r{([^ \t\r\n\[\{\(])\"(?=\W)}) { "#$1''" }. + + # convert double opening quote + gsub(/"/, "``"). + + # convert copyright + gsub(/\(c\)/, '\copyright{}') + + end + + def convert_special(special) + handled = false + Attribute.each_name_of(special.type) do |name| + method_name = "handle_special_#{name}" + if self.respond_to? method_name + special.text = send(method_name, special) + handled = true + end + end + raise "Unhandled special: #{special}" unless handled + special.text + end + + def convert_heading(level, flow) + res = + case level + when 1 then "\\chapter{" + when 2 then "\\section{" + when 3 then "\\subsection{" + when 4 then "\\subsubsection{" + else "\\paragraph{" + end + + convert_flow(flow) + + "}\n" + end + + def list_name(list_type, is_open_tag) + tags = LIST_TYPE_TO_LATEX[list_type] || raise("Invalid list type: #{list_type.inspect}") + if tags[2] # enumerate + if is_open_tag + @list_depth += 1 + if @prev_list_types[@list_depth] != tags[2] + case @list_depth + when 1 + roman = "i" + when 2 + roman = "ii" + when 3 + roman = "iii" + when 4 + roman = "iv" + else + raise("Too deep list: level #{@list_depth}") + end + @prev_list_types[@list_depth] = tags[2] + return l("\\renewcommand{\\labelenum#{roman}}{#{tags[2]}{enum#{roman}}}") + "\n" + tags[0] + end + else + @list_depth -= 1 + end + end + tags[ is_open_tag ? 0 : 1] + end + + def list_item_start(am, fragment) + case fragment.type + when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA + "\\item " + + when ListBase::LABELED + "\\item[" + convert_flow(am.flow(fragment.param)) + "] " + + when ListBase::NOTE + convert_flow(am.flow(fragment.param)) + " & " + else + raise "Invalid list type" + end + end + + def list_end_for(fragment_type) + case fragment_type + when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA, ListBase::LABELED + "" + when ListBase::NOTE + "\\\\\n" + else + raise "Invalid list type" + end + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/AllTests.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/AllTests.rb new file mode 100644 index 00000000..b9c8c9df --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/AllTests.rb @@ -0,0 +1,2 @@ +require 'TestParse.rb' +require 'TestInline.rb' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/TestInline.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/TestInline.rb new file mode 100644 index 00000000..a067d4c2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/TestInline.rb @@ -0,0 +1,154 @@ +require "test/unit" + +$:.unshift "../../.." + +require "rdoc/markup/simple_markup/inline" + +class TestInline < Test::Unit::TestCase + + + def setup + @am = SM::AttributeManager.new + + @bold_on = @am.changed_attribute_by_name([], [:BOLD]) + @bold_off = @am.changed_attribute_by_name([:BOLD], []) + + @tt_on = @am.changed_attribute_by_name([], [:TT]) + @tt_off = @am.changed_attribute_by_name([:TT], []) + + @em_on = @am.changed_attribute_by_name([], [:EM]) + @em_off = @am.changed_attribute_by_name([:EM], []) + + @bold_em_on = @am.changed_attribute_by_name([], [:BOLD] | [:EM]) + @bold_em_off = @am.changed_attribute_by_name([:BOLD] | [:EM], []) + + @em_then_bold = @am.changed_attribute_by_name([:EM], [:EM] | [:BOLD]) + + @em_to_bold = @am.changed_attribute_by_name([:EM], [:BOLD]) + + @am.add_word_pair("{", "}", :WOMBAT) + @wombat_on = @am.changed_attribute_by_name([], [:WOMBAT]) + @wombat_off = @am.changed_attribute_by_name([:WOMBAT], []) + end + + def crossref(text) + [ @am.changed_attribute_by_name([], [:CROSSREF] | [:_SPECIAL_]), + SM::Special.new(33, text), + @am.changed_attribute_by_name([:CROSSREF] | [:_SPECIAL_], []) + ] + end + + def test_special + # class names, variable names, file names, or instance variables + @am.add_special(/( + \b([A-Z]\w+(::\w+)*) + | \#\w+[!?=]? + | \b\w+([_\/\.]+\w+)+[!?=]? + )/x, + :CROSSREF) + + assert_equal(["cat"], @am.flow("cat")) + + assert_equal(["cat ", crossref("#fred"), " dog"].flatten, + @am.flow("cat #fred dog")) + + assert_equal([crossref("#fred"), " dog"].flatten, + @am.flow("#fred dog")) + + assert_equal(["cat ", crossref("#fred")].flatten, @am.flow("cat #fred")) + end + + def test_basic + assert_equal(["cat"], @am.flow("cat")) + + assert_equal(["cat ", @bold_on, "and", @bold_off, " dog"], + @am.flow("cat *and* dog")) + + assert_equal(["cat ", @bold_on, "AND", @bold_off, " dog"], + @am.flow("cat *AND* dog")) + + assert_equal(["cat ", @em_on, "And", @em_off, " dog"], + @am.flow("cat _And_ dog")) + + assert_equal(["cat *and dog*"], @am.flow("cat *and dog*")) + + assert_equal(["*cat and* dog"], @am.flow("*cat and* dog")) + + assert_equal(["cat *and ", @bold_on, "dog", @bold_off], + @am.flow("cat *and *dog*")) + + assert_equal(["cat ", @em_on, "and", @em_off, " dog"], + @am.flow("cat _and_ dog")) + + assert_equal(["cat_and_dog"], + @am.flow("cat_and_dog")) + + assert_equal(["cat ", @tt_on, "and", @tt_off, " dog"], + @am.flow("cat +and+ dog")) + + assert_equal(["cat ", @bold_on, "a_b_c", @bold_off, " dog"], + @am.flow("cat *a_b_c* dog")) + + assert_equal(["cat __ dog"], + @am.flow("cat __ dog")) + + assert_equal(["cat ", @em_on, "_", @em_off, " dog"], + @am.flow("cat ___ dog")) + + end + + def test_combined + assert_equal(["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off], + @am.flow("cat _and_ *dog*")) + + assert_equal(["cat ", @em_on, "a__nd", @em_off, " ", @bold_on, "dog", @bold_off], + @am.flow("cat _a__nd_ *dog*")) + end + + def test_html_like + assert_equal(["cat ", @tt_on, "dog", @tt_off], @am.flow("cat dog")) + + assert_equal(["cat ", @em_on, "and", @em_off, " ", @bold_on, "dog", @bold_off], + @am.flow("cat and dog")) + + assert_equal(["cat ", @em_on, "and ", @em_then_bold, "dog", @bold_em_off], + @am.flow("cat and dog")) + + assert_equal(["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off], + @am.flow("cat and dog")) + + assert_equal(["cat ", @em_on, "and ", @em_to_bold, "dog", @bold_off], + @am.flow("cat and dog")) + + assert_equal([@tt_on, "cat", @tt_off, " ", @em_on, "and ", @em_to_bold, "dog", @bold_off], + @am.flow("cat and dog")) + + assert_equal(["cat ", @em_on, "and ", @em_then_bold, "dog", @bold_em_off], + @am.flow("cat and dog")) + + assert_equal(["cat ", @bold_em_on, "and", @bold_em_off, " dog"], + @am.flow("cat and dog")) + + + end + + def test_protect + assert_equal(['cat \\ dog'], @am.flow('cat \\ dog')) + + assert_equal(["cat dog"], @am.flow("cat \\dog")) + + assert_equal(["cat ", @em_on, "and", @em_off, " dog"], + @am.flow("cat and \\dog")) + + assert_equal(["*word* or text"], @am.flow("\\*word* or \\text")) + + assert_equal(["_cat_", @em_on, "dog", @em_off], + @am.flow("\\_cat_dog")) + end + + def test_adding + assert_equal(["cat ", @wombat_on, "and", @wombat_off, " dog" ], + @am.flow("cat {and} dog")) +# assert_equal(["cat {and} dog" ], @am.flow("cat \\{and} dog")) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/TestParse.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/TestParse.rb new file mode 100644 index 00000000..3ec541ce --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/markup/test/TestParse.rb @@ -0,0 +1,503 @@ +require 'test/unit' + +$:.unshift "../../.." + +require 'rdoc/markup/simple_markup' + +include SM + +class TestParse < Test::Unit::TestCase + + class MockOutput + def start_accepting + @res = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << fragment.to_s + end + + def accept_verbatim(am, fragment) + @res << fragment.to_s + end + + def accept_list_start(am, fragment) + @res << fragment.to_s + end + + def accept_list_end(am, fragment) + @res << fragment.to_s + end + + def accept_list_item(am, fragment) + @res << fragment.to_s + end + + def accept_blank_line(am, fragment) + @res << fragment.to_s + end + + def accept_heading(am, fragment) + @res << fragment.to_s + end + + def accept_rule(am, fragment) + @res << fragment.to_s + end + + end + + def basic_conv(str) + sm = SimpleMarkup.new + mock = MockOutput.new + sm.convert(str, mock) + sm.content + end + + def line_types(str, expected) + p = SimpleMarkup.new + mock = MockOutput.new + p.convert(str, mock) + assert_equal(expected, p.get_line_types.map{|type| type.to_s[0,1]}.join('')) + end + + def line_groups(str, expected) + p = SimpleMarkup.new + mock = MockOutput.new + + block = p.convert(str, mock) + + if block != expected + rows = (0...([expected.size, block.size].max)).collect{|i| + [expected[i]||"nil", block[i]||"nil"] + } + printf "\n\n%35s %35s\n", "Expected", "Got" + rows.each {|e,g| printf "%35s %35s\n", e.dump, g.dump } + end + + assert_equal(expected, block) + end + + def test_tabs + str = "hello\n dave" + assert_equal(str, basic_conv(str)) + str = "hello\n\tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = "hello\n \tdave" + assert_equal("hello\n dave", basic_conv(str)) + str = ".\t\t." + assert_equal(". .", basic_conv(str)) + end + + def test_whitespace + assert_equal("hello", basic_conv("hello")) + assert_equal("hello", basic_conv(" hello ")) + assert_equal("hello", basic_conv(" \t \t hello\t\t")) + + assert_equal("1\n 2\n 3", basic_conv("1\n 2\n 3")) + assert_equal("1\n 2\n 3", basic_conv(" 1\n 2\n 3")) + + assert_equal("1\n 2\n 3\n1\n 2", basic_conv("1\n 2\n 3\n1\n 2")) + assert_equal("1\n 2\n 3\n1\n 2", basic_conv(" 1\n 2\n 3\n 1\n 2")) + + assert_equal("1\n 2\n\n 3", basic_conv(" 1\n 2\n\n 3")) + end + + def test_types + str = "now is the time" + line_types(str, 'P') + + str = "now is the time\nfor all good men" + line_types(str, 'PP') + + str = "now is the time\n code\nfor all good men" + line_types(str, 'PVP') + + str = "now is the time\n code\n more code\nfor all good men" + line_types(str, 'PVVP') + + str = "now is\n---\nthe time" + line_types(str, 'PRP') + + str = %{\ + now is + * l1 + * l2 + the time} + line_types(str, 'PLLP') + + str = %{\ + now is + * l1 + l1+ + * l2 + the time} + line_types(str, 'PLPLP') + + str = %{\ + now is + * l1 + * l1.1 + * l2 + the time} + line_types(str, 'PLLLP') + + str = %{\ + now is + * l1 + * l1.1 + text + code + code + + text + * l2 + the time} + line_types(str, 'PLLPVVBPLP') + + str = %{\ + now is + 1. l1 + * l1.1 + 2. l2 + the time} + line_types(str, 'PLLLP') + + str = %{\ + now is + [cat] l1 + * l1.1 + [dog] l2 + the time} + line_types(str, 'PLLLP') + + str = %{\ + now is + [cat] l1 + continuation + [dog] l2 + the time} + line_types(str, 'PLPLP') + end + + def test_groups + str = "now is the time" + line_groups(str, ["L0: Paragraph\nnow is the time"] ) + + str = "now is the time\nfor all good men" + line_groups(str, ["L0: Paragraph\nnow is the time for all good men"] ) + + str = %{\ + now is the time + code _line_ here + for all good men} + + line_groups(str, + [ "L0: Paragraph\nnow is the time", + "L0: Verbatim\n code _line_ here\n", + "L0: Paragraph\nfor all good men" + ] ) + + str = "now is the time\n code\n more code\nfor all good men" + line_groups(str, + [ "L0: Paragraph\nnow is the time", + "L0: Verbatim\n code\n more code\n", + "L0: Paragraph\nfor all good men" + ] ) + + str = %{\ + now is + * l1 + * l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + str = %{\ + now is + * l1 + l1+ + * l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1 l1+", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + str = %{\ + now is + * l1 + * l1.1 + * l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1", + "L2: ListStart\n", + "L2: ListItem\nl1.1", + "L2: ListEnd\n", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + + str = %{\ + now is + * l1 + * l1.1 + text + code + code + + text + * l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1", + "L2: ListStart\n", + "L2: ListItem\nl1.1 text", + "L2: Verbatim\n code\n code\n", + "L2: Paragraph\ntext", + "L2: ListEnd\n", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + + str = %{\ + now is + 1. l1 + * l1.1 + 2. l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1", + "L2: ListStart\n", + "L2: ListItem\nl1.1", + "L2: ListEnd\n", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + str = %{\ + now is + [cat] l1 + * l1.1 + [dog] l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1", + "L2: ListStart\n", + "L2: ListItem\nl1.1", + "L2: ListEnd\n", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + str = %{\ + now is + [cat] l1 + continuation + [dog] l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1 continuation", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + + end + + def test_verbatim_merge + str = %{\ + now is + code + the time} + + line_groups(str, + [ "L0: Paragraph\nnow is", + "L0: Verbatim\n code\n", + "L0: Paragraph\nthe time" + ]) + + + str = %{\ + now is + code + code1 + the time} + + line_groups(str, + [ "L0: Paragraph\nnow is", + "L0: Verbatim\n code\n code1\n", + "L0: Paragraph\nthe time" + ]) + + + str = %{\ + now is + code + + code1 + the time} + + line_groups(str, + [ "L0: Paragraph\nnow is", + "L0: Verbatim\n code\n\n code1\n", + "L0: Paragraph\nthe time" + ]) + + + str = %{\ + now is + code + + code1 + + the time} + + line_groups(str, + [ "L0: Paragraph\nnow is", + "L0: Verbatim\n code\n\n code1\n", + "L0: Paragraph\nthe time" + ]) + + + str = %{\ + now is + code + + code1 + + code2 + the time} + + line_groups(str, + [ "L0: Paragraph\nnow is", + "L0: Verbatim\n code\n\n code1\n\n code2\n", + "L0: Paragraph\nthe time" + ]) + + + # Folds multiple blank lines + str = %{\ + now is + code + + + code1 + + the time} + + line_groups(str, + [ "L0: Paragraph\nnow is", + "L0: Verbatim\n code\n\n code1\n", + "L0: Paragraph\nthe time" + ]) + + + end + + def test_list_split + str = %{\ + now is + * l1 + 1. n1 + 2. n2 + * l2 + the time} + line_groups(str, + [ "L0: Paragraph\nnow is", + "L1: ListStart\n", + "L1: ListItem\nl1", + "L1: ListEnd\n", + "L1: ListStart\n", + "L1: ListItem\nn1", + "L1: ListItem\nn2", + "L1: ListEnd\n", + "L1: ListStart\n", + "L1: ListItem\nl2", + "L1: ListEnd\n", + "L0: Paragraph\nthe time" + ]) + + end + + + def test_headings + str = "= heading one" + line_groups(str, + [ "L0: Heading\nheading one" + ]) + + str = "=== heading three" + line_groups(str, + [ "L0: Heading\nheading three" + ]) + + str = "text\n === heading three" + line_groups(str, + [ "L0: Paragraph\ntext", + "L0: Verbatim\n === heading three\n" + ]) + + str = "text\n code\n === heading three" + line_groups(str, + [ "L0: Paragraph\ntext", + "L0: Verbatim\n code\n === heading three\n" + ]) + + str = "text\n code\n=== heading three" + line_groups(str, + [ "L0: Paragraph\ntext", + "L0: Verbatim\n code\n", + "L0: Heading\nheading three" + ]) + + end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/options.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/options.rb new file mode 100644 index 00000000..bea7e6bd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/options.rb @@ -0,0 +1,586 @@ +# We handle the parsing of options, and subsequently as a singleton +# object to be queried for option values + +require "rdoc/ri/ri_paths" + +class Options + + require 'singleton' + require 'getoptlong' + + include Singleton + + # files matching this pattern will be excluded + attr_accessor :exclude + + # the name of the output directory + attr_accessor :op_dir + + # the name to use for the output + attr_reader :op_name + + # include private and protected methods in the + # output + attr_accessor :show_all + + # name of the file, class or module to display in + # the initial index page (if not specified + # the first file we encounter is used) + attr_accessor :main_page + + # merge into classes of the name name when generating ri + attr_reader :merge + + # Don't display progress as we process the files + attr_reader :quiet + + # description of the output generator (set with the -fmt + # option + attr_accessor :generator + + # and the list of files to be processed + attr_reader :files + + # array of directories to search for files to satisfy an :include: + attr_reader :rdoc_include + + # title to be used out the output + #attr_writer :title + + # template to be used when generating output + attr_reader :template + + # should diagrams be drawn + attr_reader :diagram + + # should we draw fileboxes in diagrams + attr_reader :fileboxes + + # include the '#' at the front of hyperlinked instance method names + attr_reader :show_hash + + # image format for diagrams + attr_reader :image_format + + # character-set + attr_reader :charset + + # should source code be included inline, or displayed in a popup + attr_reader :inline_source + + # should the output be placed into a single file + attr_reader :all_one_file + + # the number of columns in a tab + attr_reader :tab_width + + # include line numbers in the source listings + attr_reader :include_line_numbers + + # pattern for additional attr_... style methods + attr_reader :extra_accessors + attr_reader :extra_accessor_flags + + # URL of stylesheet + attr_reader :css + + # URL of web cvs frontend + attr_reader :webcvs + + # Are we promiscuous about showing module contents across + # multiple files + attr_reader :promiscuous + + # scan newer sources than the flag file if true. + attr_reader :force_update + + module OptionList + + OPTION_LIST = [ + [ "--accessor", "-A", "accessorname[,..]", + "comma separated list of additional class methods\n" + + "that should be treated like 'attr_reader' and\n" + + "friends. Option may be repeated. Each accessorname\n" + + "may have '=text' appended, in which case that text\n" + + "appears where the r/w/rw appears for normal accessors."], + + [ "--all", "-a", nil, + "include all methods (not just public)\nin the output" ], + + [ "--charset", "-c", "charset", + "specifies HTML character-set" ], + + [ "--debug", "-D", nil, + "displays lots on internal stuff" ], + + [ "--diagram", "-d", nil, + "Generate diagrams showing modules and classes.\n" + + "You need dot V1.8.6 or later to use the --diagram\n" + + "option correctly. Dot is available from\n"+ + "http://www.research.att.com/sw/tools/graphviz/" ], + + [ "--exclude", "-x", "pattern", + "do not process files or directories matching\n" + + "pattern. Files given explicitly on the command\n" + + "line will never be excluded." ], + + [ "--extension", "-E", "new=old", + "Treat files ending with .new as if they ended with\n" + + ".old. Using '-E cgi=rb' will cause xxx.cgi to be\n" + + "parsed as a Ruby file"], + + [ "--fileboxes", "-F", nil, + "classes are put in boxes which represents\n" + + "files, where these classes reside. Classes\n" + + "shared between more than one file are\n" + + "shown with list of files that sharing them.\n" + + "Silently discarded if --diagram is not given\n" + + "Experimental." ], + + [ "--force-update", "-U", nil, + "forces to scan all sources even if newer than\n" + + "the flag file." ], + + [ "--fmt", "-f", "format name", + "set the output formatter (see below)" ], + + [ "--help", "-h", nil, + "you're looking at it" ], + + [ "--help-output", "-O", nil, + "explain the various output options" ], + + [ "--image-format", "-I", "gif/png/jpg/jpeg", + "Sets output image format for diagrams. Can\n" + + "be png, gif, jpeg, jpg. If this option is\n" + + "omitted, png is used. Requires --diagram." ], + + [ "--include", "-i", "dir[,dir...]", + "set (or add to) the list of directories\n" + + "to be searched when satisfying :include:\n" + + "requests. Can be used more than once." ], + + [ "--inline-source", "-S", nil, + "Show method source code inline, rather\n" + + "than via a popup link" ], + + [ "--line-numbers", "-N", nil, + "Include line numbers in the source code" ], + + [ "--main", "-m", "name", + "'name' will be the initial page displayed" ], + + [ "--merge", "-M", nil, + "when creating ri output, merge processed classes\n" + + "into previously documented classes of the name name"], + + [ "--one-file", "-1", nil, + "put all the output into a single file" ], + + [ "--op", "-o", "dir", + "set the output directory" ], + + [ "--opname", "-n", "name", + "Set the 'name' of the output. Has no\n" + + "effect for HTML." ], + + [ "--promiscuous", "-p", nil, + "When documenting a file that contains a module\n" + + "or class also defined in other files, show\n" + + "all stuff for that module/class in each files\n" + + "page. By default, only show stuff defined in\n" + + "that particular file." ], + + [ "--quiet", "-q", nil, + "don't show progress as we parse" ], + + [ "--ri", "-r", nil, + "generate output for use by 'ri.' The files are\n" + + "stored in the '.rdoc' directory under your home\n"+ + "directory unless overridden by a subsequent\n" + + "--op parameter, so no special privileges are needed." ], + + [ "--ri-site", "-R", nil, + "generate output for use by 'ri.' The files are\n" + + "stored in a site-wide directory, making them accessible\n"+ + "to others, so special privileges are needed." ], + + [ "--ri-system", "-Y", nil, + "generate output for use by 'ri.' The files are\n" + + "stored in a system-level directory, making them accessible\n"+ + "to others, so special privileges are needed. This option\n"+ + "is intended to be used during Ruby installations" ], + + [ "--show-hash", "-H", nil, + "A name of the form #name in a comment\n" + + "is a possible hyperlink to an instance\n" + + "method name. When displayed, the '#' is\n" + + "removed unless this option is specified" ], + + [ "--style", "-s", "stylesheet url", + "specifies the URL of a separate stylesheet." ], + + [ "--tab-width", "-w", "n", + "Set the width of tab characters (default 8)"], + + [ "--template", "-T", "template name", + "Set the template used when generating output" ], + + [ "--title", "-t", "text", + "Set 'txt' as the title for the output" ], + + [ "--version", "-v", nil, + "display RDoc's version" ], + + [ "--webcvs", "-W", "url", + "Specify a URL for linking to a web frontend\n" + + "to CVS. If the URL contains a '\%s', the\n" + + "name of the current file will be substituted;\n" + + "if the URL doesn't contain a '\%s', the\n" + + "filename will be appended to it." ], + ] + + def OptionList.options + OPTION_LIST.map do |long, short, arg,| + [ long, + short, + arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT + ] + end + end + + + def OptionList.strip_output(text) + text =~ /^\s+/ + leading_spaces = $& + text.gsub!(/^#{leading_spaces}/, '') + $stdout.puts text + end + + + # Show an error and exit + + def OptionList.error(msg) + $stderr.puts + $stderr.puts msg + $stderr.puts "\nFor help on options, try 'rdoc --help'\n\n" + exit 1 + end + + # Show usage and exit + + def OptionList.usage(generator_names) + + puts + puts(VERSION_STRING) + puts + + name = File.basename($0) + OptionList.strip_output(<<-EOT) + Usage: + + #{name} [options] [names...] + + Files are parsed, and the information they contain + collected, before any output is produced. This allows cross + references between all files to be resolved. If a name is a + directory, it is traversed. If no names are specified, all + Ruby files in the current directory (and subdirectories) are + processed. + + Options: + + EOT + + OPTION_LIST.each do |long, short, arg, desc| + opt = sprintf("%20s", "#{long}, #{short}") + oparg = sprintf("%-7s", arg) + print "#{opt} #{oparg}" + desc = desc.split("\n") + if arg.nil? || arg.length < 7 + puts desc.shift + else + puts + end + desc.each do |line| + puts(" "*28 + line) + end + puts + end + + puts "\nAvailable output formatters: " + + generator_names.sort.join(', ') + "\n\n" + + puts "For information on where the output goes, use\n\n" + puts " rdoc --help-output\n\n" + + exit 0 + end + + def OptionList.help_output + OptionList.strip_output(<<-EOT) + How RDoc generates output depends on the output formatter being + used, and on the options you give. + + - HTML output is normally produced into a number of separate files + (one per class, module, and file, along with various indices). + These files will appear in the directory given by the --op + option (doc/ by default). + + - XML output by default is written to standard output. If a + --opname option is given, the output will instead be written + to a file with that name in the output directory. + + - .chm files (Windows help files) are written in the --op directory. + If an --opname parameter is present, that name is used, otherwise + the file will be called rdoc.chm. + + For information on other RDoc options, use "rdoc --help". + EOT + exit 0 + end + end + + # Parse command line options. We're passed a hash containing + # output generators, keyed by the generator name + + def parse(argv, generators) + old_argv = ARGV.dup + begin + ARGV.replace(argv) + @op_dir = "doc" + @op_name = nil + @show_all = false + @main_page = nil + @marge = false + @exclude = [] + @quiet = false + @generator_name = 'html' + @generator = generators[@generator_name] + @rdoc_include = [] + @title = nil + @template = nil + @diagram = false + @fileboxes = false + @show_hash = false + @image_format = 'png' + @inline_source = false + @all_one_file = false + @tab_width = 8 + @include_line_numbers = false + @extra_accessor_flags = {} + @promiscuous = false + @force_update = false + + @css = nil + @webcvs = nil + + @charset = case $KCODE + when /^S/i + 'Shift_JIS' + when /^E/i + 'EUC-JP' + else + 'iso-8859-1' + end + + accessors = [] + + go = GetoptLong.new(*OptionList.options) + go.quiet = true + + go.each do |opt, arg| + case opt + when "--all" then @show_all = true + when "--charset" then @charset = arg + when "--debug" then $DEBUG = true + when "--exclude" then @exclude << Regexp.new(arg) + when "--inline-source" then @inline_source = true + when "--line-numbers" then @include_line_numbers = true + when "--main" then @main_page = arg + when "--merge" then @merge = true + when "--one-file" then @all_one_file = @inline_source = true + when "--op" then @op_dir = arg + when "--opname" then @op_name = arg + when "--promiscuous" then @promiscuous = true + when "--quiet" then @quiet = true + when "--show-hash" then @show_hash = true + when "--style" then @css = arg + when "--template" then @template = arg + when "--title" then @title = arg + when "--webcvs" then @webcvs = arg + + when "--accessor" + arg.split(/,/).each do |accessor| + if accessor =~ /^(\w+)(=(.*))?$/ + accessors << $1 + @extra_accessor_flags[$1] = $3 + end + end + + when "--diagram" + check_diagram + @diagram = true + + when "--fileboxes" + @fileboxes = true if @diagram + + when "--fmt" + @generator_name = arg.downcase + setup_generator(generators) + + when "--help" + OptionList.usage(generators.keys) + + when "--help-output" + OptionList.help_output + + when "--image-format" + if ['gif', 'png', 'jpeg', 'jpg'].include?(arg) + @image_format = arg + else + raise GetoptLong::InvalidOption.new("unknown image format: #{arg}") + end + + when "--include" + @rdoc_include.concat arg.split(/\s*,\s*/) + + when "--ri", "--ri-site", "--ri-system" + @generator_name = "ri" + @op_dir = case opt + when "--ri" then RI::Paths::HOMEDIR + when "--ri-site" then RI::Paths::SITEDIR + when "--ri-system" then RI::Paths::SYSDIR + else fail opt + end + setup_generator(generators) + + when "--tab-width" + begin + @tab_width = Integer(arg) + rescue + $stderr.puts "Invalid tab width: '#{arg}'" + exit 1 + end + + when "--extension" + new, old = arg.split(/=/, 2) + OptionList.error("Invalid parameter to '-E'") unless new && old + unless RDoc::ParserFactory.alias_extension(old, new) + OptionList.error("Unknown extension .#{old} to -E") + end + + when "--force-update" + @force_update = true + + when "--version" + puts VERSION_STRING + exit + end + + end + + @files = ARGV.dup + + @rdoc_include << "." if @rdoc_include.empty? + + if @exclude.empty? + @exclude = nil + else + @exclude = Regexp.new(@exclude.join("|")) + end + + check_files + + # If no template was specified, use the default + # template for the output formatter + + @template ||= @generator_name + + # Generate a regexp from the accessors + unless accessors.empty? + re = '^(' + accessors.map{|a| Regexp.quote(a)}.join('|') + ')$' + @extra_accessors = Regexp.new(re) + end + + rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error + OptionList.error(error.message) + + ensure + ARGV.replace(old_argv) + end + end + + + def title + @title ||= "RDoc Documentation" + end + + # Set the title, but only if not already set. This means that a title set from + # the command line trumps one set in a source file + + def title=(string) + @title ||= string + end + + + private + + # Set up an output generator for the format in @generator_name + def setup_generator(generators) + @generator = generators[@generator_name] + if !@generator + OptionList.error("Invalid output formatter") + end + + if @generator_name == "xml" + @all_one_file = true + @inline_source = true + end + end + + # Check that the right version of 'dot' is available. + # Unfortuately this doesn't work correctly under Windows NT, + # so we'll bypass the test under Windows + + def check_diagram + return if RUBY_PLATFORM =~ /win/ + + ok = false + ver = nil + IO.popen("dot -V 2>&1") do |io| + ver = io.read + if ver =~ /dot.+version(?:\s+gviz)?\s+(\d+)\.(\d+)/ + ok = ($1.to_i > 1) || ($1.to_i == 1 && $2.to_i >= 8) + end + end + unless ok + if ver =~ /^dot.+version/ + $stderr.puts "Warning: You may need dot V1.8.6 or later to use\n", + "the --diagram option correctly. You have:\n\n ", + ver, + "\nDiagrams might have strange background colors.\n\n" + else + $stderr.puts "You need the 'dot' program to produce diagrams.", + "(see http://www.research.att.com/sw/tools/graphviz/)\n\n" + exit + end +# exit + end + end + + # Check that the files on the command line exist + + def check_files + @files.each do |f| + stat = File.stat f rescue error("File not found: #{f}") + error("File '#{f}' not readable") unless stat.readable? + end + end + + def error(str) + $stderr.puts str + exit(1) + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_c.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_c.rb new file mode 100644 index 00000000..25fc66af --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_c.rb @@ -0,0 +1,773 @@ +# Classes and modules built in to the interpreter. We need +# these to define superclasses of user objects + +require "rdoc/code_objects" +require "rdoc/parsers/parserfactory" +require "rdoc/options" +require "rdoc/rdoc" + +module RDoc + + ## + # Ruby's built-in classes. + + KNOWN_CLASSES = { + "rb_cObject" => "Object", + "rb_cArray" => "Array", + "rb_cBignum" => "Bignum", + "rb_cClass" => "Class", + "rb_cDir" => "Dir", + "rb_cData" => "Data", + "rb_cFalseClass" => "FalseClass", + "rb_cFile" => "File", + "rb_cFixnum" => "Fixnum", + "rb_cFloat" => "Float", + "rb_cHash" => "Hash", + "rb_cInteger" => "Integer", + "rb_cIO" => "IO", + "rb_cModule" => "Module", + "rb_cNilClass" => "NilClass", + "rb_cNumeric" => "Numeric", + "rb_cProc" => "Proc", + "rb_cRange" => "Range", + "rb_cRegexp" => "Regexp", + "rb_cString" => "String", + "rb_cSymbol" => "Symbol", + "rb_cThread" => "Thread", + "rb_cTime" => "Time", + "rb_cTrueClass" => "TrueClass", + "rb_cStruct" => "Struct", + "rb_eException" => "Exception", + "rb_eStandardError" => "StandardError", + "rb_eSystemExit" => "SystemExit", + "rb_eInterrupt" => "Interrupt", + "rb_eSignal" => "Signal", + "rb_eFatal" => "Fatal", + "rb_eArgError" => "ArgError", + "rb_eEOFError" => "EOFError", + "rb_eIndexError" => "IndexError", + "rb_eRangeError" => "RangeError", + "rb_eIOError" => "IOError", + "rb_eRuntimeError" => "RuntimeError", + "rb_eSecurityError" => "SecurityError", + "rb_eSystemCallError" => "SystemCallError", + "rb_eTypeError" => "TypeError", + "rb_eZeroDivError" => "ZeroDivError", + "rb_eNotImpError" => "NotImpError", + "rb_eNoMemError" => "NoMemError", + "rb_eFloatDomainError" => "FloatDomainError", + "rb_eScriptError" => "ScriptError", + "rb_eNameError" => "NameError", + "rb_eSyntaxError" => "SyntaxError", + "rb_eLoadError" => "LoadError", + + "rb_mKernel" => "Kernel", + "rb_mComparable" => "Comparable", + "rb_mEnumerable" => "Enumerable", + "rb_mPrecision" => "Precision", + "rb_mErrno" => "Errno", + "rb_mFileTest" => "FileTest", + "rb_mGC" => "GC", + "rb_mMath" => "Math", + "rb_mProcess" => "Process" + } + + ## + # We attempt to parse C extension files. Basically we look for + # the standard patterns that you find in extensions: rb_define_class, + # rb_define_method and so on. We also try to find the corresponding + # C source for the methods and extract comments, but if we fail + # we don't worry too much. + # + # The comments associated with a Ruby method are extracted from the C + # comment block associated with the routine that _implements_ that + # method, that is to say the method whose name is given in the + # rb_define_method call. For example, you might write: + # + # /* + # * Returns a new array that is a one-dimensional flattening of this + # * array (recursively). That is, for every element that is an array, + # * extract its elements into the new array. + # * + # * s = [ 1, 2, 3 ] #=> [1, 2, 3] + # * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] + # * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] + # * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + # */ + # static VALUE + # rb_ary_flatten(ary) + # VALUE ary; + # { + # ary = rb_obj_dup(ary); + # rb_ary_flatten_bang(ary); + # return ary; + # } + # + # ... + # + # void + # Init_Array() + # { + # ... + # rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0); + # + # Here RDoc will determine from the rb_define_method line that there's a + # method called "flatten" in class Array, and will look for the implementation + # in the method rb_ary_flatten. It will then use the comment from that + # method in the HTML output. This method must be in the same source file + # as the rb_define_method. + # + # C classes can be diagramed (see /tc/dl/ruby/ruby/error.c), and RDoc + # integrates C and Ruby source into one tree + # + # The comment blocks may include special direcives: + # + # [Document-class: name] + # This comment block is documentation for the given class. Use this + # when the Init_xxx method is not named after the class. + # + # [Document-method: name] + # This comment documents the named method. Use when RDoc cannot + # automatically find the method from it's declaration + # + # [call-seq: text up to an empty line] + # Because C source doesn't give descripive names to Ruby-level parameters, + # you need to document the calling sequence explicitly + # + # In additon, RDoc assumes by default that the C method implementing a + # Ruby function is in the same source file as the rb_define_method call. + # If this isn't the case, add the comment + # + # rb_define_method(....); // in: filename + # + # As an example, we might have an extension that defines multiple classes + # in its Init_xxx method. We could document them using + # + # + # /* + # * Document-class: MyClass + # * + # * Encapsulate the writing and reading of the configuration + # * file. ... + # */ + # + # /* + # * Document-method: read_value + # * + # * call-seq: + # * cfg.read_value(key) -> value + # * cfg.read_value(key} { |key| } -> value + # * + # * Return the value corresponding to +key+ from the configuration. + # * In the second form, if the key isn't found, invoke the + # * block and return its value. + # */ + # + + class C_Parser + + attr_accessor :progress + + extend ParserFactory + parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/) + + @@known_bodies = {} + + # prepare to parse a C file + def initialize(top_level, file_name, body, options, stats) + @known_classes = KNOWN_CLASSES.dup + @body = handle_tab_width(handle_ifdefs_in(body)) + @options = options + @stats = stats + @top_level = top_level + @classes = Hash.new + @file_dir = File.dirname(file_name) + @progress = $stderr unless options.quiet + end + + # Extract the classes/modules and methods from a C file + # and return the corresponding top-level object + def scan + remove_commented_out_lines + do_classes + do_constants + do_methods + do_includes + do_aliases + @top_level + end + + ####### + private + ####### + + def progress(char) + unless @options.quiet + @progress.print(char) + @progress.flush + end + end + + def warn(msg) + $stderr.puts + $stderr.puts msg + $stderr.flush + end + + def remove_private_comments(comment) + comment.gsub!(/\/?\*--(.*?)\/?\*\+\+/m, '') + comment.sub!(/\/?\*--.*/m, '') + end + + ## + # removes lines that are commented out that might otherwise get picked up + # when scanning for classes and methods + + def remove_commented_out_lines + @body.gsub!(%r{//.*rb_define_}, '//') + end + + def handle_class_module(var_name, class_mod, class_name, parent, in_module) + progress(class_mod[0, 1]) + + parent_name = @known_classes[parent] || parent + + if in_module + enclosure = @classes[in_module] + unless enclosure + if enclosure = @known_classes[in_module] + handle_class_module(in_module, (/^rb_m/ =~ in_module ? "module" : "class"), + enclosure, nil, nil) + enclosure = @classes[in_module] + end + end + unless enclosure + warn("Enclosing class/module '#{in_module}' for " + + "#{class_mod} #{class_name} not known") + return + end + else + enclosure = @top_level + end + + if class_mod == "class" + cm = enclosure.add_class(NormalClass, class_name, parent_name) + @stats.num_classes += 1 + else + cm = enclosure.add_module(NormalModule, class_name) + @stats.num_modules += 1 + end + cm.record_location(enclosure.toplevel) + + find_class_comment(cm.full_name, cm) + @classes[var_name] = cm + @known_classes[var_name] = cm.full_name + end + + ## + # Look for class or module documentation above Init_+class_name+(void), + # in a Document-class +class_name+ (or module) comment or above an + # rb_define_class (or module). If a comment is supplied above a matching + # Init_ and a rb_define_class the Init_ comment is used. + # + # /* + # * This is a comment for Foo + # */ + # Init_Foo(void) { + # VALUE cFoo = rb_define_class("Foo", rb_cObject); + # } + # + # /* + # * Document-class: Foo + # * This is a comment for Foo + # */ + # Init_foo(void) { + # VALUE cFoo = rb_define_class("Foo", rb_cObject); + # } + # + # /* + # * This is a comment for Foo + # */ + # VALUE cFoo = rb_define_class("Foo", rb_cObject); + + def find_class_comment(class_name, class_meth) + comment = nil + if @body =~ %r{((?>/\*.*?\*/\s+)) + (static\s+)?void\s+Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)}xmi + comment = $1 + elsif @body =~ %r{Document-(class|module):\s#{class_name}\s*?\n((?>.*?\*/))}m + comment = $2 + else + if @body =~ /rb_define_(class|module)/m then + class_name = class_name.split("::").last + comments = [] + @body.split(/(\/\*.*?\*\/)\s*?\n/m).each_with_index do |chunk, index| + comments[index] = chunk + if chunk =~ /rb_define_(class|module).*?"(#{class_name})"/m then + comment = comments[index-1] + break + end + end + end + end + class_meth.comment = mangle_comment(comment) if comment + end + + ############################################################ + + def do_classes + @body.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do + |var_name, class_name| + handle_class_module(var_name, "module", class_name, nil, nil) + end + + # The '.' lets us handle SWIG-generated files + @body.scan(/([\w\.]+)\s* = \s*rb_define_class\s* + \( + \s*"(\w+)", + \s*(\w+)\s* + \)/mx) do + + |var_name, class_name, parent| + handle_class_module(var_name, "class", class_name, parent, nil) + end + + @body.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do + |var_name, class_name, parent| + parent = nil if parent == "0" + handle_class_module(var_name, "class", class_name, parent, nil) + end + + @body.scan(/(\w+)\s* = \s*rb_define_module_under\s* + \( + \s*(\w+), + \s*"(\w+)" + \s*\)/mx) do + + |var_name, in_module, class_name| + handle_class_module(var_name, "module", class_name, nil, in_module) + end + + @body.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s* + \( + \s*(\w+), + \s*"(\w+)", + \s*(\w+)\s* + \s*\)/mx) do + + |var_name, in_module, class_name, parent| + handle_class_module(var_name, "class", class_name, parent, in_module) + end + + end + + ########################################################### + + def do_constants + @body.scan(%r{\Wrb_define_ + ( + variable | + readonly_variable | + const | + global_const | + ) + \s*\( + (?:\s*(\w+),)? + \s*"(\w+)", + \s*(.*?)\s*\)\s*; + }xm) do + + |type, var_name, const_name, definition| + var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel" + handle_constants(type, var_name, const_name, definition) + end + end + + ############################################################ + + def do_methods + + @body.scan(%r{rb_define_ + ( + singleton_method | + method | + module_function | + private_method + ) + \s*\(\s*([\w\.]+), + \s*"([^"]+)", + \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, + \s*(-?\w+)\s*\) + (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? + }xm) do + |type, var_name, meth_name, meth_body, param_count, source_file| + #" + + # Ignore top-object and weird struct.c dynamic stuff + next if var_name == "ruby_top_self" + next if var_name == "nstr" + next if var_name == "envtbl" + next if var_name == "argf" # it'd be nice to handle this one + + var_name = "rb_cObject" if var_name == "rb_mKernel" + handle_method(type, var_name, meth_name, + meth_body, param_count, source_file) + end + + @body.scan(%r{rb_define_attr\( + \s*([\w\.]+), + \s*"([^"]+)", + \s*(\d+), + \s*(\d+)\s*\); + }xm) do #" + |var_name, attr_name, attr_reader, attr_writer| + + #var_name = "rb_cObject" if var_name == "rb_mKernel" + handle_attr(var_name, attr_name, + attr_reader.to_i != 0, + attr_writer.to_i != 0) + end + + @body.scan(%r{rb_define_global_function\s*\( + \s*"([^"]+)", + \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, + \s*(-?\w+)\s*\) + (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? + }xm) do #" + |meth_name, meth_body, param_count, source_file| + handle_method("method", "rb_mKernel", meth_name, + meth_body, param_count, source_file) + end + + @body.scan(/define_filetest_function\s*\( + \s*"([^"]+)", + \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, + \s*(-?\w+)\s*\)/xm) do #" + |meth_name, meth_body, param_count| + + handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count) + handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count) + end + end + + ############################################################ + + def do_aliases + @body.scan(%r{rb_define_alias\s*\(\s*(\w+),\s*"([^"]+)",\s*"([^"]+)"\s*\)}m) do + |var_name, new_name, old_name| + @stats.num_methods += 1 + class_name = @known_classes[var_name] || var_name + class_obj = find_class(var_name, class_name) + + class_obj.add_alias(Alias.new("", old_name, new_name, "")) + end + end + + ## + # Adds constant comments. By providing some_value: at the start ofthe + # comment you can override the C value of the comment to give a friendly + # definition. + # + # /* 300: The perfect score in bowling */ + # rb_define_const(cFoo, "PERFECT", INT2FIX(300); + # + # Will override +INT2FIX(300)+ with the value +300+ in the output RDoc. + # Values may include quotes and escaped colons (\:). + + def handle_constants(type, var_name, const_name, definition) + #@stats.num_constants += 1 + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + unless class_obj + warn("Enclosing class/module '#{const_name}' for not known") + return + end + + comment = find_const_comment(type, const_name) + + # In the case of rb_define_const, the definition and comment are in + # "/* definition: comment */" form. The literal ':' and '\' characters + # can be escaped with a backslash. + if type.downcase == 'const' then + elements = mangle_comment(comment).split(':') + if elements.nil? or elements.empty? then + con = Constant.new(const_name, definition, mangle_comment(comment)) + else + new_definition = elements[0..-2].join(':') + if new_definition.empty? then # Default to literal C definition + new_definition = definition + else + new_definition.gsub!("\:", ":") + new_definition.gsub!("\\", '\\') + end + new_definition.sub!(/\A(\s+)/, '') + new_comment = $1.nil? ? elements.last : "#{$1}#{elements.last.lstrip}" + con = Constant.new(const_name, new_definition, + mangle_comment(new_comment)) + end + else + con = Constant.new(const_name, definition, mangle_comment(comment)) + end + + class_obj.add_constant(con) + end + + ## + # Finds a comment matching +type+ and +const_name+ either above the + # comment or in the matching Document- section. + + def find_const_comment(type, const_name) + if @body =~ %r{((?>^\s*/\*.*?\*/\s+)) + rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi + $1 + elsif @body =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m + $1 + else + '' + end + end + + ########################################################### + + def handle_attr(var_name, attr_name, reader, writer) + rw = '' + if reader + #@stats.num_methods += 1 + rw << 'R' + end + if writer + #@stats.num_methods += 1 + rw << 'W' + end + + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + if class_obj + comment = find_attr_comment(attr_name) + unless comment.empty? + comment = mangle_comment(comment) + end + att = Attr.new('', attr_name, rw, comment) + class_obj.add_attribute(att) + end + + end + + ########################################################### + + def find_attr_comment(attr_name) + if @body =~ %r{((?>/\*.*?\*/\s+)) + rb_define_attr\((?:\s*(\w+),)?\s*"#{attr_name}"\s*,.*?\)\s*;}xmi + $1 + elsif @body =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m + $1 + else + '' + end + end + + ########################################################### + + def handle_method(type, var_name, meth_name, + meth_body, param_count, source_file = nil) + progress(".") + + @stats.num_methods += 1 + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + if class_obj + if meth_name == "initialize" + meth_name = "new" + type = "singleton_method" + end + meth_obj = AnyMethod.new("", meth_name) + meth_obj.singleton = + %w{singleton_method module_function}.include?(type) + + p_count = (Integer(param_count) rescue -1) + + if p_count < 0 + meth_obj.params = "(...)" + elsif p_count == 0 + meth_obj.params = "()" + else + meth_obj.params = "(" + + (1..p_count).map{|i| "p#{i}"}.join(", ") + + ")" + end + + if source_file + file_name = File.join(@file_dir, source_file) + body = (@@known_bodies[source_file] ||= File.read(file_name)) + else + body = @body + end + if find_body(meth_body, meth_obj, body) and meth_obj.document_self + class_obj.add_method(meth_obj) + end + end + end + + ############################################################ + + # Find the C code corresponding to a Ruby method + def find_body(meth_name, meth_obj, body, quiet = false) + case body + when %r{((?>/\*.*?\*/\s*))(?:static\s+)?VALUE\s+#{meth_name} + \s*(\(.*?\)).*?^}xm + comment, params = $1, $2 + body_text = $& + + remove_private_comments(comment) if comment + + # see if we can find the whole body + + re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}' + if Regexp.new(re, Regexp::MULTILINE).match(body) + body_text = $& + end + + # The comment block may have been overridden with a + # 'Document-method' block. This happens in the interpreter + # when multiple methods are vectored through to the same + # C method but those methods are logically distinct (for + # example Kernel.hash and Kernel.object_id share the same + # implementation + + override_comment = find_override_comment(meth_obj.name) + comment = override_comment if override_comment + + find_modifiers(comment, meth_obj) if comment + +# meth_obj.params = params + meth_obj.start_collecting_tokens + meth_obj.add_token(RubyToken::Token.new(1,1).set_text(body_text)) + meth_obj.comment = mangle_comment(comment) + when %r{((?>/\*.*?\*/\s*))^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m + comment = $1 + find_body($2, meth_obj, body, true) + find_modifiers(comment, meth_obj) + meth_obj.comment = mangle_comment(comment) + meth_obj.comment + when %r{^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m + unless find_body($1, meth_obj, body, true) + warn "No definition for #{meth_name}" unless quiet + return false + end + else + + # No body, but might still have an override comment + comment = find_override_comment(meth_obj.name) + + if comment + find_modifiers(comment, meth_obj) + meth_obj.comment = mangle_comment(comment) + else + warn "No definition for #{meth_name}" unless quiet + return false + end + end + true + end + + + ## + # If the comment block contains a section that looks like: + # + # call-seq: + # Array.new + # Array.new(10) + # + # use it for the parameters. + + def find_modifiers(comment, meth_obj) + if comment.sub!(/:nodoc:\s*^\s*\*?\s*$/m, '') or + comment.sub!(/\A\/\*\s*:nodoc:\s*\*\/\Z/, '') + meth_obj.document_self = false + end + if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') or + comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') + seq = $1 + seq.gsub!(/^\s*\*\s*/, '') + meth_obj.call_seq = seq + end + end + + ############################################################ + + def find_override_comment(meth_name) + name = Regexp.escape(meth_name) + if @body =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m + $1 + end + end + + ## + # Look for includes of the form: + # + # rb_include_module(rb_cArray, rb_mEnumerable); + + def do_includes + @body.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m| + if cls = @classes[c] + m = @known_classes[m] || m + cls.add_include(Include.new(m, "")) + end + end + end + + ## + # Remove the /*'s and leading asterisks from C comments + + def mangle_comment(comment) + comment.sub!(%r{/\*+}) { " " * $&.length } + comment.sub!(%r{\*+/}) { " " * $&.length } + comment.gsub!(/^[ \t]*\*/m) { " " * $&.length } + comment + end + + def find_class(raw_name, name) + unless @classes[raw_name] + if raw_name =~ /^rb_m/ + @classes[raw_name] = @top_level.add_module(NormalModule, name) + else + @classes[raw_name] = @top_level.add_class(NormalClass, name, nil) + end + end + @classes[raw_name] + end + + def handle_tab_width(body) + if /\t/ =~ body + tab_width = Options.instance.tab_width + body.split(/\n/).map do |line| + 1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #` + line + end .join("\n") + else + body + end + end + + ## + # Removes #ifdefs that would otherwise confuse us + + def handle_ifdefs_in(body) + body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m) { $1 } + end + + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_f95.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_f95.rb new file mode 100644 index 00000000..f3f6d761 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_f95.rb @@ -0,0 +1,1841 @@ +#= parse_f95.rb - Fortran95 Parser +# +#== Overview +# +#"parse_f95.rb" parses Fortran95 files with suffixes "f90", "F90", "f95" +#and "F95". Fortran95 files are expected to be conformed to Fortran95 +#standards. +# +#== Rules +# +#Fundamental rules are same as that of the Ruby parser. +#But comment markers are '!' not '#'. +# +#=== Correspondence between RDoc documentation and Fortran95 programs +# +#"parse_f95.rb" parses main programs, modules, subroutines, functions, +#derived-types, public variables, public constants, +#defined operators and defined assignments. +#These components are described in items of RDoc documentation, as follows. +# +#Files :: Files (same as Ruby) +#Classes :: Modules +#Methods :: Subroutines, functions, variables, constants, derived-types, defined operators, defined assignments +#Required files :: Files in which imported modules, external subroutines and external functions are defined. +#Included Modules :: List of imported modules +#Attributes :: List of derived-types, List of imported modules all of whose components are published again +# +#Components listed in 'Methods' (subroutines, functions, ...) +#defined in modules are described in the item of 'Classes'. +#On the other hand, components defined in main programs or +#as external procedures are described in the item of 'Files'. +# +#=== Components parsed by default +# +#By default, documentation on public components (subroutines, functions, +#variables, constants, derived-types, defined operators, +#defined assignments) are generated. +#With "--all" option, documentation on all components +#are generated (almost same as the Ruby parser). +# +#=== Information parsed automatically +# +#The following information is automatically parsed. +# +#* Types of arguments +#* Types of variables and constants +#* Types of variables in the derived types, and initial values +#* NAMELISTs and types of variables in them, and initial values +# +#Aliases by interface statement are described in the item of 'Methods'. +# +#Components which are imported from other modules and published again +#are described in the item of 'Methods'. +# +#=== Format of comment blocks +# +#Comment blocks should be written as follows. +#Comment blocks are considered to be ended when the line without '!' +#appears. +#The indentation is not necessary. +# +# ! (Top of file) +# ! +# ! Comment blocks for the files. +# ! +# !-- +# ! The comment described in the part enclosed by +# ! "!--" and "!++" is ignored. +# !++ +# ! +# module hogehoge +# ! +# ! Comment blocks for the modules (or the programs). +# ! +# +# private +# +# logical :: a ! a private variable +# real, public :: b ! a public variable +# integer, parameter :: c = 0 ! a public constant +# +# public :: c +# public :: MULTI_ARRAY +# public :: hoge, foo +# +# type MULTI_ARRAY +# ! +# ! Comment blocks for the derived-types. +# ! +# real, pointer :: var(:) =>null() ! Comments block for the variables. +# integer :: num = 0 +# end type MULTI_ARRAY +# +# contains +# +# subroutine hoge( in, & ! Comment blocks between continuation lines are ignored. +# & out ) +# ! +# ! Comment blocks for the subroutines or functions +# ! +# character(*),intent(in):: in ! Comment blocks for the arguments. +# character(*),intent(out),allocatable,target :: in +# ! Comment blocks can be +# ! written under Fortran statements. +# +# character(32) :: file ! This comment parsed as a variable in below NAMELIST. +# integer :: id +# +# namelist /varinfo_nml/ file, id +# ! +# ! Comment blocks for the NAMELISTs. +# ! Information about variables are described above. +# ! +# +# .... +# +# end subroutine hoge +# +# integer function foo( in ) +# ! +# ! This part is considered as comment block. +# +# ! Comment blocks under blank lines are ignored. +# ! +# integer, intent(in):: inA ! This part is considered as comment block. +# +# ! This part is ignored. +# +# end function foo +# +# subroutine hide( in, & +# & out ) !:nodoc: +# ! +# ! If "!:nodoc:" is described at end-of-line in subroutine +# ! statement as above, the subroutine is ignored. +# ! This assignment can be used to modules, subroutines, +# ! functions, variables, constants, derived-types, +# ! defined operators, defined assignments, +# ! list of imported modules ("use" statement). +# ! +# +# .... +# +# end subroutine hide +# +# end module hogehoge +# + + +require "rdoc/code_objects" + +module RDoc + + class Token + + NO_TEXT = "??".freeze + + def initialize(line_no, char_no) + @line_no = line_no + @char_no = char_no + @text = NO_TEXT + end + # Because we're used in contexts that expect to return a token, + # we set the text string and then return ourselves + def set_text(text) + @text = text + self + end + + attr_reader :line_no, :char_no, :text + + end + + # See rdoc/parsers/parse_f95.rb + + class Fortran95parser + + extend ParserFactory + parse_files_matching(/\.((f|F)9(0|5)|F)$/) + + @@external_aliases = [] + @@public_methods = [] + + # "false":: Comments are below source code + # "true" :: Comments are upper source code + COMMENTS_ARE_UPPER = false + + # Internal alias message + INTERNAL_ALIAS_MES = "Alias for" + + # External alias message + EXTERNAL_ALIAS_MES = "The entity is" + + # prepare to parse a Fortran 95 file + def initialize(top_level, file_name, body, options, stats) + @body = body + @stats = stats + @file_name = file_name + @options = options + @top_level = top_level + @progress = $stderr unless options.quiet + end + + # devine code constructs + def scan + + # remove private comment + remaining_code = remove_private_comments(@body) + + # continuation lines are united to one line + remaining_code = united_to_one_line(remaining_code) + + # semicolons are replaced to line feed + remaining_code = semicolon_to_linefeed(remaining_code) + + # collect comment for file entity + whole_comment, remaining_code = collect_first_comment(remaining_code) + @top_level.comment = whole_comment + + # String "remaining_code" is converted to Array "remaining_lines" + remaining_lines = remaining_code.split("\n") + + # "module" or "program" parts are parsed (new) + # + level_depth = 0 + block_searching_flag = nil + block_searching_lines = [] + pre_comment = [] + module_program_trailing = "" + module_program_name = "" + other_block_level_depth = 0 + other_block_searching_flag = nil + remaining_lines.collect!{|line| + if !block_searching_flag && !other_block_searching_flag + if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i + block_searching_flag = :module + block_searching_lines << line + module_program_name = $1 + module_program_trailing = find_comments($2) + next false + elsif line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i || + line =~ /^\s*?\w/ && !block_start?(line) + block_searching_flag = :program + block_searching_lines << line + module_program_name = $1 || "" + module_program_trailing = find_comments($2) + next false + + elsif block_start?(line) + other_block_searching_flag = true + next line + + elsif line =~ /^\s*?!\s?(.*)/ + pre_comment << line + next line + else + pre_comment = [] + next line + end + elsif other_block_searching_flag + other_block_level_depth += 1 if block_start?(line) + other_block_level_depth -= 1 if block_end?(line) + if other_block_level_depth < 0 + other_block_level_depth = 0 + other_block_searching_flag = nil + end + next line + end + + block_searching_lines << line + level_depth += 1 if block_start?(line) + level_depth -= 1 if block_end?(line) + if level_depth >= 0 + next false + end + + # "module_program_code" is formatted. + # ":nodoc:" flag is checked. + # + module_program_code = block_searching_lines.join("\n") + module_program_code = remove_empty_head_lines(module_program_code) + if module_program_trailing =~ /^:nodoc:/ + # next loop to search next block + level_depth = 0 + block_searching_flag = false + block_searching_lines = [] + pre_comment = [] + next false + end + + # NormalClass is created, and added to @top_level + # + if block_searching_flag == :module + module_name = module_program_name + module_code = module_program_code + module_trailing = module_program_trailing + progress "m" + @stats.num_modules += 1 + f9x_module = @top_level.add_module NormalClass, module_name + f9x_module.record_location @top_level + + f9x_comment = COMMENTS_ARE_UPPER ? + find_comments(pre_comment.join("\n")) + "\n" + module_trailing : + module_trailing + "\n" + find_comments(module_code.sub(/^.*$\n/i, '')) + f9x_module.comment = f9x_comment + parse_program_or_module(f9x_module, module_code) + + TopLevel.all_files.each do |name, toplevel| + if toplevel.include_includes?(module_name, @options.ignore_case) + if !toplevel.include_requires?(@file_name, @options.ignore_case) + toplevel.add_require(Require.new(@file_name, "")) + end + end + toplevel.each_classmodule{|m| + if m.include_includes?(module_name, @options.ignore_case) + if !m.include_requires?(@file_name, @options.ignore_case) + m.add_require(Require.new(@file_name, "")) + end + end + } + end + elsif block_searching_flag == :program + program_name = module_program_name + program_code = module_program_code + program_trailing = module_program_trailing + progress "p" + program_comment = COMMENTS_ARE_UPPER ? + find_comments(pre_comment.join("\n")) + "\n" + program_trailing : + program_trailing + "\n" + find_comments(program_code.sub(/^.*$\n/i, '')) + program_comment = "\n\n= Program #{program_name}\n\n" \ + + program_comment + @top_level.comment << program_comment + parse_program_or_module(@top_level, program_code, :private) + end + + # next loop to search next block + level_depth = 0 + block_searching_flag = false + block_searching_lines = [] + pre_comment = [] + next false + } + + remaining_lines.delete_if{ |line| + line == false + } + + # External subprograms and functions are parsed + # + parse_program_or_module(@top_level, remaining_lines.join("\n"), + :public, true) + + @top_level + end # End of scan + + private + + def parse_program_or_module(container, code, + visibility=:public, external=nil) + return unless container + return unless code + remaining_lines = code.split("\n") + remaining_code = "#{code}" + + # + # Parse variables before "contains" in module + # + level_depth = 0 + before_contains_lines = [] + before_contains_code = nil + before_contains_flag = nil + remaining_lines.each{ |line| + if !before_contains_flag + if line =~ /^\s*?module\s+\w+\s*?(!.*?)?$/i + before_contains_flag = true + end + else + break if line =~ /^\s*?contains\s*?(!.*?)?$/i + level_depth += 1 if block_start?(line) + level_depth -= 1 if block_end?(line) + break if level_depth < 0 + before_contains_lines << line + end + } + before_contains_code = before_contains_lines.join("\n") + if before_contains_code + before_contains_code.gsub!(/^\s*?interface\s+.*?\s+end\s+interface.*?$/im, "") + before_contains_code.gsub!(/^\s*?type[\s\,]+.*?\s+end\s+type.*?$/im, "") + end + + # + # Parse global "use" + # + use_check_code = "#{before_contains_code}" + cascaded_modules_list = [] + while use_check_code =~ /^\s*?use\s+(\w+)(.*?)(!.*?)?$/i + use_check_code = $~.pre_match + use_check_code << $~.post_match + used_mod_name = $1.strip.chomp + used_list = $2 || "" + used_trailing = $3 || "" + next if used_trailing =~ /!:nodoc:/ + if !container.include_includes?(used_mod_name, @options.ignore_case) + progress "." + container.add_include Include.new(used_mod_name, "") + end + if ! (used_list =~ /\,\s*?only\s*?:/i ) + cascaded_modules_list << "\#" + used_mod_name + end + end + + # + # Parse public and private, and store information. + # This information is used when "add_method" and + # "set_visibility_for" are called. + # + visibility_default, visibility_info = + parse_visibility(remaining_lines.join("\n"), visibility, container) + @@public_methods.concat visibility_info + if visibility_default == :public + if !cascaded_modules_list.empty? + cascaded_modules = + Attr.new("Cascaded Modules", + "Imported modules all of whose components are published again", + "", + cascaded_modules_list.join(", ")) + container.add_attribute(cascaded_modules) + end + end + + # + # Check rename elements + # + use_check_code = "#{before_contains_code}" + while use_check_code =~ /^\s*?use\s+(\w+)\s*?\,(.+)$/i + use_check_code = $~.pre_match + use_check_code << $~.post_match + used_mod_name = $1.strip.chomp + used_elements = $2.sub(/\s*?only\s*?:\s*?/i, '') + used_elements.split(",").each{ |used| + if /\s*?(\w+)\s*?=>\s*?(\w+)\s*?/ =~ used + local = $1 + org = $2 + @@public_methods.collect!{ |pub_meth| + if local == pub_meth["name"] || + local.upcase == pub_meth["name"].upcase && + @options.ignore_case + pub_meth["name"] = org + pub_meth["local_name"] = local + end + pub_meth + } + end + } + end + + # + # Parse private "use" + # + use_check_code = remaining_lines.join("\n") + while use_check_code =~ /^\s*?use\s+(\w+)(.*?)(!.*?)?$/i + use_check_code = $~.pre_match + use_check_code << $~.post_match + used_mod_name = $1.strip.chomp + used_trailing = $3 || "" + next if used_trailing =~ /!:nodoc:/ + if !container.include_includes?(used_mod_name, @options.ignore_case) + progress "." + container.add_include Include.new(used_mod_name, "") + end + end + + container.each_includes{ |inc| + TopLevel.all_files.each do |name, toplevel| + indicated_mod = toplevel.find_symbol(inc.name, + nil, @options.ignore_case) + if indicated_mod + indicated_name = indicated_mod.parent.file_relative_name + if !container.include_requires?(indicated_name, @options.ignore_case) + container.add_require(Require.new(indicated_name, "")) + end + break + end + end + } + + # + # Parse derived-types definitions + # + derived_types_comment = "" + remaining_code = remaining_lines.join("\n") + while remaining_code =~ /^\s*? + type[\s\,]+(public|private)?\s*?(::)?\s*? + (\w+)\s*?(!.*?)?$ + (.*?) + ^\s*?end\s+type.*?$ + /imx + remaining_code = $~.pre_match + remaining_code << $~.post_match + typename = $3.chomp.strip + type_elements = $5 || "" + type_code = remove_empty_head_lines($&) + type_trailing = find_comments($4) + next if type_trailing =~ /^:nodoc:/ + type_visibility = $1 + type_comment = COMMENTS_ARE_UPPER ? + find_comments($~.pre_match) + "\n" + type_trailing : + type_trailing + "\n" + find_comments(type_code.sub(/^.*$\n/i, '')) + type_element_visibility_public = true + type_code.split("\n").each{ |line| + if /^\s*?private\s*?$/ =~ line + type_element_visibility_public = nil + break + end + } if type_code + + args_comment = "" + type_args_info = nil + + if @options.show_all + args_comment = find_arguments(nil, type_code, true) + else + type_public_args_list = [] + type_args_info = definition_info(type_code) + type_args_info.each{ |arg| + arg_is_public = type_element_visibility_public + arg_is_public = true if arg.include_attr?("public") + arg_is_public = nil if arg.include_attr?("private") + type_public_args_list << arg.varname if arg_is_public + } + args_comment = find_arguments(type_public_args_list, type_code) + end + + type = AnyMethod.new("type #{typename}", typename) + type.singleton = false + type.params = "" + type.comment = " Derived Type :: \n" + type.comment << args_comment if args_comment + type.comment << type_comment if type_comment + progress "t" + @stats.num_methods += 1 + container.add_method type + + set_visibility(container, typename, visibility_default, @@public_methods) + + if type_visibility + type_visibility.gsub!(/\s/,'') + type_visibility.gsub!(/\,/,'') + type_visibility.gsub!(/:/,'') + type_visibility.downcase! + if type_visibility == "public" + container.set_visibility_for([typename], :public) + elsif type_visibility == "private" + container.set_visibility_for([typename], :private) + end + end + + check_public_methods(type, container.name) + + if @options.show_all + derived_types_comment << ", " unless derived_types_comment.empty? + derived_types_comment << typename + else + if type.visibility == :public + derived_types_comment << ", " unless derived_types_comment.empty? + derived_types_comment << typename + end + end + + end + + if !derived_types_comment.empty? + derived_types_table = + Attr.new("Derived Types", "Derived_Types", "", + derived_types_comment) + container.add_attribute(derived_types_table) + end + + # + # move interface scope + # + interface_code = "" + while remaining_code =~ /^\s*? + interface( + \s+\w+ | + \s+operator\s*?\(.*?\) | + \s+assignment\s*?\(\s*?=\s*?\) + )?\s*?$ + (.*?) + ^\s*?end\s+interface.*?$ + /imx + interface_code << remove_empty_head_lines($&) + "\n" + remaining_code = $~.pre_match + remaining_code << $~.post_match + end + + # + # Parse global constants or variables in modules + # + const_var_defs = definition_info(before_contains_code) + const_var_defs.each{|defitem| + next if defitem.nodoc + const_or_var_type = "Variable" + const_or_var_progress = "v" + if defitem.include_attr?("parameter") + const_or_var_type = "Constant" + const_or_var_progress = "c" + end + const_or_var = AnyMethod.new(const_or_var_type, defitem.varname) + const_or_var.singleton = false + const_or_var.params = "" + self_comment = find_arguments([defitem.varname], before_contains_code) + const_or_var.comment = "" + const_or_var_type + " :: \n" + const_or_var.comment << self_comment if self_comment + progress const_or_var_progress + @stats.num_methods += 1 + container.add_method const_or_var + + set_visibility(container, defitem.varname, visibility_default, @@public_methods) + + if defitem.include_attr?("public") + container.set_visibility_for([defitem.varname], :public) + elsif defitem.include_attr?("private") + container.set_visibility_for([defitem.varname], :private) + end + + check_public_methods(const_or_var, container.name) + + } if const_var_defs + + remaining_lines = remaining_code.split("\n") + + # "subroutine" or "function" parts are parsed (new) + # + level_depth = 0 + block_searching_flag = nil + block_searching_lines = [] + pre_comment = [] + procedure_trailing = "" + procedure_name = "" + procedure_params = "" + procedure_prefix = "" + procedure_result_arg = "" + procedure_type = "" + contains_lines = [] + contains_flag = nil + remaining_lines.collect!{|line| + if !block_searching_flag + # subroutine + if line =~ /^\s*? + (recursive|pure|elemental)?\s*? + subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$ + /ix + block_searching_flag = :subroutine + block_searching_lines << line + + procedure_name = $2.chomp.strip + procedure_params = $3 || "" + procedure_prefix = $1 || "" + procedure_trailing = $4 || "!" + next false + + # function + elsif line =~ /^\s*? + (recursive|pure|elemental)?\s*? + ( + character\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | type\s*?\([\w\s]+?\)\s+ + | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | double\s+precision\s+ + | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + )? + function\s+(\w+)\s*? + (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$ + /ix + block_searching_flag = :function + block_searching_lines << line + + procedure_prefix = $1 || "" + procedure_type = $2 ? $2.chomp.strip : nil + procedure_name = $8.chomp.strip + procedure_params = $9 || "" + procedure_result_arg = $11 ? $11.chomp.strip : procedure_name + procedure_trailing = $12 || "!" + next false + elsif line =~ /^\s*?!\s?(.*)/ + pre_comment << line + next line + else + pre_comment = [] + next line + end + end + contains_flag = true if line =~ /^\s*?contains\s*?(!.*?)?$/ + block_searching_lines << line + contains_lines << line if contains_flag + + level_depth += 1 if block_start?(line) + level_depth -= 1 if block_end?(line) + if level_depth >= 0 + next false + end + + # "procedure_code" is formatted. + # ":nodoc:" flag is checked. + # + procedure_code = block_searching_lines.join("\n") + procedure_code = remove_empty_head_lines(procedure_code) + if procedure_trailing =~ /^!:nodoc:/ + # next loop to search next block + level_depth = 0 + block_searching_flag = nil + block_searching_lines = [] + pre_comment = [] + procedure_trailing = "" + procedure_name = "" + procedure_params = "" + procedure_prefix = "" + procedure_result_arg = "" + procedure_type = "" + contains_lines = [] + contains_flag = nil + next false + end + + # AnyMethod is created, and added to container + # + subroutine_function = nil + if block_searching_flag == :subroutine + subroutine_prefix = procedure_prefix + subroutine_name = procedure_name + subroutine_params = procedure_params + subroutine_trailing = procedure_trailing + subroutine_code = procedure_code + + subroutine_comment = COMMENTS_ARE_UPPER ? + pre_comment.join("\n") + "\n" + subroutine_trailing : + subroutine_trailing + "\n" + subroutine_code.sub(/^.*$\n/i, '') + subroutine = AnyMethod.new("subroutine", subroutine_name) + parse_subprogram(subroutine, subroutine_params, + subroutine_comment, subroutine_code, + before_contains_code, nil, subroutine_prefix) + progress "s" + @stats.num_methods += 1 + container.add_method subroutine + subroutine_function = subroutine + + elsif block_searching_flag == :function + function_prefix = procedure_prefix + function_type = procedure_type + function_name = procedure_name + function_params_org = procedure_params + function_result_arg = procedure_result_arg + function_trailing = procedure_trailing + function_code_org = procedure_code + + function_comment = COMMENTS_ARE_UPPER ? + pre_comment.join("\n") + "\n" + function_trailing : + function_trailing + "\n " + function_code_org.sub(/^.*$\n/i, '') + + function_code = "#{function_code_org}" + if function_type + function_code << "\n" + function_type + " :: " + function_result_arg + end + + function_params = + function_params_org.sub(/^\(/, "\(#{function_result_arg}, ") + + function = AnyMethod.new("function", function_name) + parse_subprogram(function, function_params, + function_comment, function_code, + before_contains_code, true, function_prefix) + + # Specific modification due to function + function.params.sub!(/\(\s*?#{function_result_arg}\s*?,\s*?/, "\( ") + function.params << " result(" + function_result_arg + ")" + function.start_collecting_tokens + function.add_token Token.new(1,1).set_text(function_code_org) + + progress "f" + @stats.num_methods += 1 + container.add_method function + subroutine_function = function + + end + + # The visibility of procedure is specified + # + set_visibility(container, procedure_name, + visibility_default, @@public_methods) + + # The alias for this procedure from external modules + # + check_external_aliases(procedure_name, + subroutine_function.params, + subroutine_function.comment, subroutine_function) if external + check_public_methods(subroutine_function, container.name) + + + # contains_lines are parsed as private procedures + if contains_flag + parse_program_or_module(container, + contains_lines.join("\n"), :private) + end + + # next loop to search next block + level_depth = 0 + block_searching_flag = nil + block_searching_lines = [] + pre_comment = [] + procedure_trailing = "" + procedure_name = "" + procedure_params = "" + procedure_prefix = "" + procedure_result_arg = "" + contains_lines = [] + contains_flag = nil + next false + } # End of remaining_lines.collect!{|line| + + # Array remains_lines is converted to String remains_code again + # + remaining_code = remaining_lines.join("\n") + + # + # Parse interface + # + interface_scope = false + generic_name = "" + interface_code.split("\n").each{ |line| + if /^\s*? + interface( + \s+\w+| + \s+operator\s*?\(.*?\)| + \s+assignment\s*?\(\s*?=\s*?\) + )? + \s*?(!.*?)?$ + /ix =~ line + generic_name = $1 ? $1.strip.chomp : nil + interface_trailing = $2 || "!" + interface_scope = true + interface_scope = false if interface_trailing =~ /!:nodoc:/ +# if generic_name =~ /operator\s*?\((.*?)\)/i +# operator_name = $1 +# if operator_name && !operator_name.empty? +# generic_name = "#{operator_name}" +# end +# end +# if generic_name =~ /assignment\s*?\((.*?)\)/i +# assignment_name = $1 +# if assignment_name && !assignment_name.empty? +# generic_name = "#{assignment_name}" +# end +# end + end + if /^\s*?end\s+interface/i =~ line + interface_scope = false + generic_name = nil + end + # internal alias + if interface_scope && /^\s*?module\s+procedure\s+(.*?)(!.*?)?$/i =~ line + procedures = $1.strip.chomp + procedures_trailing = $2 || "!" + next if procedures_trailing =~ /!:nodoc:/ + procedures.split(",").each{ |proc| + proc.strip! + proc.chomp! + next if generic_name == proc || !generic_name + old_meth = container.find_symbol(proc, nil, @options.ignore_case) + next if !old_meth + nolink = old_meth.visibility == :private ? true : nil + nolink = nil if @options.show_all + new_meth = + initialize_external_method(generic_name, proc, + old_meth.params, nil, + old_meth.comment, + old_meth.clone.token_stream[0].text, + true, nolink) + new_meth.singleton = old_meth.singleton + + progress "i" + @stats.num_methods += 1 + container.add_method new_meth + + set_visibility(container, generic_name, visibility_default, @@public_methods) + + check_public_methods(new_meth, container.name) + + } + end + + # external aliases + if interface_scope + # subroutine + proc = nil + params = nil + procedures_trailing = nil + if line =~ /^\s*? + (recursive|pure|elemental)?\s*? + subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$ + /ix + proc = $2.chomp.strip + generic_name = proc unless generic_name + params = $3 || "" + procedures_trailing = $4 || "!" + + # function + elsif line =~ /^\s*? + (recursive|pure|elemental)?\s*? + ( + character\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | type\s*?\([\w\s]+?\)\s+ + | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | double\s+precision\s+ + | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + )? + function\s+(\w+)\s*? + (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$ + /ix + proc = $8.chomp.strip + generic_name = proc unless generic_name + params = $9 || "" + procedures_trailing = $12 || "!" + else + next + end + next if procedures_trailing =~ /!:nodoc:/ + indicated_method = nil + indicated_file = nil + TopLevel.all_files.each do |name, toplevel| + indicated_method = toplevel.find_local_symbol(proc, @options.ignore_case) + indicated_file = name + break if indicated_method + end + + if indicated_method + external_method = + initialize_external_method(generic_name, proc, + indicated_method.params, + indicated_file, + indicated_method.comment) + + progress "e" + @stats.num_methods += 1 + container.add_method external_method + set_visibility(container, generic_name, visibility_default, @@public_methods) + if !container.include_requires?(indicated_file, @options.ignore_case) + container.add_require(Require.new(indicated_file, "")) + end + check_public_methods(external_method, container.name) + + else + @@external_aliases << { + "new_name" => generic_name, + "old_name" => proc, + "file_or_module" => container, + "visibility" => find_visibility(container, generic_name, @@public_methods) || visibility_default + } + end + end + + } if interface_code # End of interface_code.split("\n").each ... + + # + # Already imported methods are removed from @@public_methods. + # Remainders are assumed to be imported from other modules. + # + @@public_methods.delete_if{ |method| method["entity_is_discovered"]} + + @@public_methods.each{ |pub_meth| + next unless pub_meth["file_or_module"].name == container.name + pub_meth["used_modules"].each{ |used_mod| + TopLevel.all_classes_and_modules.each{ |modules| + if modules.name == used_mod || + modules.name.upcase == used_mod.upcase && + @options.ignore_case + modules.method_list.each{ |meth| + if meth.name == pub_meth["name"] || + meth.name.upcase == pub_meth["name"].upcase && + @options.ignore_case + new_meth = initialize_public_method(meth, + modules.name) + if pub_meth["local_name"] + new_meth.name = pub_meth["local_name"] + end + progress "e" + @stats.num_methods += 1 + container.add_method new_meth + end + } + end + } + } + } + + container + end # End of parse_program_or_module + + # + # Parse arguments, comment, code of subroutine and function. + # Return AnyMethod object. + # + def parse_subprogram(subprogram, params, comment, code, + before_contains=nil, function=nil, prefix=nil) + subprogram.singleton = false + prefix = "" if !prefix + arguments = params.sub(/\(/, "").sub(/\)/, "").split(",") if params + args_comment, params_opt = + find_arguments(arguments, code.sub(/^s*?contains\s*?(!.*?)?$.*/im, ""), + nil, nil, true) + params_opt = "( " + params_opt + " ) " if params_opt + subprogram.params = params_opt || "" + namelist_comment = find_namelists(code, before_contains) + + block_comment = find_comments comment + if function + subprogram.comment = " Function :: #{prefix}\n" + else + subprogram.comment = " Subroutine :: #{prefix}\n" + end + subprogram.comment << args_comment if args_comment + subprogram.comment << block_comment if block_comment + subprogram.comment << namelist_comment if namelist_comment + + # For output source code + subprogram.start_collecting_tokens + subprogram.add_token Token.new(1,1).set_text(code) + + subprogram + end + + # + # Collect comment for file entity + # + def collect_first_comment(body) + comment = "" + not_comment = "" + comment_start = false + comment_end = false + body.split("\n").each{ |line| + if comment_end + not_comment << line + not_comment << "\n" + elsif /^\s*?!\s?(.*)$/i =~ line + comment_start = true + comment << $1 + comment << "\n" + elsif /^\s*?$/i =~ line + comment_end = true if comment_start && COMMENTS_ARE_UPPER + else + comment_end = true + not_comment << line + not_comment << "\n" + end + } + return comment, not_comment + end + + + # Return comments of definitions of arguments + # + # If "all" argument is true, information of all arguments are returned. + # If "modified_params" is true, list of arguments are decorated, + # for exameple, optional arguments are parenthetic as "[arg]". + # + def find_arguments(args, text, all=nil, indent=nil, modified_params=nil) + return unless args || all + indent = "" unless indent + args = ["all"] if all + params = "" if modified_params + comma = "" + return unless text + args_rdocforms = "\n" + remaining_lines = "#{text}" + definitions = definition_info(remaining_lines) + args.each{ |arg| + arg.strip! + arg.chomp! + definitions.each { |defitem| + if arg == defitem.varname.strip.chomp || all + args_rdocforms << <<-"EOF" + +#{indent}#{defitem.varname.chomp.strip}#{defitem.arraysuffix} #{defitem.inivalue} :: +#{indent} #{defitem.types.chomp.strip} +EOF + if !defitem.comment.chomp.strip.empty? + comment = "" + defitem.comment.split("\n").each{ |line| + comment << " " + line + "\n" + } + args_rdocforms << <<-"EOF" + +#{indent} :: +#{indent} +#{indent} #{comment.chomp.strip} +EOF + end + + if modified_params + if defitem.include_attr?("optional") + params << "#{comma}[#{arg}]" + else + params << "#{comma}#{arg}" + end + comma = ", " + end + end + } + } + if modified_params + return args_rdocforms, params + else + return args_rdocforms + end + end + + # Return comments of definitions of namelists + # + def find_namelists(text, before_contains=nil) + return nil if !text + result = "" + lines = "#{text}" + before_contains = "" if !before_contains + while lines =~ /^\s*?namelist\s+\/\s*?(\w+)\s*?\/([\s\w\,]+)$/i + lines = $~.post_match + nml_comment = COMMENTS_ARE_UPPER ? + find_comments($~.pre_match) : find_comments($~.post_match) + nml_name = $1 + nml_args = $2.split(",") + result << "\n\n=== NAMELIST " + nml_name + "\n\n" + result << nml_comment + "\n" if nml_comment + if lines.split("\n")[0] =~ /^\//i + lines = "namelist " + lines + end + result << find_arguments(nml_args, "#{text}" + "\n" + before_contains) + end + return result + end + + # + # Comments just after module or subprogram, or arguments are + # returnd. If "COMMENTS_ARE_UPPER" is true, comments just before + # modules or subprograms are returnd + # + def find_comments text + return "" unless text + lines = text.split("\n") + lines.reverse! if COMMENTS_ARE_UPPER + comment_block = Array.new + lines.each do |line| + break if line =~ /^\s*?\w/ || line =~ /^\s*?$/ + if COMMENTS_ARE_UPPER + comment_block.unshift line.sub(/^\s*?!\s?/,"") + else + comment_block.push line.sub(/^\s*?!\s?/,"") + end + end + nice_lines = comment_block.join("\n").split "\n\s*?\n" + nice_lines[0] ||= "" + nice_lines.shift + end + + def progress(char) + unless @options.quiet + @progress.print(char) + @progress.flush + end + end + + # + # Create method for internal alias + # + def initialize_public_method(method, parent) + return if !method || !parent + + new_meth = AnyMethod.new("External Alias for module", method.name) + new_meth.singleton = method.singleton + new_meth.params = method.params.clone + new_meth.comment = remove_trailing_alias(method.comment.clone) + new_meth.comment << "\n\n#{EXTERNAL_ALIAS_MES} #{parent.strip.chomp}\##{method.name}" + + return new_meth + end + + # + # Create method for external alias + # + # If argument "internal" is true, file is ignored. + # + def initialize_external_method(new, old, params, file, comment, token=nil, + internal=nil, nolink=nil) + return nil unless new || old + + if internal + external_alias_header = "#{INTERNAL_ALIAS_MES} " + external_alias_text = external_alias_header + old + elsif file + external_alias_header = "#{EXTERNAL_ALIAS_MES} " + external_alias_text = external_alias_header + file + "#" + old + else + return nil + end + external_meth = AnyMethod.new(external_alias_text, new) + external_meth.singleton = false + external_meth.params = params + external_comment = remove_trailing_alias(comment) + "\n\n" if comment + external_meth.comment = external_comment || "" + if nolink && token + external_meth.start_collecting_tokens + external_meth.add_token Token.new(1,1).set_text(token) + else + external_meth.comment << external_alias_text + end + + return external_meth + end + + + + # + # Parse visibility + # + def parse_visibility(code, default, container) + result = [] + visibility_default = default || :public + + used_modules = [] + container.includes.each{|i| used_modules << i.name} if container + + remaining_code = code.gsub(/^\s*?type[\s\,]+.*?\s+end\s+type.*?$/im, "") + remaining_code.split("\n").each{ |line| + if /^\s*?private\s*?$/ =~ line + visibility_default = :private + break + end + } if remaining_code + + remaining_code.split("\n").each{ |line| + if /^\s*?private\s*?(::)?\s+(.*)\s*?(!.*?)?/i =~ line + methods = $2.sub(/!.*$/, '') + methods.split(",").each{ |meth| + meth.sub!(/!.*$/, '') + meth.gsub!(/:/, '') + result << { + "name" => meth.chomp.strip, + "visibility" => :private, + "used_modules" => used_modules.clone, + "file_or_module" => container, + "entity_is_discovered" => nil, + "local_name" => nil + } + } + elsif /^\s*?public\s*?(::)?\s+(.*)\s*?(!.*?)?/i =~ line + methods = $2.sub(/!.*$/, '') + methods.split(",").each{ |meth| + meth.sub!(/!.*$/, '') + meth.gsub!(/:/, '') + result << { + "name" => meth.chomp.strip, + "visibility" => :public, + "used_modules" => used_modules.clone, + "file_or_module" => container, + "entity_is_discovered" => nil, + "local_name" => nil + } + } + end + } if remaining_code + + if container + result.each{ |vis_info| + vis_info["parent"] = container.name + } + end + + return visibility_default, result + end + + # + # Set visibility + # + # "subname" element of "visibility_info" is deleted. + # + def set_visibility(container, subname, visibility_default, visibility_info) + return unless container || subname || visibility_default || visibility_info + not_found = true + visibility_info.collect!{ |info| + if info["name"] == subname || + @options.ignore_case && info["name"].upcase == subname.upcase + if info["file_or_module"].name == container.name + container.set_visibility_for([subname], info["visibility"]) + info["entity_is_discovered"] = true + not_found = false + end + end + info + } + if not_found + return container.set_visibility_for([subname], visibility_default) + else + return container + end + end + + # + # Find visibility + # + def find_visibility(container, subname, visibility_info) + return nil if !subname || !visibility_info + visibility_info.each{ |info| + if info["name"] == subname || + @options.ignore_case && info["name"].upcase == subname.upcase + if info["parent"] == container.name + return info["visibility"] + end + end + } + return nil + end + + # + # Check external aliases + # + def check_external_aliases(subname, params, comment, test=nil) + @@external_aliases.each{ |alias_item| + if subname == alias_item["old_name"] || + subname.upcase == alias_item["old_name"].upcase && + @options.ignore_case + + new_meth = initialize_external_method(alias_item["new_name"], + subname, params, @file_name, + comment) + new_meth.visibility = alias_item["visibility"] + + progress "e" + @stats.num_methods += 1 + alias_item["file_or_module"].add_method(new_meth) + + if !alias_item["file_or_module"].include_requires?(@file_name, @options.ignore_case) + alias_item["file_or_module"].add_require(Require.new(@file_name, "")) + end + end + } + end + + # + # Check public_methods + # + def check_public_methods(method, parent) + return if !method || !parent + @@public_methods.each{ |alias_item| + parent_is_used_module = nil + alias_item["used_modules"].each{ |used_module| + if used_module == parent || + used_module.upcase == parent.upcase && + @options.ignore_case + parent_is_used_module = true + end + } + next if !parent_is_used_module + + if method.name == alias_item["name"] || + method.name.upcase == alias_item["name"].upcase && + @options.ignore_case + + new_meth = initialize_public_method(method, parent) + if alias_item["local_name"] + new_meth.name = alias_item["local_name"] + end + + progress "e" + @stats.num_methods += 1 + alias_item["file_or_module"].add_method new_meth + end + } + end + + # + # Continuous lines are united. + # + # Comments in continuous lines are removed. + # + def united_to_one_line(f90src) + return "" unless f90src + lines = f90src.split("\n") + previous_continuing = false + now_continuing = false + body = "" + lines.each{ |line| + words = line.split("") + next if words.empty? && previous_continuing + commentout = false + brank_flag = true ; brank_char = "" + squote = false ; dquote = false + ignore = false + words.collect! { |char| + if previous_continuing && brank_flag + now_continuing = true + ignore = true + case char + when "!" ; break + when " " ; brank_char << char ; next "" + when "&" + brank_flag = false + now_continuing = false + next "" + else + brank_flag = false + now_continuing = false + ignore = false + next brank_char + char + end + end + ignore = false + + if now_continuing + next "" + elsif !(squote) && !(dquote) && !(commentout) + case char + when "!" ; commentout = true ; next char + when "\""; dquote = true ; next char + when "\'"; squote = true ; next char + when "&" ; now_continuing = true ; next "" + else next char + end + elsif commentout + next char + elsif squote + case char + when "\'"; squote = false ; next char + else next char + end + elsif dquote + case char + when "\""; dquote = false ; next char + else next char + end + end + } + if !ignore && !previous_continuing || !brank_flag + if previous_continuing + body << words.join("") + else + body << "\n" + words.join("") + end + end + previous_continuing = now_continuing ? true : nil + now_continuing = nil + } + return body + end + + + # + # Continuous line checker + # + def continuous_line?(line) + continuous = false + if /&\s*?(!.*)?$/ =~ line + continuous = true + if comment_out?($~.pre_match) + continuous = false + end + end + return continuous + end + + # + # Comment out checker + # + def comment_out?(line) + return nil unless line + commentout = false + squote = false ; dquote = false + line.split("").each { |char| + if !(squote) && !(dquote) + case char + when "!" ; commentout = true ; break + when "\""; dquote = true + when "\'"; squote = true + else next + end + elsif squote + case char + when "\'"; squote = false + else next + end + elsif dquote + case char + when "\""; dquote = false + else next + end + end + } + return commentout + end + + # + # Semicolons are replaced to line feed. + # + def semicolon_to_linefeed(text) + return "" unless text + lines = text.split("\n") + lines.collect!{ |line| + words = line.split("") + commentout = false + squote = false ; dquote = false + words.collect! { |char| + if !(squote) && !(dquote) && !(commentout) + case char + when "!" ; commentout = true ; next char + when "\""; dquote = true ; next char + when "\'"; squote = true ; next char + when ";" ; "\n" + else next char + end + elsif commentout + next char + elsif squote + case char + when "\'"; squote = false ; next char + else next char + end + elsif dquote + case char + when "\""; dquote = false ; next char + else next char + end + end + } + words.join("") + } + return lines.join("\n") + end + + # + # Which "line" is start of block (module, program, block data, + # subroutine, function) statement ? + # + def block_start?(line) + return nil if !line + + if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i || + line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i || + line =~ /^\s*?block\s+data(\s+\w+)?\s*?(!.*?)?$/i || + line =~ \ + /^\s*? + (recursive|pure|elemental)?\s*? + subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$ + /ix || + line =~ \ + /^\s*? + (recursive|pure|elemental)?\s*? + ( + character\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | type\s*?\([\w\s]+?\)\s+ + | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | double\s+precision\s+ + | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+ + )? + function\s+(\w+)\s*? + (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$ + /ix + return true + end + + return nil + end + + # + # Which "line" is end of block (module, program, block data, + # subroutine, function) statement ? + # + def block_end?(line) + return nil if !line + + if line =~ /^\s*?end\s*?(!.*?)?$/i || + line =~ /^\s*?end\s+module(\s+\w+)?\s*?(!.*?)?$/i || + line =~ /^\s*?end\s+program(\s+\w+)?\s*?(!.*?)?$/i || + line =~ /^\s*?end\s+block\s+data(\s+\w+)?\s*?(!.*?)?$/i || + line =~ /^\s*?end\s+subroutine(\s+\w+)?\s*?(!.*?)?$/i || + line =~ /^\s*?end\s+function(\s+\w+)?\s*?(!.*?)?$/i + return true + end + + return nil + end + + # + # Remove "Alias for" in end of comments + # + def remove_trailing_alias(text) + return "" if !text + lines = text.split("\n").reverse + comment_block = Array.new + checked = false + lines.each do |line| + if !checked + if /^\s?#{INTERNAL_ALIAS_MES}/ =~ line || + /^\s?#{EXTERNAL_ALIAS_MES}/ =~ line + checked = true + next + end + end + comment_block.unshift line + end + nice_lines = comment_block.join("\n") + nice_lines ||= "" + return nice_lines + end + + # Empty lines in header are removed + def remove_empty_head_lines(text) + return "" unless text + lines = text.split("\n") + header = true + lines.delete_if{ |line| + header = false if /\S/ =~ line + header && /^\s*?$/ =~ line + } + lines.join("\n") + end + + + # header marker "=", "==", ... are removed + def remove_header_marker(text) + return text.gsub(/^\s?(=+)/, '\1') + end + + def remove_private_comments(body) + body.gsub!(/^\s*!--\s*?$.*?^\s*!\+\+\s*?$/m, '') + return body + end + + + # + # Information of arguments of subroutines and functions in Fortran95 + # + class Fortran95Definition + + # Name of variable + # + attr_reader :varname + + # Types of variable + # + attr_reader :types + + # Initial Value + # + attr_reader :inivalue + + # Suffix of array + # + attr_reader :arraysuffix + + # Comments + # + attr_accessor :comment + + # Flag of non documentation + # + attr_accessor :nodoc + + def initialize(varname, types, inivalue, arraysuffix, comment, + nodoc=false) + @varname = varname + @types = types + @inivalue = inivalue + @arraysuffix = arraysuffix + @comment = comment + @nodoc = nodoc + end + + def to_s + return <<-EOF + +EOF + end + + # + # If attr is included, true is returned + # + def include_attr?(attr) + return if !attr + @types.split(",").each{ |type| + return true if type.strip.chomp.upcase == attr.strip.chomp.upcase + } + return nil + end + + end # End of Fortran95Definition + + # + # Parse string argument "text", and Return Array of + # Fortran95Definition object + # + def definition_info(text) + return nil unless text + lines = "#{text}" + defs = Array.new + comment = "" + trailing_comment = "" + under_comment_valid = false + lines.split("\n").each{ |line| + if /^\s*?!\s?(.*)/ =~ line + if COMMENTS_ARE_UPPER + comment << remove_header_marker($1) + comment << "\n" + elsif defs[-1] && under_comment_valid + defs[-1].comment << "\n" + defs[-1].comment << remove_header_marker($1) + end + next + elsif /^\s*?$/ =~ line + comment = "" + under_comment_valid = false + next + end + type = "" + characters = "" + if line =~ /^\s*? + ( + character\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* + | type\s*?\([\w\s]+?\)[\s\,]* + | integer\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* + | real\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* + | double\s+precision[\s\,]* + | logical\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* + | complex\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* + ) + (.*?::)? + (.+)$ + /ix + characters = $8 + type = $1 + type << $7.gsub(/::/, '').gsub(/^\s*?\,/, '') if $7 + else + under_comment_valid = false + next + end + squote = false ; dquote = false ; bracket = 0 + iniflag = false; commentflag = false + varname = "" ; arraysuffix = "" ; inivalue = "" + start_pos = defs.size + characters.split("").each { |char| + if !(squote) && !(dquote) && bracket <= 0 && !(iniflag) && !(commentflag) + case char + when "!" ; commentflag = true + when "(" ; bracket += 1 ; arraysuffix = char + when "\""; dquote = true + when "\'"; squote = true + when "=" ; iniflag = true ; inivalue << char + when "," + defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment) + varname = "" ; arraysuffix = "" ; inivalue = "" + under_comment_valid = true + when " " ; next + else ; varname << char + end + elsif commentflag + comment << remove_header_marker(char) + trailing_comment << remove_header_marker(char) + elsif iniflag + if dquote + case char + when "\"" ; dquote = false ; inivalue << char + else ; inivalue << char + end + elsif squote + case char + when "\'" ; squote = false ; inivalue << char + else ; inivalue << char + end + elsif bracket > 0 + case char + when "(" ; bracket += 1 ; inivalue << char + when ")" ; bracket -= 1 ; inivalue << char + else ; inivalue << char + end + else + case char + when "," + defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment) + varname = "" ; arraysuffix = "" ; inivalue = "" + iniflag = false + under_comment_valid = true + when "(" ; bracket += 1 ; inivalue << char + when "\""; dquote = true ; inivalue << char + when "\'"; squote = true ; inivalue << char + when "!" ; commentflag = true + else ; inivalue << char + end + end + elsif !(squote) && !(dquote) && bracket > 0 + case char + when "(" ; bracket += 1 ; arraysuffix << char + when ")" ; bracket -= 1 ; arraysuffix << char + else ; arraysuffix << char + end + elsif squote + case char + when "\'"; squote = false ; inivalue << char + else ; inivalue << char + end + elsif dquote + case char + when "\""; dquote = false ; inivalue << char + else ; inivalue << char + end + end + } + defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment) + if trailing_comment =~ /^:nodoc:/ + defs[start_pos..-1].collect!{ |defitem| + defitem.nodoc = true + } + end + varname = "" ; arraysuffix = "" ; inivalue = "" + comment = "" + under_comment_valid = true + trailing_comment = "" + } + return defs + end + + + end # class Fortran95parser + +end # module RDoc diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_rb.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_rb.rb new file mode 100644 index 00000000..750c483c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_rb.rb @@ -0,0 +1,2609 @@ +#!/usr/local/bin/ruby + +# Parse a Ruby source file, building a set of objects +# representing the modules, classes, methods, +# requires, and includes we find (these classes +# are defined in code_objects.rb). + +# This file contains stuff stolen outright from: +# +# rtags.rb - +# ruby-lex.rb - ruby lexcal analizer +# ruby-token.rb - ruby tokens +# by Keiju ISHITSUKA (Nippon Rational Inc.) +# + +require "e2mmap" +require "irb/slex" + +require "rdoc/code_objects" +require "rdoc/tokenstream" + +require "rdoc/markup/simple_markup/preprocess" + +require "rdoc/parsers/parserfactory" + +$TOKEN_DEBUG = $DEBUG + +# Definitions of all tokens involved in the lexical analysis + +module RubyToken + EXPR_BEG = :EXPR_BEG + EXPR_MID = :EXPR_MID + EXPR_END = :EXPR_END + EXPR_ARG = :EXPR_ARG + EXPR_FNAME = :EXPR_FNAME + EXPR_DOT = :EXPR_DOT + EXPR_CLASS = :EXPR_CLASS + + class Token + NO_TEXT = "??".freeze + attr :text + + def initialize(line_no, char_no) + @line_no = line_no + @char_no = char_no + @text = NO_TEXT + end + + # Because we're used in contexts that expect to return a token, + # we set the text string and then return ourselves + def set_text(text) + @text = text + self + end + + attr_reader :line_no, :char_no, :text + end + + class TkNode < Token + attr :node + end + + class TkId < Token + def initialize(line_no, char_no, name) + super(line_no, char_no) + @name = name + end + attr :name + end + + class TkKW < TkId + end + + class TkVal < Token + def initialize(line_no, char_no, value = nil) + super(line_no, char_no) + set_text(value) + end + end + + class TkOp < Token + def name + self.class.op_name + end + end + + class TkOPASGN < TkOp + def initialize(line_no, char_no, op) + super(line_no, char_no) + op = TkReading2Token[op] unless op.kind_of?(Symbol) + @op = op + end + attr :op + end + + class TkUnknownChar < Token + def initialize(line_no, char_no, id) + super(line_no, char_no) + @name = char_no.chr + end + attr :name + end + + class TkError < Token + end + + def set_token_position(line, char) + @prev_line_no = line + @prev_char_no = char + end + + def Token(token, value = nil) + tk = nil + case token + when String, Symbol + source = token.kind_of?(String) ? TkReading2Token : TkSymbol2Token + if (tk = source[token]).nil? + IRB.fail TkReading2TokenNoKey, token + end + tk = Token(tk[0], value) + else + tk = if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty? + token.new(@prev_line_no, @prev_char_no) + else + token.new(@prev_line_no, @prev_char_no, value) + end + end + tk + end + + TokenDefinitions = [ + [:TkCLASS, TkKW, "class", EXPR_CLASS], + [:TkMODULE, TkKW, "module", EXPR_BEG], + [:TkDEF, TkKW, "def", EXPR_FNAME], + [:TkUNDEF, TkKW, "undef", EXPR_FNAME], + [:TkBEGIN, TkKW, "begin", EXPR_BEG], + [:TkRESCUE, TkKW, "rescue", EXPR_MID], + [:TkENSURE, TkKW, "ensure", EXPR_BEG], + [:TkEND, TkKW, "end", EXPR_END], + [:TkIF, TkKW, "if", EXPR_BEG, :TkIF_MOD], + [:TkUNLESS, TkKW, "unless", EXPR_BEG, :TkUNLESS_MOD], + [:TkTHEN, TkKW, "then", EXPR_BEG], + [:TkELSIF, TkKW, "elsif", EXPR_BEG], + [:TkELSE, TkKW, "else", EXPR_BEG], + [:TkCASE, TkKW, "case", EXPR_BEG], + [:TkWHEN, TkKW, "when", EXPR_BEG], + [:TkWHILE, TkKW, "while", EXPR_BEG, :TkWHILE_MOD], + [:TkUNTIL, TkKW, "until", EXPR_BEG, :TkUNTIL_MOD], + [:TkFOR, TkKW, "for", EXPR_BEG], + [:TkBREAK, TkKW, "break", EXPR_END], + [:TkNEXT, TkKW, "next", EXPR_END], + [:TkREDO, TkKW, "redo", EXPR_END], + [:TkRETRY, TkKW, "retry", EXPR_END], + [:TkIN, TkKW, "in", EXPR_BEG], + [:TkDO, TkKW, "do", EXPR_BEG], + [:TkRETURN, TkKW, "return", EXPR_MID], + [:TkYIELD, TkKW, "yield", EXPR_END], + [:TkSUPER, TkKW, "super", EXPR_END], + [:TkSELF, TkKW, "self", EXPR_END], + [:TkNIL, TkKW, "nil", EXPR_END], + [:TkTRUE, TkKW, "true", EXPR_END], + [:TkFALSE, TkKW, "false", EXPR_END], + [:TkAND, TkKW, "and", EXPR_BEG], + [:TkOR, TkKW, "or", EXPR_BEG], + [:TkNOT, TkKW, "not", EXPR_BEG], + [:TkIF_MOD, TkKW], + [:TkUNLESS_MOD, TkKW], + [:TkWHILE_MOD, TkKW], + [:TkUNTIL_MOD, TkKW], + [:TkALIAS, TkKW, "alias", EXPR_FNAME], + [:TkDEFINED, TkKW, "defined?", EXPR_END], + [:TklBEGIN, TkKW, "BEGIN", EXPR_END], + [:TklEND, TkKW, "END", EXPR_END], + [:Tk__LINE__, TkKW, "__LINE__", EXPR_END], + [:Tk__FILE__, TkKW, "__FILE__", EXPR_END], + + [:TkIDENTIFIER, TkId], + [:TkFID, TkId], + [:TkGVAR, TkId], + [:TkIVAR, TkId], + [:TkCONSTANT, TkId], + + [:TkINTEGER, TkVal], + [:TkFLOAT, TkVal], + [:TkSTRING, TkVal], + [:TkXSTRING, TkVal], + [:TkREGEXP, TkVal], + [:TkCOMMENT, TkVal], + + [:TkDSTRING, TkNode], + [:TkDXSTRING, TkNode], + [:TkDREGEXP, TkNode], + [:TkNTH_REF, TkId], + [:TkBACK_REF, TkId], + + [:TkUPLUS, TkOp, "+@"], + [:TkUMINUS, TkOp, "-@"], + [:TkPOW, TkOp, "**"], + [:TkCMP, TkOp, "<=>"], + [:TkEQ, TkOp, "=="], + [:TkEQQ, TkOp, "==="], + [:TkNEQ, TkOp, "!="], + [:TkGEQ, TkOp, ">="], + [:TkLEQ, TkOp, "<="], + [:TkANDOP, TkOp, "&&"], + [:TkOROP, TkOp, "||"], + [:TkMATCH, TkOp, "=~"], + [:TkNMATCH, TkOp, "!~"], + [:TkDOT2, TkOp, ".."], + [:TkDOT3, TkOp, "..."], + [:TkAREF, TkOp, "[]"], + [:TkASET, TkOp, "[]="], + [:TkLSHFT, TkOp, "<<"], + [:TkRSHFT, TkOp, ">>"], + [:TkCOLON2, TkOp], + [:TkCOLON3, TkOp], +# [:OPASGN, TkOp], # +=, -= etc. # + [:TkASSOC, TkOp, "=>"], + [:TkQUESTION, TkOp, "?"], #? + [:TkCOLON, TkOp, ":"], #: + + [:TkfLPAREN], # func( # + [:TkfLBRACK], # func[ # + [:TkfLBRACE], # func{ # + [:TkSTAR], # *arg + [:TkAMPER], # &arg # + [:TkSYMBOL, TkId], # :SYMBOL + [:TkSYMBEG, TkId], + [:TkGT, TkOp, ">"], + [:TkLT, TkOp, "<"], + [:TkPLUS, TkOp, "+"], + [:TkMINUS, TkOp, "-"], + [:TkMULT, TkOp, "*"], + [:TkDIV, TkOp, "/"], + [:TkMOD, TkOp, "%"], + [:TkBITOR, TkOp, "|"], + [:TkBITXOR, TkOp, "^"], + [:TkBITAND, TkOp, "&"], + [:TkBITNOT, TkOp, "~"], + [:TkNOTOP, TkOp, "!"], + + [:TkBACKQUOTE, TkOp, "`"], + + [:TkASSIGN, Token, "="], + [:TkDOT, Token, "."], + [:TkLPAREN, Token, "("], #(exp) + [:TkLBRACK, Token, "["], #[arry] + [:TkLBRACE, Token, "{"], #{hash} + [:TkRPAREN, Token, ")"], + [:TkRBRACK, Token, "]"], + [:TkRBRACE, Token, "}"], + [:TkCOMMA, Token, ","], + [:TkSEMICOLON, Token, ";"], + + [:TkRD_COMMENT], + [:TkSPACE], + [:TkNL], + [:TkEND_OF_SCRIPT], + + [:TkBACKSLASH, TkUnknownChar, "\\"], + [:TkAT, TkUnknownChar, "@"], + [:TkDOLLAR, TkUnknownChar, "\$"], #" + ] + + # {reading => token_class} + # {reading => [token_class, *opt]} + TkReading2Token = {} + TkSymbol2Token = {} + + def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts) + token_n = token_n.id2name unless token_n.kind_of?(String) + if RubyToken.const_defined?(token_n) + IRB.fail AlreadyDefinedToken, token_n + end + + token_c = Class.new super_token + RubyToken.const_set token_n, token_c +# token_c.inspect + + if reading + if TkReading2Token[reading] + IRB.fail TkReading2TokenDuplicateError, token_n, reading + end + if opts.empty? + TkReading2Token[reading] = [token_c] + else + TkReading2Token[reading] = [token_c].concat(opts) + end + end + TkSymbol2Token[token_n.intern] = token_c + + if token_c <= TkOp + token_c.class_eval %{ + def self.op_name; "#{reading}"; end + } + end + end + + for defs in TokenDefinitions + def_token(*defs) + end + + NEWLINE_TOKEN = TkNL.new(0,0) + NEWLINE_TOKEN.set_text("\n") + +end + + + +# Lexical analyzer for Ruby source + +class RubyLex + + ###################################################################### + # + # Read an input stream character by character. We allow for unlimited + # ungetting of characters just read. + # + # We simplify the implementation greatly by reading the entire input + # into a buffer initially, and then simply traversing it using + # pointers. + # + # We also have to allow for the here document diversion. This + # little gem comes about when the lexer encounters a here + # document. At this point we effectively need to split the input + # stream into two parts: one to read the body of the here document, + # the other to read the rest of the input line where the here + # document was initially encountered. For example, we might have + # + # do_something(<<-A, <<-B) + # stuff + # for + # A + # stuff + # for + # B + # + # When the lexer encounters the <= @size + ch = @content[@offset, 1] + + @offset += 1 + @hwm = @offset if @hwm < @offset + + if @newline_pending + @line_num += 1 + @last_newline = @offset - 1 + @newline_pending = false + end + + if ch == "\n" + @newline_pending = true + end + ch + end + + def getc_already_read + getc + end + + def ungetc(ch) + raise "unget past beginning of file" if @offset <= 0 + @offset -= 1 + if @content[@offset] == ?\n + @newline_pending = false + end + end + + def get_read + res = @content[@read_back_offset...@offset] + @read_back_offset = @offset + res + end + + def peek(at) + pos = @offset + at + if pos >= @size + nil + else + @content[pos, 1] + end + end + + def peek_equal(str) + @content[@offset, str.length] == str + end + + def divert_read_from(reserve) + @content[@offset, 0] = reserve + @size = @content.size + end + end + + # end of nested class BufferedReader + + extend Exception2MessageMapper + def_exception(:AlreadyDefinedToken, "Already defined token(%s)") + def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')") + def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')") + def_exception(:TkReading2TokenDuplicateError, + "key duplicate(token_n='%s', key='%s')") + def_exception(:SyntaxError, "%s") + + include RubyToken + include IRB + + attr_reader :continue + attr_reader :lex_state + + def RubyLex.debug? + false + end + + def initialize(content) + lex_init + + @reader = BufferedReader.new(content) + + @exp_line_no = @line_no = 1 + @base_char_no = 0 + @indent = 0 + + @ltype = nil + @quoted = nil + @lex_state = EXPR_BEG + @space_seen = false + + @continue = false + @line = "" + + @skip_space = false + @read_auto_clean_up = false + @exception_on_syntax_error = true + end + + attr :skip_space, true + attr :read_auto_clean_up, true + attr :exception_on_syntax_error, true + + attr :indent + + # io functions + def line_no + @reader.line_num + end + + def char_no + @reader.column + end + + def get_read + @reader.get_read + end + + def getc + @reader.getc + end + + def getc_of_rests + @reader.getc_already_read + end + + def gets + c = getc or return + l = "" + begin + l.concat c unless c == "\r" + break if c == "\n" + end while c = getc + l + end + + + def ungetc(c = nil) + @reader.ungetc(c) + end + + def peek_equal?(str) + @reader.peek_equal(str) + end + + def peek(i = 0) + @reader.peek(i) + end + + def lex + until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) && + !@continue or + tk.nil?) + end + line = get_read + + if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil? + nil + else + line + end + end + + def token + set_token_position(line_no, char_no) + begin + begin + tk = @OP.match(self) + @space_seen = tk.kind_of?(TkSPACE) + rescue SyntaxError + abort if @exception_on_syntax_error + tk = TkError.new(line_no, char_no) + end + end while @skip_space and tk.kind_of?(TkSPACE) + if @read_auto_clean_up + get_read + end +# throw :eof unless tk + p tk if $DEBUG + tk + end + + ENINDENT_CLAUSE = [ + "case", "class", "def", "do", "for", "if", + "module", "unless", "until", "while", "begin" #, "when" + ] + DEINDENT_CLAUSE = ["end" #, "when" + ] + + PERCENT_LTYPE = { + "q" => "\'", + "Q" => "\"", + "x" => "\`", + "r" => "/", + "w" => "]" + } + + PERCENT_PAREN = { + "{" => "}", + "[" => "]", + "<" => ">", + "(" => ")" + } + + Ltype2Token = { + "\'" => TkSTRING, + "\"" => TkSTRING, + "\`" => TkXSTRING, + "/" => TkREGEXP, + "]" => TkDSTRING + } + Ltype2Token.default = TkSTRING + + DLtype2Token = { + "\"" => TkDSTRING, + "\`" => TkDXSTRING, + "/" => TkDREGEXP, + } + + def lex_init() + @OP = SLex.new + @OP.def_rules("\0", "\004", "\032") do |chars, io| + Token(TkEND_OF_SCRIPT).set_text(chars) + end + + @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |chars, io| + @space_seen = TRUE + while (ch = getc) =~ /[ \t\f\r\13]/ + chars << ch + end + ungetc + Token(TkSPACE).set_text(chars) + end + + @OP.def_rule("#") do + |op, io| + identify_comment + end + + @OP.def_rule("=begin", proc{@prev_char_no == 0 && peek(0) =~ /\s/}) do + |op, io| + str = op + @ltype = "=" + + + begin + line = "" + begin + ch = getc + line << ch + end until ch == "\n" + str << line + end until line =~ /^=end/ + + ungetc + + @ltype = nil + + if str =~ /\A=begin\s+rdoc/i + str.sub!(/\A=begin.*\n/, '') + str.sub!(/^=end.*/m, '') + Token(TkCOMMENT).set_text(str) + else + Token(TkRD_COMMENT)#.set_text(str) + end + end + + @OP.def_rule("\n") do + print "\\n\n" if RubyLex.debug? + case @lex_state + when EXPR_BEG, EXPR_FNAME, EXPR_DOT + @continue = TRUE + else + @continue = FALSE + @lex_state = EXPR_BEG + end + Token(TkNL).set_text("\n") + end + + @OP.def_rules("*", "**", + "!", "!=", "!~", + "=", "==", "===", + "=~", "<=>", + "<", "<=", + ">", ">=", ">>") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + @OP.def_rules("<<") do + |op, io| + tk = nil + if @lex_state != EXPR_END && @lex_state != EXPR_CLASS && + (@lex_state != EXPR_ARG || @space_seen) + c = peek(0) + if /[-\w_\"\'\`]/ =~ c + tk = identify_here_document + end + end + if !tk + @lex_state = EXPR_BEG + tk = Token(op).set_text(op) + end + tk + end + + @OP.def_rules("'", '"') do + |op, io| + identify_string(op) + end + + @OP.def_rules("`") do + |op, io| + if @lex_state == EXPR_FNAME + Token(op).set_text(op) + else + identify_string(op) + end + end + + @OP.def_rules('?') do + |op, io| + if @lex_state == EXPR_END + @lex_state = EXPR_BEG + Token(TkQUESTION).set_text(op) + else + ch = getc + if @lex_state == EXPR_ARG && ch !~ /\s/ + ungetc + @lex_state = EXPR_BEG; + Token(TkQUESTION).set_text(op) + else + str = op + str << ch + if (ch == '\\') #' + str << read_escape + end + @lex_state = EXPR_END + Token(TkINTEGER).set_text(str) + end + end + end + + @OP.def_rules("&", "&&", "|", "||") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + @OP.def_rules("+=", "-=", "*=", "**=", + "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do + |op, io| + @lex_state = EXPR_BEG + op =~ /^(.*)=$/ + Token(TkOPASGN, $1).set_text(op) + end + + @OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do |op, io| + Token(TkUPLUS).set_text(op) + end + + @OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do |op, io| + Token(TkUMINUS).set_text(op) + end + + @OP.def_rules("+", "-") do + |op, io| + catch(:RET) do + if @lex_state == EXPR_ARG + if @space_seen and peek(0) =~ /[0-9]/ + throw :RET, identify_number(op) + else + @lex_state = EXPR_BEG + end + elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/ + throw :RET, identify_number(op) + else + @lex_state = EXPR_BEG + end + Token(op).set_text(op) + end + end + + @OP.def_rule(".") do + @lex_state = EXPR_BEG + if peek(0) =~ /[0-9]/ + ungetc + identify_number("") + else + # for obj.if + @lex_state = EXPR_DOT + Token(TkDOT).set_text(".") + end + end + + @OP.def_rules("..", "...") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + lex_int2 + end + + def lex_int2 + @OP.def_rules("]", "}", ")") do + |op, io| + @lex_state = EXPR_END + @indent -= 1 + Token(op).set_text(op) + end + + @OP.def_rule(":") do + if @lex_state == EXPR_END || peek(0) =~ /\s/ + @lex_state = EXPR_BEG + tk = Token(TkCOLON) + else + @lex_state = EXPR_FNAME; + tk = Token(TkSYMBEG) + end + tk.set_text(":") + end + + @OP.def_rule("::") do +# p @lex_state.id2name, @space_seen + if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen + @lex_state = EXPR_BEG + tk = Token(TkCOLON3) + else + @lex_state = EXPR_DOT + tk = Token(TkCOLON2) + end + tk.set_text("::") + end + + @OP.def_rule("/") do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_string(op) + elsif peek(0) == '=' + getc + @lex_state = EXPR_BEG + Token(TkOPASGN, :/).set_text("/=") #") + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_string(op) + else + @lex_state = EXPR_BEG + Token("/").set_text(op) + end + end + + @OP.def_rules("^") do + @lex_state = EXPR_BEG + Token("^").set_text("^") + end + + # @OP.def_rules("^=") do + # @lex_state = EXPR_BEG + # Token(TkOPASGN, :^) + # end + + @OP.def_rules(",", ";") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + @OP.def_rule("~") do + @lex_state = EXPR_BEG + Token("~").set_text("~") + end + + @OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) do + @lex_state = EXPR_BEG + Token("~").set_text("~@") + end + + @OP.def_rule("(") do + @indent += 1 + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + @lex_state = EXPR_BEG + tk = Token(TkfLPAREN) + else + @lex_state = EXPR_BEG + tk = Token(TkLPAREN) + end + tk.set_text("(") + end + + @OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) do + Token("[]").set_text("[]") + end + + @OP.def_rule("[]=", proc{@lex_state == EXPR_FNAME}) do + Token("[]=").set_text("[]=") + end + + @OP.def_rule("[") do + @indent += 1 + if @lex_state == EXPR_FNAME + t = Token(TkfLBRACK) + else + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + t = Token(TkLBRACK) + elsif @lex_state == EXPR_ARG && @space_seen + t = Token(TkLBRACK) + else + t = Token(TkfLBRACK) + end + @lex_state = EXPR_BEG + end + t.set_text("[") + end + + @OP.def_rule("{") do + @indent += 1 + if @lex_state != EXPR_END && @lex_state != EXPR_ARG + t = Token(TkLBRACE) + else + t = Token(TkfLBRACE) + end + @lex_state = EXPR_BEG + t.set_text("{") + end + + @OP.def_rule('\\') do #' + if getc == "\n" + @space_seen = true + @continue = true + Token(TkSPACE).set_text("\\\n") + else + ungetc + Token("\\").set_text("\\") #" + end + end + + @OP.def_rule('%') do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_quotation('%') + elsif peek(0) == '=' + getc + Token(TkOPASGN, "%").set_text("%=") + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_quotation('%') + else + @lex_state = EXPR_BEG + Token("%").set_text("%") + end + end + + @OP.def_rule('$') do #' + identify_gvar + end + + @OP.def_rule('@') do + if peek(0) =~ /[@\w_]/ + ungetc + identify_identifier + else + Token("@").set_text("@") + end + end + + # @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do + # |op, io| + # @indent += 1 + # @lex_state = EXPR_FNAME + # # @lex_state = EXPR_END + # # until @rests[0] == "\n" or @rests[0] == ";" + # # rests.shift + # # end + # end + + @OP.def_rule("__END__", proc{@prev_char_no == 0 && peek(0) =~ /[\r\n]/}) do + throw :eof + end + + @OP.def_rule("") do + |op, io| + printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug? + if peek(0) =~ /[0-9]/ + t = identify_number("") + elsif peek(0) =~ /[\w_]/ + t = identify_identifier + end + printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug? + t + end + + p @OP if RubyLex.debug? + end + + def identify_gvar + @lex_state = EXPR_END + str = "$" + + tk = case ch = getc + when /[~_*$?!@\/\\;,=:<>".]/ #" + str << ch + Token(TkGVAR, str) + + when "-" + str << "-" << getc + Token(TkGVAR, str) + + when "&", "`", "'", "+" + str << ch + Token(TkBACK_REF, str) + + when /[1-9]/ + str << ch + while (ch = getc) =~ /[0-9]/ + str << ch + end + ungetc + Token(TkNTH_REF) + when /\w/ + ungetc + ungetc + return identify_identifier + else + ungetc + Token("$") + end + tk.set_text(str) + end + + def identify_identifier + token = "" + token.concat getc if peek(0) =~ /[$@]/ + token.concat getc if peek(0) == "@" + + while (ch = getc) =~ /\w|_/ + print ":", ch, ":" if RubyLex.debug? + token.concat ch + end + ungetc + + if ch == "!" or ch == "?" + token.concat getc + end + # fix token + + # $stderr.puts "identifier - #{token}, state = #@lex_state" + + case token + when /^\$/ + return Token(TkGVAR, token).set_text(token) + when /^\@/ + @lex_state = EXPR_END + return Token(TkIVAR, token).set_text(token) + end + + if @lex_state != EXPR_DOT + print token, "\n" if RubyLex.debug? + + token_c, *trans = TkReading2Token[token] + if token_c + # reserved word? + + if (@lex_state != EXPR_BEG && + @lex_state != EXPR_FNAME && + trans[1]) + # modifiers + token_c = TkSymbol2Token[trans[1]] + @lex_state = trans[0] + else + if @lex_state != EXPR_FNAME + if ENINDENT_CLAUSE.include?(token) + @indent += 1 + elsif DEINDENT_CLAUSE.include?(token) + @indent -= 1 + end + @lex_state = trans[0] + else + @lex_state = EXPR_END + end + end + return Token(token_c, token).set_text(token) + end + end + + if @lex_state == EXPR_FNAME + @lex_state = EXPR_END + if peek(0) == '=' + token.concat getc + end + elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_END + end + + if token[0, 1] =~ /[A-Z]/ + return Token(TkCONSTANT, token).set_text(token) + elsif token[token.size - 1, 1] =~ /[!?]/ + return Token(TkFID, token).set_text(token) + else + return Token(TkIDENTIFIER, token).set_text(token) + end + end + + def identify_here_document + ch = getc + if ch == "-" + ch = getc + indent = true + end + if /['"`]/ =~ ch # ' + lt = ch + quoted = "" + while (c = getc) && c != lt + quoted.concat c + end + else + lt = '"' + quoted = ch.dup + while (c = getc) && c =~ /\w/ + quoted.concat c + end + ungetc + end + + ltback, @ltype = @ltype, lt + reserve = "" + + while ch = getc + reserve << ch + if ch == "\\" #" + ch = getc + reserve << ch + elsif ch == "\n" + break + end + end + + str = "" + while (l = gets) + l.chomp! + l.strip! if indent + break if l == quoted + str << l.chomp << "\n" + end + + @reader.divert_read_from(reserve) + + @ltype = ltback + @lex_state = EXPR_END + Token(Ltype2Token[lt], str).set_text(str.dump) + end + + def identify_quotation(initial_char) + ch = getc + if lt = PERCENT_LTYPE[ch] + initial_char += ch + ch = getc + elsif ch =~ /\W/ + lt = "\"" + else + RubyLex.fail SyntaxError, "unknown type of %string ('#{ch}')" + end +# if ch !~ /\W/ +# ungetc +# next +# end + #@ltype = lt + @quoted = ch unless @quoted = PERCENT_PAREN[ch] + identify_string(lt, @quoted, ch, initial_char) + end + + def identify_number(start) + str = start.dup + + if start == "+" or start == "-" or start == "" + start = getc + str << start + end + + @lex_state = EXPR_END + + if start == "0" + if peek(0) == "x" + ch = getc + str << ch + match = /[0-9a-f_]/ + else + match = /[0-7_]/ + end + while ch = getc + if ch !~ match + ungetc + break + else + str << ch + end + end + return Token(TkINTEGER).set_text(str) + end + + type = TkINTEGER + allow_point = TRUE + allow_e = TRUE + while ch = getc + case ch + when /[0-9_]/ + str << ch + + when allow_point && "." + type = TkFLOAT + if peek(0) !~ /[0-9]/ + ungetc + break + end + str << ch + allow_point = false + + when allow_e && "e", allow_e && "E" + str << ch + type = TkFLOAT + if peek(0) =~ /[+-]/ + str << getc + end + allow_e = false + allow_point = false + else + ungetc + break + end + end + Token(type).set_text(str) + end + + def identify_string(ltype, quoted = ltype, opener=nil, initial_char = nil) + @ltype = ltype + @quoted = quoted + subtype = nil + + str = "" + str << initial_char if initial_char + str << (opener||quoted) + + nest = 0 + begin + while ch = getc + str << ch + if @quoted == ch + if nest == 0 + break + else + nest -= 1 + end + elsif opener == ch + nest += 1 + elsif @ltype != "'" && @ltype != "]" and ch == "#" + ch = getc + if ch == "{" + subtype = true + str << ch << skip_inner_expression + else + ungetc(ch) + end + elsif ch == '\\' #' + str << read_escape + end + end + if @ltype == "/" + if peek(0) =~ /i|o|n|e|s/ + str << getc + end + end + if subtype + Token(DLtype2Token[ltype], str) + else + Token(Ltype2Token[ltype], str) + end.set_text(str) + ensure + @ltype = nil + @quoted = nil + @lex_state = EXPR_END + end + end + + def skip_inner_expression + res = "" + nest = 0 + while (ch = getc) + res << ch + if ch == '}' + break if nest.zero? + nest -= 1 + elsif ch == '{' + nest += 1 + end + end + res + end + + def identify_comment + @ltype = "#" + comment = "#" + while ch = getc + if ch == "\\" + ch = getc + if ch == "\n" + ch = " " + else + comment << "\\" + end + else + if ch == "\n" + @ltype = nil + ungetc + break + end + end + comment << ch + end + return Token(TkCOMMENT).set_text(comment) + end + + def read_escape + res = "" + case ch = getc + when /[0-7]/ + ungetc ch + 3.times do + case ch = getc + when /[0-7]/ + when nil + break + else + ungetc + break + end + res << ch + end + + when "x" + res << ch + 2.times do + case ch = getc + when /[0-9a-fA-F]/ + when nil + break + else + ungetc + break + end + res << ch + end + + when "M" + res << ch + if (ch = getc) != '-' + ungetc + else + res << ch + if (ch = getc) == "\\" #" + res << ch + res << read_escape + else + res << ch + end + end + + when "C", "c" #, "^" + res << ch + if ch == "C" and (ch = getc) != "-" + ungetc + else + res << ch + if (ch = getc) == "\\" #" + res << ch + res << read_escape + else + res << ch + end + end + else + res << ch + end + res + end +end + + + +# Extract code elements from a source file, returning a TopLevel +# object containing the constituent file elements. +# +# This file is based on rtags + +module RDoc + + GENERAL_MODIFIERS = [ 'nodoc' ].freeze + + CLASS_MODIFIERS = GENERAL_MODIFIERS + + ATTR_MODIFIERS = GENERAL_MODIFIERS + + CONSTANT_MODIFIERS = GENERAL_MODIFIERS + + METHOD_MODIFIERS = GENERAL_MODIFIERS + + [ 'arg', 'args', 'yield', 'yields', 'notnew', 'not-new', 'not_new', 'doc' ] + + + class RubyParser + include RubyToken + include TokenStream + + extend ParserFactory + + parse_files_matching(/\.rbw?$/) + + + def initialize(top_level, file_name, content, options, stats) + @options = options + @stats = stats + @size = 0 + @token_listeners = nil + @input_file_name = file_name + @scanner = RubyLex.new(content) + @scanner.exception_on_syntax_error = false + @top_level = top_level + @progress = $stderr unless options.quiet + end + + def scan + @tokens = [] + @unget_read = [] + @read = [] + catch(:eof) do + catch(:enddoc) do + begin + parse_toplevel_statements(@top_level) + rescue Exception => e + $stderr.puts "\n\n" + $stderr.puts "RDoc failure in #@input_file_name at or around " + + "line #{@scanner.line_no} column #{@scanner.char_no}" + $stderr.puts + $stderr.puts "Before reporting this, could you check that the file" + $stderr.puts "you're documenting compiles cleanly--RDoc is not a" + $stderr.puts "full Ruby parser, and gets confused easily if fed" + $stderr.puts "invalid programs." + $stderr.puts + $stderr.puts "The internal error was:\n\n" + + e.set_backtrace(e.backtrace[0,4]) + raise + end + end + end + @top_level + end + + private + + def make_message(msg) + prefix = "\n" + @input_file_name + ":" + if @scanner + prefix << "#{@scanner.line_no}:#{@scanner.char_no}: " + end + return prefix + msg + end + + def warn(msg) + return if @options.quiet + msg = make_message msg + $stderr.puts msg + end + + def error(msg) + msg = make_message msg + $stderr.puts msg + exit(1) + end + + def progress(char) + unless @options.quiet + @progress.print(char) + @progress.flush + end + end + + def add_token_listener(obj) + @token_listeners ||= [] + @token_listeners << obj + end + + def remove_token_listener(obj) + @token_listeners.delete(obj) + end + + def get_tk + tk = nil + if @tokens.empty? + tk = @scanner.token + @read.push @scanner.get_read + puts "get_tk1 => #{tk.inspect}" if $TOKEN_DEBUG + else + @read.push @unget_read.shift + tk = @tokens.shift + puts "get_tk2 => #{tk.inspect}" if $TOKEN_DEBUG + end + + if tk.kind_of?(TkSYMBEG) + set_token_position(tk.line_no, tk.char_no) + tk1 = get_tk + if tk1.kind_of?(TkId) || tk1.kind_of?(TkOp) + tk = Token(TkSYMBOL).set_text(":" + tk1.name) + # remove the identifier we just read (we're about to + # replace it with a symbol) + @token_listeners.each do |obj| + obj.pop_token + end if @token_listeners + else + warn("':' not followed by identifier or operator") + tk = tk1 + end + end + + # inform any listeners of our shiny new token + @token_listeners.each do |obj| + obj.add_token(tk) + end if @token_listeners + + tk + end + + def peek_tk + unget_tk(tk = get_tk) + tk + end + + def unget_tk(tk) + @tokens.unshift tk + @unget_read.unshift @read.pop + + # Remove this token from any listeners + @token_listeners.each do |obj| + obj.pop_token + end if @token_listeners + end + + def skip_tkspace(skip_nl = true) + tokens = [] + while ((tk = get_tk).kind_of?(TkSPACE) || + (skip_nl && tk.kind_of?(TkNL))) + tokens.push tk + end + unget_tk(tk) + tokens + end + + def get_tkread + read = @read.join("") + @read = [] + read + end + + def peek_read + @read.join('') + end + + NORMAL = "::" + SINGLE = "<<" + + # Look for the first comment in a file that isn't + # a shebang line. + + def collect_first_comment + skip_tkspace + res = '' + first_line = true + + tk = get_tk + while tk.kind_of?(TkCOMMENT) + if first_line && /\A#!/ =~ tk.text + skip_tkspace + tk = get_tk + elsif first_line && /\A#\s*-\*-/ =~ tk.text + first_line = false + skip_tkspace + tk = get_tk + else + first_line = false + res << tk.text << "\n" + tk = get_tk + if tk.kind_of? TkNL + skip_tkspace(false) + tk = get_tk + end + end + end + unget_tk(tk) + res + end + + def parse_toplevel_statements(container) + comment = collect_first_comment + look_for_directives_in(container, comment) + container.comment = comment unless comment.empty? + parse_statements(container, NORMAL, nil, comment) + end + + def parse_statements(container, single=NORMAL, current_method=nil, comment='') + nest = 1 + save_visibility = container.visibility + +# if container.kind_of?(TopLevel) +# else +# comment = '' +# end + + non_comment_seen = true + + while tk = get_tk + + keep_comment = false + + non_comment_seen = true unless tk.kind_of?(TkCOMMENT) + + case tk + + when TkNL + skip_tkspace(true) # Skip blanks and newlines + tk = get_tk + if tk.kind_of?(TkCOMMENT) + if non_comment_seen + comment = '' + non_comment_seen = false + end + while tk.kind_of?(TkCOMMENT) + comment << tk.text << "\n" + tk = get_tk # this is the newline + skip_tkspace(false) # leading spaces + tk = get_tk + end + unless comment.empty? + look_for_directives_in(container, comment) + if container.done_documenting + container.ongoing_visibility = save_visibility +# return + end + end + keep_comment = true + else + non_comment_seen = true + end + unget_tk(tk) + keep_comment = true + + + when TkCLASS + if container.document_children + parse_class(container, single, tk, comment) + else + nest += 1 + end + + when TkMODULE + if container.document_children + parse_module(container, single, tk, comment) + else + nest += 1 + end + + when TkDEF + if container.document_self + parse_method(container, single, tk, comment) + else + nest += 1 + end + + when TkCONSTANT + if container.document_self + parse_constant(container, single, tk, comment) + end + + when TkALIAS + if container.document_self + parse_alias(container, single, tk, comment) + end + + when TkYIELD + if current_method.nil? + warn("Warning: yield outside of method") if container.document_self + else + parse_yield(container, single, tk, current_method) + end + + # Until and While can have a 'do', which shouldn't increas + # the nesting. We can't solve the general case, but we can + # handle most occurrences by ignoring a do at the end of a line + + when TkUNTIL, TkWHILE + nest += 1 + puts "FOUND #{tk.class} in #{container.name}, nest = #{nest}, " + + "line #{tk.line_no}" if $DEBUG + skip_optional_do_after_expression + + # 'for' is trickier + when TkFOR + nest += 1 + puts "FOUND #{tk.class} in #{container.name}, nest = #{nest}, " + + "line #{tk.line_no}" if $DEBUG + skip_for_variable + skip_optional_do_after_expression + + when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN + nest += 1 + puts "Found #{tk.class} in #{container.name}, nest = #{nest}, " + + "line #{tk.line_no}" if $DEBUG + + when TkIDENTIFIER + if nest == 1 and current_method.nil? + case tk.name + when "private", "protected", "public", + "private_class_method", "public_class_method" + parse_visibility(container, single, tk) + keep_comment = true + when "attr" + parse_attr(container, single, tk, comment) + when /^attr_(reader|writer|accessor)$/, @options.extra_accessors + parse_attr_accessor(container, single, tk, comment) + when "alias_method" + if container.document_self + parse_alias(container, single, tk, comment) + end + end + end + + case tk.name + when "require" + parse_require(container, comment) + when "include" + parse_include(container, comment) + end + + + when TkEND + nest -= 1 + puts "Found 'end' in #{container.name}, nest = #{nest}, line #{tk.line_no}" if $DEBUG + puts "Method = #{current_method.name}" if $DEBUG and current_method + if nest == 0 + read_documentation_modifiers(container, CLASS_MODIFIERS) + container.ongoing_visibility = save_visibility + return + end + + end + + comment = '' unless keep_comment + begin + get_tkread + skip_tkspace(false) + end while peek_tk == TkNL + + end + end + + def parse_class(container, single, tk, comment, &block) + progress("c") + + @stats.num_classes += 1 + + container, name_t = get_class_or_module(container) + + case name_t + when TkCONSTANT + name = name_t.name + superclass = "Object" + + if peek_tk.kind_of?(TkLT) + get_tk + skip_tkspace(true) + superclass = get_class_specification + superclass = "" if superclass.empty? + end + + if single == SINGLE + cls_type = SingleClass + else + cls_type = NormalClass + end + + cls = container.add_class(cls_type, name, superclass) + read_documentation_modifiers(cls, CLASS_MODIFIERS) + cls.record_location(@top_level) + parse_statements(cls) + cls.comment = comment + + when TkLSHFT + case name = get_class_specification + when "self", container.name + parse_statements(container, SINGLE, &block) + else + other = TopLevel.find_class_named(name) + unless other +# other = @top_level.add_class(NormalClass, name, nil) +# other.record_location(@top_level) +# other.comment = comment + other = NormalClass.new("Dummy", nil) + end + read_documentation_modifiers(other, CLASS_MODIFIERS) + parse_statements(other, SINGLE, &block) + end + + else + warn("Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}") + end + end + + def parse_module(container, single, tk, comment) + progress("m") + @stats.num_modules += 1 + container, name_t = get_class_or_module(container) +# skip_tkspace + name = name_t.name + mod = container.add_module(NormalModule, name) + mod.record_location(@top_level) + read_documentation_modifiers(mod, CLASS_MODIFIERS) + parse_statements(mod) + mod.comment = comment + end + + # Look for the name of a class of module (optionally with a leading :: or + # with :: separated named) and return the ultimate name and container + + def get_class_or_module(container) + skip_tkspace + name_t = get_tk + + # class ::A -> A is in the top level + if name_t.kind_of?(TkCOLON2) + name_t = get_tk + container = @top_level + end + + skip_tkspace(false) + + while peek_tk.kind_of?(TkCOLON2) + prev_container = container + container = container.find_module_named(name_t.name) + if !container +# warn("Couldn't find module #{name_t.name}") + container = prev_container.add_module(NormalModule, name_t.name) + end + get_tk + name_t = get_tk + end + skip_tkspace(false) + return [container, name_t] + end + + def parse_constant(container, single, tk, comment) + name = tk.name + skip_tkspace(false) + eq_tk = get_tk + + unless eq_tk.kind_of?(TkASSIGN) + unget_tk(eq_tk) + return + end + + + nest = 0 + get_tkread + + tk = get_tk + if tk.kind_of? TkGT + unget_tk(tk) + unget_tk(eq_tk) + return + end + + loop do + puts("Param: #{tk}, #{@scanner.continue} " + + "#{@scanner.lex_state} #{nest}") if $DEBUG + + case tk + when TkSEMICOLON + break + when TkLPAREN, TkfLPAREN + nest += 1 + when TkRPAREN + nest -= 1 + when TkCOMMENT + if nest <= 0 && @scanner.lex_state == EXPR_END + unget_tk(tk) + break + end + when TkNL + if (@scanner.lex_state == EXPR_END and nest <= 0) || !@scanner.continue + unget_tk(tk) + break + end + end + tk = get_tk + end + + res = get_tkread.tr("\n", " ").strip + res = "" if res == ";" + con = Constant.new(name, res, comment) + read_documentation_modifiers(con, CONSTANT_MODIFIERS) + if con.document_self + container.add_constant(con) + end + end + + def parse_method(container, single, tk, comment) + progress(".") + @stats.num_methods += 1 + line_no = tk.line_no + column = tk.char_no + + start_collecting_tokens + add_token(tk) + add_token_listener(self) + + @scanner.instance_eval{@lex_state = EXPR_FNAME} + skip_tkspace(false) + name_t = get_tk + back_tk = skip_tkspace + meth = nil + added_container = false + + dot = get_tk + if dot.kind_of?(TkDOT) or dot.kind_of?(TkCOLON2) + @scanner.instance_eval{@lex_state = EXPR_FNAME} + skip_tkspace + name_t2 = get_tk + case name_t + when TkSELF + name = name_t2.name + when TkCONSTANT + name = name_t2.name + prev_container = container + container = container.find_module_named(name_t.name) + if !container + added_container = true + obj = name_t.name.split("::").inject(Object) do |state, item| + state.const_get(item) + end rescue nil + + type = obj.class == Class ? NormalClass : NormalModule + if not [Class, Module].include?(obj.class) + warn("Couldn't find #{name_t.name}. Assuming it's a module") + end + + if type == NormalClass then + container = prev_container.add_class(type, name_t.name, obj.superclass.name) + else + container = prev_container.add_module(type, name_t.name) + end + end + else + # warn("Unexpected token '#{name_t2.inspect}'") + # break + skip_method(container) + return + end + meth = AnyMethod.new(get_tkread, name) + meth.singleton = true + else + unget_tk dot + back_tk.reverse_each do + |tk| + unget_tk tk + end + name = name_t.name + + meth = AnyMethod.new(get_tkread, name) + meth.singleton = (single == SINGLE) + end + + remove_token_listener(self) + + meth.start_collecting_tokens + indent = TkSPACE.new(1,1) + indent.set_text(" " * column) + + meth.add_tokens([TkCOMMENT.new(line_no, + 1, + "# File #{@top_level.file_absolute_name}, line #{line_no}"), + NEWLINE_TOKEN, + indent]) + + meth.add_tokens(@token_stream) + + add_token_listener(meth) + + @scanner.instance_eval{@continue = false} + parse_method_parameters(meth) + + if meth.document_self + container.add_method(meth) + elsif added_container + container.document_self = false + end + + # Having now read the method parameters and documentation modifiers, we + # now know whether we have to rename #initialize to ::new + + if name == "initialize" && !meth.singleton + if meth.dont_rename_initialize + meth.visibility = :protected + else + meth.singleton = true + meth.name = "new" + meth.visibility = :public + end + end + + parse_statements(container, single, meth) + + remove_token_listener(meth) + + # Look for a 'call-seq' in the comment, and override the + # normal parameter stuff + + if comment.sub!(/:?call-seq:(.*?)^\s*\#?\s*$/m, '') + seq = $1 + seq.gsub!(/^\s*\#\s*/, '') + meth.call_seq = seq + end + + meth.comment = comment + + end + + def skip_method(container) + meth = AnyMethod.new("", "anon") + parse_method_parameters(meth) + parse_statements(container, false, meth) + end + + # Capture the method's parameters. Along the way, + # look for a comment containing + # + # # yields: .... + # + # and add this as the block_params for the method + + def parse_method_parameters(method) + res = parse_method_or_yield_parameters(method) + res = "(" + res + ")" unless res[0] == ?( + method.params = res unless method.params + if method.block_params.nil? + skip_tkspace(false) + read_documentation_modifiers(method, METHOD_MODIFIERS) + end + end + + def parse_method_or_yield_parameters(method=nil, modifiers=METHOD_MODIFIERS) + skip_tkspace(false) + tk = get_tk + + # Little hack going on here. In the statement + # f = 2*(1+yield) + # We see the RPAREN as the next token, so we need + # to exit early. This still won't catch all cases + # (such as "a = yield + 1" + end_token = case tk + when TkLPAREN, TkfLPAREN + TkRPAREN + when TkRPAREN + return "" + else + TkNL + end + nest = 0 + + loop do + puts("Param: #{tk.inspect}, #{@scanner.continue} " + + "#{@scanner.lex_state} #{nest}") if $DEBUG + case tk + when TkSEMICOLON + break + when TkLBRACE + nest += 1 + when TkRBRACE + # we might have a.each {|i| yield i } + unget_tk(tk) if nest.zero? + nest -= 1 + break if nest <= 0 + when TkLPAREN, TkfLPAREN + nest += 1 + when end_token + if end_token == TkRPAREN + nest -= 1 + break if @scanner.lex_state == EXPR_END and nest <= 0 + else + break unless @scanner.continue + end + when method && method.block_params.nil? && TkCOMMENT + unget_tk(tk) + read_documentation_modifiers(method, modifiers) + end + tk = get_tk + end + res = get_tkread.tr("\n", " ").strip + res = "" if res == ";" + res + end + + # skip the var [in] part of a 'for' statement + def skip_for_variable + skip_tkspace(false) + tk = get_tk + skip_tkspace(false) + tk = get_tk + unget_tk(tk) unless tk.kind_of?(TkIN) + end + + # while, until, and for have an optional + def skip_optional_do_after_expression + skip_tkspace(false) + tk = get_tk + case tk + when TkLPAREN, TkfLPAREN + end_token = TkRPAREN + else + end_token = TkNL + end + + nest = 0 + @scanner.instance_eval{@continue = false} + + loop do + puts("\nWhile: #{tk}, #{@scanner.continue} " + + "#{@scanner.lex_state} #{nest}") if $DEBUG + case tk + when TkSEMICOLON + break + when TkLPAREN, TkfLPAREN + nest += 1 + when TkDO + break if nest.zero? + when end_token + if end_token == TkRPAREN + nest -= 1 + break if @scanner.lex_state == EXPR_END and nest.zero? + else + break unless @scanner.continue + end + end + tk = get_tk + end + skip_tkspace(false) + if peek_tk.kind_of? TkDO + get_tk + end + end + + # Return a superclass, which can be either a constant + # of an expression + + def get_class_specification + tk = get_tk + return "self" if tk.kind_of?(TkSELF) + + res = "" + while tk.kind_of?(TkCOLON2) || + tk.kind_of?(TkCOLON3) || + tk.kind_of?(TkCONSTANT) + + res += tk.text + tk = get_tk + end + + unget_tk(tk) + skip_tkspace(false) + + get_tkread # empty out read buffer + + tk = get_tk + + case tk + when TkNL, TkCOMMENT, TkSEMICOLON + unget_tk(tk) + return res + end + + res += parse_call_parameters(tk) + res + end + + def parse_call_parameters(tk) + + end_token = case tk + when TkLPAREN, TkfLPAREN + TkRPAREN + when TkRPAREN + return "" + else + TkNL + end + nest = 0 + + loop do + puts("Call param: #{tk}, #{@scanner.continue} " + + "#{@scanner.lex_state} #{nest}") if $DEBUG + case tk + when TkSEMICOLON + break + when TkLPAREN, TkfLPAREN + nest += 1 + when end_token + if end_token == TkRPAREN + nest -= 1 + break if @scanner.lex_state == EXPR_END and nest <= 0 + else + break unless @scanner.continue + end + when TkCOMMENT + unget_tk(tk) + break + end + tk = get_tk + end + res = get_tkread.tr("\n", " ").strip + res = "" if res == ";" + res + end + + + # Parse a constant, which might be qualified by + # one or more class or module names + + def get_constant + res = "" + skip_tkspace(false) + tk = get_tk + + while tk.kind_of?(TkCOLON2) || + tk.kind_of?(TkCOLON3) || + tk.kind_of?(TkCONSTANT) + + res += tk.text + tk = get_tk + end + +# if res.empty? +# warn("Unexpected token #{tk} in constant") +# end + unget_tk(tk) + res + end + + # Get a constant that may be surrounded by parens + + def get_constant_with_optional_parens + skip_tkspace(false) + nest = 0 + while (tk = peek_tk).kind_of?(TkLPAREN) || tk.kind_of?(TkfLPAREN) + get_tk + skip_tkspace(true) + nest += 1 + end + + name = get_constant + + while nest > 0 + skip_tkspace(true) + tk = get_tk + nest -= 1 if tk.kind_of?(TkRPAREN) + end + name + end + + # Directives are modifier comments that can appear after class, module, + # or method names. For example + # + # def fred # :yields: a, b + # + # or + # + # class SM # :nodoc: + # + # we return the directive name and any parameters as a two element array + + def read_directive(allowed) + tk = get_tk + puts "directive: #{tk.inspect}" if $DEBUG + result = nil + if tk.kind_of?(TkCOMMENT) + if tk.text =~ /\s*:?(\w+):\s*(.*)/ + directive = $1.downcase + if allowed.include?(directive) + result = [directive, $2] + end + end + else + unget_tk(tk) + end + result + end + + + def read_documentation_modifiers(context, allow) + dir = read_directive(allow) + + case dir[0] + + when "notnew", "not_new", "not-new" + context.dont_rename_initialize = true + + when "nodoc" + context.document_self = false + if dir[1].downcase == "all" + context.document_children = false + end + + when "doc" + context.document_self = true + context.force_documentation = true + + when "yield", "yields" + unless context.params.nil? + context.params.sub!(/(,|)\s*&\w+/,'') # remove parameter &proc + end + context.block_params = dir[1] + + when "arg", "args" + context.params = dir[1] + end if dir + end + + + # Look for directives in a normal comment block: + # + # #-- - don't display comment from this point forward + # + # + # This routine modifies it's parameter + + def look_for_directives_in(context, comment) + + preprocess = SM::PreProcess.new(@input_file_name, + @options.rdoc_include) + + preprocess.handle(comment) do |directive, param| + case directive + when "stopdoc" + context.stop_doc + "" + when "startdoc" + context.start_doc + context.force_documentation = true + "" + + when "enddoc" + #context.done_documenting = true + #"" + throw :enddoc + + when "main" + options = Options.instance + options.main_page = param + "" + + when "title" + options = Options.instance + options.title = param + "" + + when "section" + context.set_current_section(param, comment) + comment.replace("") # 1.8 doesn't support #clear + break + else + warn "Unrecognized directive '#{directive}'" + break + end + end + + remove_private_comments(comment) + end + + def remove_private_comments(comment) + comment.gsub!(/^#--.*?^#\+\+/m, '') + comment.sub!(/^#--.*/m, '') + end + + + + def get_symbol_or_name + tk = get_tk + case tk + when TkSYMBOL + tk.text.sub(/^:/, '') + when TkId, TkOp + tk.name + when TkSTRING + tk.text + else + raise "Name or symbol expected (got #{tk})" + end + end + + def parse_alias(context, single, tk, comment) + skip_tkspace + if (peek_tk.kind_of? TkLPAREN) + get_tk + skip_tkspace + end + new_name = get_symbol_or_name + @scanner.instance_eval{@lex_state = EXPR_FNAME} + skip_tkspace + if (peek_tk.kind_of? TkCOMMA) + get_tk + skip_tkspace + end + old_name = get_symbol_or_name + + al = Alias.new(get_tkread, old_name, new_name, comment) + read_documentation_modifiers(al, ATTR_MODIFIERS) + if al.document_self + context.add_alias(al) + end + end + + def parse_yield_parameters + parse_method_or_yield_parameters + end + + def parse_yield(context, single, tk, method) + if method.block_params.nil? + get_tkread + @scanner.instance_eval{@continue = false} + method.block_params = parse_yield_parameters + end + end + + def parse_require(context, comment) + skip_tkspace_comment + tk = get_tk + if tk.kind_of? TkLPAREN + skip_tkspace_comment + tk = get_tk + end + + name = nil + case tk + when TkSTRING + name = tk.text +# when TkCONSTANT, TkIDENTIFIER, TkIVAR, TkGVAR +# name = tk.name + when TkDSTRING + warn "Skipping require of dynamic string: #{tk.text}" + # else + # warn "'require' used as variable" + end + if name + context.add_require(Require.new(name, comment)) + else + unget_tk(tk) + end + end + + def parse_include(context, comment) + loop do + skip_tkspace_comment + name = get_constant_with_optional_parens + unless name.empty? + context.add_include(Include.new(name, comment)) + end + return unless peek_tk.kind_of?(TkCOMMA) + get_tk + end + end + + def get_bool + skip_tkspace + tk = get_tk + case tk + when TkTRUE + true + when TkFALSE, TkNIL + false + else + unget_tk tk + true + end + end + + def parse_attr(context, single, tk, comment) + args = parse_symbol_arg(1) + if args.size > 0 + name = args[0] + rw = "R" + skip_tkspace(false) + tk = get_tk + if tk.kind_of? TkCOMMA + rw = "RW" if get_bool + else + unget_tk tk + end + att = Attr.new(get_tkread, name, rw, comment) + read_documentation_modifiers(att, ATTR_MODIFIERS) + if att.document_self + context.add_attribute(att) + end + else + warn("'attr' ignored - looks like a variable") + end + + end + + def parse_visibility(container, single, tk) + singleton = (single == SINGLE) + vis = case tk.name + when "private" then :private + when "protected" then :protected + when "public" then :public + when "private_class_method" + singleton = true + :private + when "public_class_method" + singleton = true + :public + else raise "Invalid visibility: #{tk.name}" + end + + skip_tkspace_comment(false) + case peek_tk + # Ryan Davis suggested the extension to ignore modifiers, because he + # often writes + # + # protected unless $TESTING + # + when TkNL, TkUNLESS_MOD, TkIF_MOD +# error("Missing argument") if singleton + container.ongoing_visibility = vis + else + args = parse_symbol_arg + container.set_visibility_for(args, vis, singleton) + end + end + + def parse_attr_accessor(context, single, tk, comment) + args = parse_symbol_arg + read = get_tkread + rw = "?" + + # If nodoc is given, don't document any of them + + tmp = CodeObject.new + read_documentation_modifiers(tmp, ATTR_MODIFIERS) + return unless tmp.document_self + + case tk.name + when "attr_reader" then rw = "R" + when "attr_writer" then rw = "W" + when "attr_accessor" then rw = "RW" + else + rw = @options.extra_accessor_flags[tk.name] + end + + for name in args + att = Attr.new(get_tkread, name, rw, comment) + context.add_attribute(att) + end + end + + def skip_tkspace_comment(skip_nl = true) + loop do + skip_tkspace(skip_nl) + return unless peek_tk.kind_of? TkCOMMENT + get_tk + end + end + + def parse_symbol_arg(no = nil) + + args = [] + skip_tkspace_comment + case tk = get_tk + when TkLPAREN + loop do + skip_tkspace_comment + if tk1 = parse_symbol_in_arg + args.push tk1 + break if no and args.size >= no + end + + skip_tkspace_comment + case tk2 = get_tk + when TkRPAREN + break + when TkCOMMA + else + warn("unexpected token: '#{tk2.inspect}'") if $DEBUG + break + end + end + else + unget_tk tk + if tk = parse_symbol_in_arg + args.push tk + return args if no and args.size >= no + end + + loop do +# skip_tkspace_comment(false) + skip_tkspace(false) + + tk1 = get_tk + unless tk1.kind_of?(TkCOMMA) + unget_tk tk1 + break + end + + skip_tkspace_comment + if tk = parse_symbol_in_arg + args.push tk + break if no and args.size >= no + end + end + end + args + end + + def parse_symbol_in_arg + case tk = get_tk + when TkSYMBOL + tk.text.sub(/^:/, '') + when TkSTRING + eval @read[-1] + else + warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG + nil + end + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_simple.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_simple.rb new file mode 100644 index 00000000..3f1a5469 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parse_simple.rb @@ -0,0 +1,41 @@ +# Parse a non-source file. We basically take the whole thing +# as one big comment. If the first character in the file +# is '#', we strip leading pound signs. + + +require "rdoc/code_objects" +require "rdoc/markup/simple_markup/preprocess" + +module RDoc + # See rdoc/parsers/parse_c.rb + + class SimpleParser + + # prepare to parse a plain file + def initialize(top_level, file_name, body, options, stats) + + preprocess = SM::PreProcess.new(file_name, options.rdoc_include) + + preprocess.handle(body) do |directive, param| + $stderr.puts "Unrecognized directive '#{directive}' in #{file_name}" + end + + @body = body + @options = options + @top_level = top_level + end + + # Extract the file contents and attach them to the toplevel as a + # comment + + def scan + # @body.gsub(/^(\s\n)+/, '') + @top_level.comment = remove_private_comments(@body) + @top_level + end + + def remove_private_comments(comment) + comment.gsub(/^--.*?^\+\+/m, '').sub(/^--.*/m, '') + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parserfactory.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parserfactory.rb new file mode 100644 index 00000000..00a82cf4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/parsers/parserfactory.rb @@ -0,0 +1,99 @@ +require "rdoc/parsers/parse_simple" + +module RDoc + + # A parser is simple a class that implements + # + # #initialize(file_name, body, options) + # + # and + # + # #scan + # + # The initialize method takes a file name to be used, the body of the + # file, and an RDoc::Options object. The scan method is then called + # to return an appropriately parsed TopLevel code object. + # + # The ParseFactory is used to redirect to the correct parser given a filename + # extension. This magic works because individual parsers have to register + # themselves with us as they are loaded in. The do this using the following + # incantation + # + # + # require "rdoc/parsers/parsefactory" + # + # module RDoc + # + # class XyzParser + # extend ParseFactory <<<< + # parse_files_matching /\.xyz$/ <<<< + # + # def initialize(file_name, body, options) + # ... + # end + # + # def scan + # ... + # end + # end + # end + # + # Just to make life interesting, if we suspect a plain text file, we + # also look for a shebang line just in case it's a potential + # shell script + + + + module ParserFactory + + @@parsers = [] + + Parsers = Struct.new(:regexp, :parser) + + # Record the fact that a particular class parses files that + # match a given extension + + def parse_files_matching(regexp) + @@parsers.unshift Parsers.new(regexp, self) + end + + # Return a parser that can handle a particular extension + + def ParserFactory.can_parse(file_name) + @@parsers.find {|p| p.regexp.match(file_name) } + end + + # Alias an extension to another extension. After this call, + # files ending "new_ext" will be parsed using the same parser + # as "old_ext" + + def ParserFactory.alias_extension(old_ext, new_ext) + parser = ParserFactory.can_parse("xxx.#{old_ext}") + return false unless parser + @@parsers.unshift Parsers.new(Regexp.new("\\.#{new_ext}$"), parser.parser) + true + end + + # Find the correct parser for a particular file name. Return a + # SimpleParser for ones that we don't know + + def ParserFactory.parser_for(top_level, file_name, body, options, stats) + # If no extension, look for shebang + if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)} + shebang = $1 + case shebang + when %r{env\s+ruby}, %r{/ruby} + file_name = "dummy.rb" + end + end + parser_description = can_parse(file_name) + if parser_description + parser = parser_description.parser + else + parser = SimpleParser + end + + parser.new(top_level, file_name, body, options, stats) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/rdoc.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/rdoc.rb new file mode 100644 index 00000000..91f56111 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/rdoc.rb @@ -0,0 +1,298 @@ +# See README. +# + + +VERSION_STRING = %{RDoc V1.0.1 - 20041108} + + +require 'rdoc/parsers/parse_rb.rb' +require 'rdoc/parsers/parse_c.rb' +require 'rdoc/parsers/parse_f95.rb' + +require 'rdoc/parsers/parse_simple.rb' +require 'rdoc/options' + +require 'rdoc/diagram' + +require 'find' +require 'ftools' +require 'time' + +# We put rdoc stuff in the RDoc module to avoid namespace +# clutter. +# +# ToDo: This isn't universally true. +# +# :include: README + +module RDoc + + # Name of the dotfile that contains the description of files to be + # processed in the current directory + DOT_DOC_FILENAME = ".document" + + # Simple stats collector + class Stats + attr_accessor :num_files, :num_classes, :num_modules, :num_methods + def initialize + @num_files = @num_classes = @num_modules = @num_methods = 0 + @start = Time.now + end + def print + puts "Files: #@num_files" + puts "Classes: #@num_classes" + puts "Modules: #@num_modules" + puts "Methods: #@num_methods" + puts "Elapsed: " + sprintf("%0.3fs", Time.now - @start) + end + end + + + # Exception thrown by any rdoc error. Only the #message part is + # of use externally. + + class RDocError < Exception + end + + # Encapsulate the production of rdoc documentation. Basically + # you can use this as you would invoke rdoc from the command + # line: + # + # rdoc = RDoc::RDoc.new + # rdoc.document(args) + # + # where _args_ is an array of strings, each corresponding to + # an argument you'd give rdoc on the command line. See rdoc/rdoc.rb + # for details. + + class RDoc + + ## + # This is the list of output generators that we + # support + + Generator = Struct.new(:file_name, :class_name, :key) + + GENERATORS = {} + $:.collect {|d| + File::expand_path(d) + }.find_all {|d| + File::directory?("#{d}/rdoc/generators") + }.each {|dir| + Dir::entries("#{dir}/rdoc/generators").each {|gen| + next unless /(\w+)_generator.rb$/ =~ gen + type = $1 + unless GENERATORS.has_key? type + GENERATORS[type] = Generator.new("rdoc/generators/#{gen}", + "#{type.upcase}Generator".intern, + type) + end + } + } + + ####### + private + ####### + + ## + # Report an error message and exit + + def error(msg) + raise RDocError.new(msg) + end + + ## + # Create an output dir if it doesn't exist. If it does + # exist, but doesn't contain the flag file created.rid + # then we refuse to use it, as we may clobber some + # manually generated documentation + + def setup_output_dir(op_dir, force) + flag_file = output_flag_file(op_dir) + if File.exist?(op_dir) + unless File.directory?(op_dir) + error "'#{op_dir}' exists, and is not a directory" + end + begin + created = File.read(flag_file) + rescue SystemCallError + error "\nDirectory #{op_dir} already exists, but it looks like it\n" + + "isn't an RDoc directory. Because RDoc doesn't want to risk\n" + + "destroying any of your existing files, you'll need to\n" + + "specify a different output directory name (using the\n" + + "--op option).\n\n" + else + last = (Time.parse(created) unless force rescue nil) + end + else + File.makedirs(op_dir) + end + last + end + + # Update the flag file in an output directory. + def update_output_dir(op_dir, time) + File.open(output_flag_file(op_dir), "w") {|f| f.puts time.rfc2822 } + end + + # Return the path name of the flag file in an output directory. + def output_flag_file(op_dir) + File.join(op_dir, "created.rid") + end + + # The .document file contains a list of file and directory name + # patterns, representing candidates for documentation. It may + # also contain comments (starting with '#') + def parse_dot_doc_file(in_dir, filename, options) + # read and strip comments + patterns = File.read(filename).gsub(/#.*/, '') + + result = [] + + patterns.split.each do |patt| + candidates = Dir.glob(File.join(in_dir, patt)) + result.concat(normalized_file_list(options, candidates)) + end + result + end + + + # Given a list of files and directories, create a list + # of all the Ruby files they contain. + # + # If +force_doc+ is true, we always add the given files. + # If false, only add files that we guarantee we can parse + # It is true when looking at files given on the command line, + # false when recursing through subdirectories. + # + # The effect of this is that if you want a file with a non- + # standard extension parsed, you must name it explicity. + # + + def normalized_file_list(options, relative_files, force_doc = false, exclude_pattern=nil) + file_list = [] + + relative_files.each do |rel_file_name| + next if exclude_pattern && exclude_pattern =~ rel_file_name + stat = File.stat(rel_file_name) + case type = stat.ftype + when "file" + next if @last_created and stat.mtime < @last_created + file_list << rel_file_name.sub(/^\.\//, '') if force_doc || ParserFactory.can_parse(rel_file_name) + when "directory" + next if rel_file_name == "CVS" || rel_file_name == ".svn" + dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME) + if File.file?(dot_doc) + file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options)) + else + file_list.concat(list_files_in_directory(rel_file_name, options)) + end + else + raise RDocError.new("I can't deal with a #{type} #{rel_file_name}") + end + end + file_list + end + + # Return a list of the files to be processed in + # a directory. We know that this directory doesn't have + # a .document file, so we're looking for real files. However + # we may well contain subdirectories which must + # be tested for .document files + def list_files_in_directory(dir, options) + normalized_file_list(options, Dir.glob(File.join(dir, "*")), false, options.exclude) + end + + + # Parse each file on the command line, recursively entering + # directories + + def parse_files(options) + + file_info = [] + + files = options.files + files = ["."] if files.empty? + + file_list = normalized_file_list(options, files, true) + + file_list.each do |fn| + $stderr.printf("\n%35s: ", File.basename(fn)) unless options.quiet + + content = File.open(fn, "r") {|f| f.read} + + top_level = TopLevel.new(fn) + parser = ParserFactory.parser_for(top_level, fn, content, options, @stats) + file_info << parser.scan + @stats.num_files += 1 + end + + file_info + end + + + public + + ################################################################### + # + # Format up one or more files according to the given arguments. + # For simplicity, _argv_ is an array of strings, equivalent to the + # strings that would be passed on the command line. (This isn't a + # coincidence, as we _do_ pass in ARGV when running + # interactively). For a list of options, see rdoc/rdoc.rb. By + # default, output will be stored in a directory called +doc+ below + # the current directory, so make sure you're somewhere writable + # before invoking. + # + # Throws: RDocError on error + + def document(argv) + + TopLevel::reset + + @stats = Stats.new + + options = Options.instance + options.parse(argv, GENERATORS) + + @last_created = nil + unless options.all_one_file + @last_created = setup_output_dir(options.op_dir, options.force_update) + end + start_time = Time.now + + file_info = parse_files(options) + + if file_info.empty? + $stderr.puts "\nNo newer files." unless options.quiet + else + gen = options.generator + + $stderr.puts "\nGenerating #{gen.key.upcase}..." unless options.quiet + + require gen.file_name + + gen_class = Generators.const_get(gen.class_name) + gen = gen_class.for(options) + + pwd = Dir.pwd + + Dir.chdir(options.op_dir) unless options.all_one_file + + begin + Diagram.new(file_info, options).draw if options.diagram + gen.generate(file_info) + update_output_dir(".", start_time) + ensure + Dir.chdir(pwd) + end + end + + unless options.quiet + puts + @stats.print + end + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_cache.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_cache.rb new file mode 100644 index 00000000..1844ac96 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_cache.rb @@ -0,0 +1,187 @@ +module RI + + class ClassEntry + + attr_reader :name + attr_reader :path_names + + def initialize(path_name, name, in_class) + @path_names = [ path_name ] + @name = name + @in_class = in_class + @class_methods = [] + @instance_methods = [] + @inferior_classes = [] + end + + # We found this class in more tha one place, so add + # in the name from there. + def add_path(path) + @path_names << path + end + + # read in our methods and any classes + # and modules in our namespace. Methods are + # stored in files called name-c|i.yaml, + # where the 'name' portion is the external + # form of the method name and the c|i is a class|instance + # flag + + def load_from(dir) + Dir.foreach(dir) do |name| + next if name =~ /^\./ + + # convert from external to internal form, and + # extract the instance/class flag + + if name =~ /^(.*?)-(c|i).yaml$/ + external_name = $1 + is_class_method = $2 == "c" + internal_name = RiWriter.external_to_internal(external_name) + list = is_class_method ? @class_methods : @instance_methods + path = File.join(dir, name) + list << MethodEntry.new(path, internal_name, is_class_method, self) + else + full_name = File.join(dir, name) + if File.directory?(full_name) + inf_class = @inferior_classes.find {|c| c.name == name } + if inf_class + inf_class.add_path(full_name) + else + inf_class = ClassEntry.new(full_name, name, self) + @inferior_classes << inf_class + end + inf_class.load_from(full_name) + end + end + end + end + + # Return a list of any classes or modules that we contain + # that match a given string + + def contained_modules_matching(name) + @inferior_classes.find_all {|c| c.name[name]} + end + + def classes_and_modules + @inferior_classes + end + + # Return an exact match to a particular name + def contained_class_named(name) + @inferior_classes.find {|c| c.name == name} + end + + # return the list of local methods matching name + # We're split into two because we need distinct behavior + # when called from the _toplevel_ + def methods_matching(name, is_class_method) + local_methods_matching(name, is_class_method) + end + + # Find methods matching 'name' in ourselves and in + # any classes we contain + def recursively_find_methods_matching(name, is_class_method) + res = local_methods_matching(name, is_class_method) + @inferior_classes.each do |c| + res.concat(c.recursively_find_methods_matching(name, is_class_method)) + end + res + end + + + # Return our full name + def full_name + res = @in_class.full_name + res << "::" unless res.empty? + res << @name + end + + # Return a list of all out method names + def all_method_names + res = @class_methods.map {|m| m.full_name } + @instance_methods.each {|m| res << m.full_name} + res + end + + private + + # Return a list of all our methods matching a given string. + # Is +is_class_methods+ if 'nil', we don't care if the method + # is a class method or not, otherwise we only return + # those methods that match + def local_methods_matching(name, is_class_method) + + list = case is_class_method + when nil then @class_methods + @instance_methods + when true then @class_methods + when false then @instance_methods + else fail "Unknown is_class_method: #{is_class_method.inspect}" + end + + list.find_all {|m| m.name; m.name[name]} + end + end + + # A TopLevelEntry is like a class entry, but when asked to search + # for methods searches all classes, not just itself + + class TopLevelEntry < ClassEntry + def methods_matching(name, is_class_method) + res = recursively_find_methods_matching(name, is_class_method) + end + + def full_name + "" + end + + def module_named(name) + + end + + end + + class MethodEntry + attr_reader :name + attr_reader :path_name + + def initialize(path_name, name, is_class_method, in_class) + @path_name = path_name + @name = name + @is_class_method = is_class_method + @in_class = in_class + end + + def full_name + res = @in_class.full_name + unless res.empty? + if @is_class_method + res << "::" + else + res << "#" + end + end + res << @name + end + end + + # We represent everything know about all 'ri' files + # accessible to this program + + class RiCache + + attr_reader :toplevel + + def initialize(dirs) + # At the top level we have a dummy module holding the + # overall namespace + @toplevel = TopLevelEntry.new('', '::', nil) + + dirs.each do |dir| + @toplevel.load_from(dir) + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_descriptions.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_descriptions.rb new file mode 100644 index 00000000..e5ea9f2f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_descriptions.rb @@ -0,0 +1,154 @@ +require 'yaml' +require 'rdoc/markup/simple_markup/fragments' + +# Descriptions are created by RDoc (in ri_generator) and +# written out in serialized form into the documentation +# tree. ri then reads these to generate the documentation + +module RI + class NamedThing + attr_reader :name + def initialize(name) + @name = name + end + def <=>(other) + @name <=> other.name + end + + def hash + @name.hash + end + + def eql?(other) + @name.eql?(other) + end + end + +# Alias = Struct.new(:old_name, :new_name) + + class AliasName < NamedThing + end + + class Attribute < NamedThing + attr_reader :rw, :comment + def initialize(name, rw, comment) + super(name) + @rw = rw + @comment = comment + end + end + + class Constant < NamedThing + attr_reader :value, :comment + def initialize(name, value, comment) + super(name) + @value = value + @comment = comment + end + end + + class IncludedModule < NamedThing + end + + + class MethodSummary < NamedThing + def initialize(name="") + super + end + end + + + + class Description + attr_accessor :name + attr_accessor :full_name + attr_accessor :comment + + def serialize + self.to_yaml + end + + def Description.deserialize(from) + YAML.load(from) + end + + def <=>(other) + @name <=> other.name + end + end + + class ModuleDescription < Description + + attr_accessor :class_methods + attr_accessor :instance_methods + attr_accessor :attributes + attr_accessor :constants + attr_accessor :includes + + # merge in another class desscription into this one + def merge_in(old) + merge(@class_methods, old.class_methods) + merge(@instance_methods, old.instance_methods) + merge(@attributes, old.attributes) + merge(@constants, old.constants) + merge(@includes, old.includes) + if @comment.nil? || @comment.empty? + @comment = old.comment + else + unless old.comment.nil? or old.comment.empty? then + @comment << SM::Flow::RULE.new + @comment.concat old.comment + end + end + end + + def display_name + "Module" + end + + # the 'ClassDescription' subclass overrides this + # to format up the name of a parent + def superclass_string + nil + end + + private + + def merge(into, from) + names = {} + into.each {|i| names[i.name] = i } + from.each {|i| names[i.name] = i } + into.replace(names.keys.sort.map {|n| names[n]}) + end + end + + class ClassDescription < ModuleDescription + attr_accessor :superclass + + def display_name + "Class" + end + + def superclass_string + if @superclass && @superclass != "Object" + @superclass + else + nil + end + end + end + + + class MethodDescription < Description + + attr_accessor :is_class_method + attr_accessor :visibility + attr_accessor :block_params + attr_accessor :is_singleton + attr_accessor :aliases + attr_accessor :is_alias_for + attr_accessor :params + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_display.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_display.rb new file mode 100644 index 00000000..67962fc2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_display.rb @@ -0,0 +1,255 @@ +require 'rdoc/ri/ri_util' +require 'rdoc/ri/ri_formatter' +require 'rdoc/ri/ri_options' + + +# This is a kind of 'flag' module. If you want to write your +# own 'ri' display module (perhaps because you'r writing +# an IDE or somesuch beast), you simply write a class +# which implements the various 'display' methods in 'DefaultDisplay', +# and include the 'RiDisplay' module in that class. +# +# To access your class from the command line, you can do +# +# ruby -r ../ri .... +# +# If folks _really_ want to do this from the command line, +# I'll build an option in + +module RiDisplay + @@display_class = nil + + def RiDisplay.append_features(display_class) + @@display_class = display_class + end + + def RiDisplay.new(*args) + @@display_class.new(*args) + end +end + +###################################################################### +# +# A paging display module. Uses the ri_formatter class to do the +# actual presentation +# + +class DefaultDisplay + + include RiDisplay + + def initialize(options) + @options = options + @formatter = @options.formatter.new(@options, " ") + end + + + ###################################################################### + + def display_usage + page do + RI::Options::OptionList.usage(short_form=true) + end + end + + + ###################################################################### + + def display_method_info(method) + page do + @formatter.draw_line(method.full_name) + display_params(method) + @formatter.draw_line + display_flow(method.comment) + if method.aliases && !method.aliases.empty? + @formatter.blankline + aka = "(also known as " + aka << method.aliases.map {|a| a.name }.join(", ") + aka << ")" + @formatter.wrap(aka) + end + end + end + + ###################################################################### + + def display_class_info(klass, ri_reader) + page do + superclass = klass.superclass_string + + if superclass + superclass = " < " + superclass + else + superclass = "" + end + + @formatter.draw_line(klass.display_name + ": " + + klass.full_name + superclass) + + display_flow(klass.comment) + @formatter.draw_line + + unless klass.includes.empty? + @formatter.blankline + @formatter.display_heading("Includes:", 2, "") + incs = [] + klass.includes.each do |inc| + inc_desc = ri_reader.find_class_by_name(inc.name) + if inc_desc + str = inc.name + "(" + str << inc_desc.instance_methods.map{|m| m.name}.join(", ") + str << ")" + incs << str + else + incs << inc.name + end + end + @formatter.wrap(incs.sort.join(', ')) + end + + unless klass.constants.empty? + @formatter.blankline + @formatter.display_heading("Constants:", 2, "") + len = 0 + klass.constants.each { |c| len = c.name.length if c.name.length > len } + len += 2 + klass.constants.each do |c| + @formatter.wrap(c.value, + @formatter.indent+((c.name+":").ljust(len))) + end + end + + unless klass.class_methods.empty? + @formatter.blankline + @formatter.display_heading("Class methods:", 2, "") + @formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', ')) + end + + unless klass.instance_methods.empty? + @formatter.blankline + @formatter.display_heading("Instance methods:", 2, "") + @formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', ')) + end + + unless klass.attributes.empty? + @formatter.blankline + @formatter.wrap("Attributes:", "") + @formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', ')) + end + end + end + + ###################################################################### + + # Display a list of method names + + def display_method_list(methods) + page do + puts "More than one method matched your request. You can refine" + puts "your search by asking for information on one of:\n\n" + @formatter.wrap(methods.map {|m| m.full_name} .join(", ")) + end + end + + ###################################################################### + + def display_class_list(namespaces) + page do + puts "More than one class or module matched your request. You can refine" + puts "your search by asking for information on one of:\n\n" + @formatter.wrap(namespaces.map {|m| m.full_name}.join(", ")) + end + end + + ###################################################################### + + def list_known_classes(classes) + if classes.empty? + warn_no_database + else + page do + @formatter.draw_line("Known classes and modules") + @formatter.blankline + @formatter.wrap(classes.sort.join(", ")) + end + end + end + + ###################################################################### + + def list_known_names(names) + if names.empty? + warn_no_database + else + page do + names.each {|n| @formatter.raw_print_line(n)} + end + end + end + + ###################################################################### + + private + + ###################################################################### + + def page + return yield unless pager = setup_pager + begin + save_stdout = STDOUT.clone + STDOUT.reopen(pager) + yield + ensure + STDOUT.reopen(save_stdout) + save_stdout.close + pager.close + end + end + + ###################################################################### + + def setup_pager + unless @options.use_stdout + for pager in [ ENV['PAGER'], "less", "more", 'pager' ].compact.uniq + return IO.popen(pager, "w") rescue nil + end + @options.use_stdout = true + nil + end + end + + ###################################################################### + + def display_params(method) + + params = method.params + + if params[0,1] == "(" + if method.is_singleton + params = method.full_name + params + else + params = method.name + params + end + end + params.split(/\n/).each do |p| + @formatter.wrap(p) + @formatter.break_to_newline + end + end + ###################################################################### + + def display_flow(flow) + if !flow || flow.empty? + @formatter.wrap("(no description...)") + else + @formatter.display_flow(flow) + end + end + + ###################################################################### + + def warn_no_database + puts "Before using ri, you need to generate documentation" + puts "using 'rdoc' with the --ri option" + end +end # class RiDisplay diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_driver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_driver.rb new file mode 100644 index 00000000..a00f20ee --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_driver.rb @@ -0,0 +1,143 @@ +require 'rdoc/ri/ri_paths' +require 'rdoc/usage' +require 'rdoc/ri/ri_cache' +require 'rdoc/ri/ri_util' +require 'rdoc/ri/ri_reader' +require 'rdoc/ri/ri_formatter' +require 'rdoc/ri/ri_options' + + +###################################################################### + +class RiDriver + + def initialize + @options = RI::Options.instance + + args = ARGV + if ENV["RI"] + args = ENV["RI"].split.concat(ARGV) + end + + @options.parse(args) + + path = @options.path + report_missing_documentation @options.raw_path if path.empty? + + @ri_reader = RI::RiReader.new(RI::RiCache.new(path)) + @display = @options.displayer + end + + # Couldn't find documentation in +path+, so tell the user what to do + + def report_missing_documentation(path) + STDERR.puts "No ri documentation found in:" + path.each do |d| + STDERR.puts " #{d}" + end + STDERR.puts "\nWas rdoc run to create documentation?\n\n" + RDoc::usage("Installing Documentation") + end + + ###################################################################### + + # If the list of matching methods contains exactly one entry, or + # if it contains an entry that exactly matches the requested method, + # then display that entry, otherwise display the list of + # matching method names + + def report_method_stuff(requested_method_name, methods) + if methods.size == 1 + method = @ri_reader.get_method(methods[0]) + @display.display_method_info(method) + else + entries = methods.find_all {|m| m.name == requested_method_name} + if entries.size == 1 + method = @ri_reader.get_method(entries[0]) + @display.display_method_info(method) + else + @display.display_method_list(methods) + end + end + end + + ###################################################################### + + def report_class_stuff(namespaces) + if namespaces.size == 1 + klass = @ri_reader.get_class(namespaces[0]) + @display.display_class_info(klass, @ri_reader) + else +# entries = namespaces.find_all {|m| m.full_name == requested_class_name} +# if entries.size == 1 +# klass = @ri_reader.get_class(entries[0]) +# @display.display_class_info(klass, @ri_reader) +# else + @display.display_class_list(namespaces) +# end + end + end + + ###################################################################### + + + def get_info_for(arg) + desc = NameDescriptor.new(arg) + + namespaces = @ri_reader.top_level_namespace + + for class_name in desc.class_names + namespaces = @ri_reader.lookup_namespace_in(class_name, namespaces) + if namespaces.empty? + raise RiError.new("Nothing known about #{arg}") + end + end + + # at this point, if we have multiple possible namespaces, but one + # is an exact match for our requested class, prune down to just it + + full_class_name = desc.full_class_name + entries = namespaces.find_all {|m| m.full_name == full_class_name} + namespaces = entries if entries.size == 1 + + if desc.method_name.nil? + report_class_stuff(namespaces) + else + methods = @ri_reader.find_methods(desc.method_name, + desc.is_class_method, + namespaces) + + if methods.empty? + raise RiError.new("Nothing known about #{arg}") + else + report_method_stuff(desc.method_name, methods) + end + end + end + + ###################################################################### + + def process_args + if @options.list_classes + classes = @ri_reader.full_class_names + @display.list_known_classes(classes) + elsif @options.list_names + names = @ri_reader.all_names + @display.list_known_names(names) + else + if ARGV.size.zero? + @display.display_usage + else + begin + ARGV.each do |arg| + get_info_for(arg) + end + rescue RiError => e + STDERR.puts(e.message) + exit(1) + end + end + end + end + +end # class RiDriver diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_formatter.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_formatter.rb new file mode 100644 index 00000000..34eb561c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_formatter.rb @@ -0,0 +1,672 @@ +module RI + class TextFormatter + + attr_reader :indent + + def initialize(options, indent) + @options = options + @width = options.width + @indent = indent + end + + + ###################################################################### + + def draw_line(label=nil) + len = @width + len -= (label.size+1) if label + print "-"*len + if label + print(" ") + bold_print(label) + end + puts + end + + ###################################################################### + + def wrap(txt, prefix=@indent, linelen=@width) + return unless txt && !txt.empty? + work = conv_markup(txt) + textLen = linelen - prefix.length + patt = Regexp.new("^(.{0,#{textLen}})[ \n]") + next_prefix = prefix.tr("^ ", " ") + + res = [] + + while work.length > textLen + if work =~ patt + res << $1 + work.slice!(0, $&.length) + else + res << work.slice!(0, textLen) + end + end + res << work if work.length.nonzero? + puts(prefix + res.join("\n" + next_prefix)) + end + + ###################################################################### + + def blankline + puts + end + + ###################################################################### + + # called when we want to ensure a nbew 'wrap' starts on a newline + # Only needed for HtmlFormatter, because the rest do their + # own line breaking + + def break_to_newline + end + + ###################################################################### + + def bold_print(txt) + print txt + end + + ###################################################################### + + def raw_print_line(txt) + puts txt + end + + ###################################################################### + + # convert HTML entities back to ASCII + def conv_html(txt) + txt. + gsub(/>/, '>'). + gsub(/</, '<'). + gsub(/"/, '"'). + gsub(/&/, '&') + + end + + # convert markup into display form + def conv_markup(txt) + txt. + gsub(%r{(.*?)}) { "+#$1+" } . + gsub(%r{(.*?)}) { "+#$1+" } . + gsub(%r{(.*?)}) { "*#$1*" } . + gsub(%r{(.*?)}) { "_#$1_" } + end + + ###################################################################### + + def display_list(list) + case list.type + + when SM::ListBase::BULLET + prefixer = proc { |ignored| @indent + "* " } + + when SM::ListBase::NUMBER, + SM::ListBase::UPPERALPHA, + SM::ListBase::LOWERALPHA + + start = case list.type + when SM::ListBase::NUMBER then 1 + when SM::ListBase::UPPERALPHA then 'A' + when SM::ListBase::LOWERALPHA then 'a' + end + prefixer = proc do |ignored| + res = @indent + "#{start}.".ljust(4) + start = start.succ + res + end + + when SM::ListBase::LABELED + prefixer = proc do |li| + li.label + end + + when SM::ListBase::NOTE + longest = 0 + list.contents.each do |item| + if item.kind_of?(SM::Flow::LI) && item.label.length > longest + longest = item.label.length + end + end + + prefixer = proc do |li| + @indent + li.label.ljust(longest+1) + end + + else + fail "unknown list type" + + end + + list.contents.each do |item| + if item.kind_of? SM::Flow::LI + prefix = prefixer.call(item) + display_flow_item(item, prefix) + else + display_flow_item(item) + end + end + end + + ###################################################################### + + def display_flow_item(item, prefix=@indent) + case item + when SM::Flow::P, SM::Flow::LI + wrap(conv_html(item.body), prefix) + blankline + + when SM::Flow::LIST + display_list(item) + + when SM::Flow::VERB + display_verbatim_flow_item(item, @indent) + + when SM::Flow::H + display_heading(conv_html(item.text), item.level, @indent) + + when SM::Flow::RULE + draw_line + + else + fail "Unknown flow element: #{item.class}" + end + end + + ###################################################################### + + def display_verbatim_flow_item(item, prefix=@indent) + item.body.split(/\n/).each do |line| + print @indent, conv_html(line), "\n" + end + blankline + end + + ###################################################################### + + def display_heading(text, level, indent) + text = strip_attributes(text) + case level + when 1 + ul = "=" * text.length + puts + puts text.upcase + puts ul +# puts + + when 2 + ul = "-" * text.length + puts + puts text + puts ul +# puts + else + print indent, text, "\n" + end + end + + + def display_flow(flow) + flow.each do |f| + display_flow_item(f) + end + end + + def strip_attributes(txt) + tokens = txt.split(%r{()}) + text = [] + attributes = 0 + tokens.each do |tok| + case tok + when %r{^$}, %r{^<(\w+)>$} + ; + else + text << tok + end + end + text.join + end + + + end + + + ###################################################################### + # Handle text with attributes. We're a base class: there are + # different presentation classes (one, for example, uses overstrikes + # to handle bold and underlining, while another using ANSI escape + # sequences + + class AttributeFormatter < TextFormatter + + BOLD = 1 + ITALIC = 2 + CODE = 4 + + ATTR_MAP = { + "b" => BOLD, + "code" => CODE, + "em" => ITALIC, + "i" => ITALIC, + "tt" => CODE + } + + # TODO: struct? + class AttrChar + attr_reader :char + attr_reader :attr + + def initialize(char, attr) + @char = char + @attr = attr + end + end + + + class AttributeString + attr_reader :txt + + def initialize + @txt = [] + @optr = 0 + end + + def <<(char) + @txt << char + end + + def empty? + @optr >= @txt.length + end + + # accept non space, then all following spaces + def next_word + start = @optr + len = @txt.length + + while @optr < len && @txt[@optr].char != " " + @optr += 1 + end + + while @optr < len && @txt[@optr].char == " " + @optr += 1 + end + + @txt[start...@optr] + end + end + + ###################################################################### + # overrides base class. Looks for ... etc sequences + # and generates an array of AttrChars. This array is then used + # as the basis for the split + + def wrap(txt, prefix=@indent, linelen=@width) + return unless txt && !txt.empty? + + txt = add_attributes_to(txt) + next_prefix = prefix.tr("^ ", " ") + linelen -= prefix.size + + line = [] + + until txt.empty? + word = txt.next_word + if word.size + line.size > linelen + write_attribute_text(prefix, line) + prefix = next_prefix + line = [] + end + line.concat(word) + end + + write_attribute_text(prefix, line) if line.length > 0 + end + + protected + + # overridden in specific formatters + + def write_attribute_text(prefix, line) + print prefix + line.each do |achar| + print achar.char + end + puts + end + + # again, overridden + + def bold_print(txt) + print txt + end + + private + + def add_attributes_to(txt) + tokens = txt.split(%r{()}) + text = AttributeString.new + attributes = 0 + tokens.each do |tok| + case tok + when %r{^$} then attributes &= ~(ATTR_MAP[$1]||0) + when %r{^<(\w+)>$} then attributes |= (ATTR_MAP[$1]||0) + else + tok.split(//).each {|ch| text << AttrChar.new(ch, attributes)} + end + end + text + end + + end + + + ################################################## + + # This formatter generates overstrike-style formatting, which + # works with pagers such as man and less. + + class OverstrikeFormatter < AttributeFormatter + + BS = "\C-h" + + def write_attribute_text(prefix, line) + print prefix + line.each do |achar| + attr = achar.attr + if (attr & (ITALIC+CODE)) != 0 + print "_", BS + end + if (attr & BOLD) != 0 + print achar.char, BS + end + print achar.char + end + puts + end + + # draw a string in bold + def bold_print(text) + text.split(//).each do |ch| + print ch, BS, ch + end + end + end + + ################################################## + + # This formatter uses ANSI escape sequences + # to colorize stuff + # works with pages such as man and less. + + class AnsiFormatter < AttributeFormatter + + def initialize(*args) + print "\033[0m" + super + end + + def write_attribute_text(prefix, line) + print prefix + curr_attr = 0 + line.each do |achar| + attr = achar.attr + if achar.attr != curr_attr + update_attributes(achar.attr) + curr_attr = achar.attr + end + print achar.char + end + update_attributes(0) unless curr_attr.zero? + puts + end + + + def bold_print(txt) + print "\033[1m#{txt}\033[m" + end + + HEADINGS = { + 1 => [ "\033[1;32m", "\033[m" ] , + 2 => ["\033[4;32m", "\033[m" ], + 3 => ["\033[32m", "\033[m" ] + } + + def display_heading(text, level, indent) + level = 3 if level > 3 + heading = HEADINGS[level] + print indent + print heading[0] + print strip_attributes(text) + puts heading[1] + end + + private + + ATTR_MAP = { + BOLD => "1", + ITALIC => "33", + CODE => "36" + } + + def update_attributes(attr) + str = "\033[" + for quality in [ BOLD, ITALIC, CODE] + unless (attr & quality).zero? + str << ATTR_MAP[quality] + end + end + print str, "m" + end + end + + ################################################## + + # This formatter uses HTML. + + class HtmlFormatter < AttributeFormatter + + def initialize(*args) + super + end + + def write_attribute_text(prefix, line) + curr_attr = 0 + line.each do |achar| + attr = achar.attr + if achar.attr != curr_attr + update_attributes(curr_attr, achar.attr) + curr_attr = achar.attr + end + print(escape(achar.char)) + end + update_attributes(curr_attr, 0) unless curr_attr.zero? + end + + def draw_line(label=nil) + if label != nil + bold_print(label) + end + puts("
    ") + end + + def bold_print(txt) + tag("b") { txt } + end + + def blankline() + puts("

    ") + end + + def break_to_newline + puts("
    ") + end + + def display_heading(text, level, indent) + level = 4 if level > 4 + tag("h#{level}") { text } + puts + end + + ###################################################################### + + def display_list(list) + + case list.type + when SM::ListBase::BULLET + list_type = "ul" + prefixer = proc { |ignored| "

  • " } + + when SM::ListBase::NUMBER, + SM::ListBase::UPPERALPHA, + SM::ListBase::LOWERALPHA + list_type = "ol" + prefixer = proc { |ignored| "
  • " } + + when SM::ListBase::LABELED + list_type = "dl" + prefixer = proc do |li| + "
    " + escape(li.label) + "
    " + end + + when SM::ListBase::NOTE + list_type = "table" + prefixer = proc do |li| + %{#{li.label.gsub(/ /, ' ')}} + end + else + fail "unknown list type" + end + + print "<#{list_type}>" + list.contents.each do |item| + if item.kind_of? SM::Flow::LI + prefix = prefixer.call(item) + print prefix + display_flow_item(item, prefix) + else + display_flow_item(item) + end + end + print "" + end + + def display_verbatim_flow_item(item, prefix=@indent) + print("
    ")
    +        puts item.body
    +        puts("
    ") + end + + private + + ATTR_MAP = { + BOLD => "b>", + ITALIC => "i>", + CODE => "tt>" + } + + def update_attributes(current, wanted) + str = "" + # first turn off unwanted ones + off = current & ~wanted + for quality in [ BOLD, ITALIC, CODE] + if (off & quality) > 0 + str << "") + print(yield) + print("") + end + + def escape(str) + str. + gsub(/&/n, '&'). + gsub(/\"/n, '"'). + gsub(/>/n, '>'). + gsub(/ AnsiFormatter, + "bs" => OverstrikeFormatter, + "html" => HtmlFormatter, + "plain" => TextFormatter, + "simple" => SimpleFormatter, + } + + def TextFormatter.list + FORMATTERS.keys.sort.join(", ") + end + + def TextFormatter.for(name) + FORMATTERS[name.downcase] + end + + end + +end + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_options.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_options.rb new file mode 100644 index 00000000..db9f4afe --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_options.rb @@ -0,0 +1,313 @@ +# We handle the parsing of options, and subsequently as a singleton +# object to be queried for option values + +module RI + + require 'rdoc/ri/ri_paths' + require 'rdoc/ri/ri_display' + + VERSION_STRING = "ri v1.0.1 - 20041108" + + class Options + + require 'singleton' + require 'getoptlong' + + include Singleton + + # No not use a pager. Writable, because ri sets it if it + # can't find a pager + attr_accessor :use_stdout + + # should we just display a class list and exit + attr_reader :list_classes + + # should we display a list of all names + attr_reader :list_names + + # The width of the output line + attr_reader :width + + # the formatting we apply to the output + attr_reader :formatter + + # the directory we search for original documentation + attr_reader :doc_dir + + module OptionList + + OPTION_LIST = [ + [ "--help", "-h", nil, + "you're looking at it" ], + + [ "--classes", "-c", nil, + "Display the names of classes and modules we\n" + + "know about"], + + [ "--doc-dir", "-d", "", + "A directory to search for documentation. If not\n" + + "specified, we search the standard rdoc/ri directories.\n" + + "May be repeated."], + + [ "--system", nil, nil, + "Include documentation from Ruby's standard library:\n " + + RI::Paths::SYSDIR ], + + [ "--site", nil, nil, + "Include documentation from libraries installed in site_lib:\n " + + RI::Paths::SITEDIR ], + + [ "--home", nil, nil, + "Include documentation stored in ~/.rdoc:\n " + + (RI::Paths::HOMEDIR || "No ~/.rdoc found") ], + + [ "--gems", nil, nil, + "Include documentation from Rubygems:\n " + + (RI::Paths::GEMDIRS ? "#{Gem.path}/doc/*/ri" : + "No Rubygems ri found.") ], + + [ "--format", "-f", "", + "Format to use when displaying output:\n" + + " " + RI::TextFormatter.list + "\n" + + "Use 'bs' (backspace) with most pager programs.\n" + + "To use ANSI, either also use the -T option, or\n" + + "tell your pager to allow control characters\n" + + "(for example using the -R option to less)"], + + [ "--list-names", "-l", nil, + "List all the names known to RDoc, one per line" + ], + + [ "--no-pager", "-T", nil, + "Send output directly to stdout." + ], + + [ "--width", "-w", "output width", + "Set the width of the output" ], + + [ "--version", "-v", nil, + "Display the version of ri" + ], + + ] + + def OptionList.options + OPTION_LIST.map do |long, short, arg,| + option = [] + option << long + option << short unless short.nil? + option << (arg ? GetoptLong::REQUIRED_ARGUMENT : + GetoptLong::NO_ARGUMENT) + option + end + end + + + def OptionList.strip_output(text) + text =~ /^\s+/ + leading_spaces = $& + text.gsub!(/^#{leading_spaces}/, '') + $stdout.puts text + end + + + # Show an error and exit + + def OptionList.error(msg) + $stderr.puts + $stderr.puts msg + $stderr.puts "\nFor help on options, try 'ri --help'\n\n" + exit 1 + end + + # Show usage and exit + + def OptionList.usage(short_form=false) + + puts + puts(RI::VERSION_STRING) + puts + + name = File.basename($0) + + directories = [ + RI::Paths::SYSDIR, + RI::Paths::SITEDIR, + RI::Paths::HOMEDIR + ] + + directories << "#{Gem.path}/doc/*/ri" if RI::Paths::GEMDIRS + + directories = directories.join("\n ") + + OptionList.strip_output(<<-EOT) + Usage: + + #{name} [options] [names...] + + Display information on Ruby classes, modules, and methods. + Give the names of classes or methods to see their documentation. + Partial names may be given: if the names match more than + one entity, a list will be shown, otherwise details on + that entity will be displayed. + + Nested classes and modules can be specified using the normal + Name::Name notation, and instance methods can be distinguished + from class methods using "." (or "#") instead of "::". + + For example: + + ri File + ri File.new + ri F.n + ri zip + + Note that shell quoting may be required for method names + containing punctuation: + + ri 'Array.[]' + ri compact\\! + + By default ri searches for documentation in the following + directories: + + #{directories} + + Specifying the --system, --site, --home, --gems or --doc-dir + options will limit ri to searching only the specified + directories. + + EOT + + if short_form + puts "For help on options, type 'ri -h'" + puts "For a list of classes I know about, type 'ri -c'" + else + puts "Options:\n\n" + OPTION_LIST.each do|long, short, arg, desc| + opt = '' + opt << (short ? sprintf("%15s", "#{long}, #{short}") : + sprintf("%15s", long)) + if arg + opt << " " << arg + end + print opt + desc = desc.split("\n") + if opt.size < 17 + print " "*(18-opt.size) + puts desc.shift + else + puts + end + desc.each do |line| + puts(" "*18 + line) + end + puts + end + puts "Options may also be passed in the 'RI' environment variable" + exit 0 + end + end + end + + # Show the version and exit + def show_version + puts VERSION_STRING + exit(0) + end + + def initialize + @use_stdout = !STDOUT.tty? + @width = 72 + @formatter = RI::TextFormatter.for("plain") + @list_classes = false + @list_names = false + + # By default all paths are used. If any of these are true, only those + # directories are used. + @use_system = false + @use_site = false + @use_home = false + @use_gems = false + @doc_dirs = [] + end + + # Parse command line options. + + def parse(args) + + old_argv = ARGV.dup + + ARGV.replace(args) + + begin + + go = GetoptLong.new(*OptionList.options) + go.quiet = true + + go.each do |opt, arg| + case opt + when "--help" then OptionList.usage + when "--version" then show_version + when "--list-names" then @list_names = true + when "--no-pager" then @use_stdout = true + when "--classes" then @list_classes = true + + when "--system" then @use_system = true + when "--site" then @use_site = true + when "--home" then @use_home = true + when "--gems" then @use_gems = true + + when "--doc-dir" + if File.directory?(arg) + @doc_dirs << arg + else + $stderr.puts "Invalid directory: #{arg}" + exit 1 + end + + when "--format" + @formatter = RI::TextFormatter.for(arg) + unless @formatter + $stderr.print "Invalid formatter (should be one of " + $stderr.puts RI::TextFormatter.list + ")" + exit 1 + end + when "--width" + begin + @width = Integer(arg) + rescue + $stderr.puts "Invalid width: '#{arg}'" + exit 1 + end + end + end + + rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error + OptionList.error(error.message) + + end + end + + # Return the selected documentation directories. + + def path + RI::Paths.path(@use_system, @use_site, @use_home, @use_gems, *@doc_dirs) + end + + def raw_path + RI::Paths.raw_path(@use_system, @use_site, @use_home, @use_gems, + *@doc_dirs) + end + + # Return an instance of the displayer (the thing that actually writes + # the information). This allows us to load in new displayer classes + # at runtime (for example to help with IDE integration) + + def displayer + ::RiDisplay.new(self) + end + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_paths.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_paths.rb new file mode 100644 index 00000000..32363bf7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_paths.rb @@ -0,0 +1,80 @@ +module RI + + # Encapsulate all the strangeness to do with finding out + # where to find RDoc files + # + # We basically deal with three directories: + # + # 1. The 'system' documentation directory, which holds + # the documentation distributed with Ruby, and which + # is managed by the Ruby install process + # 2. The 'site' directory, which contains site-wide + # documentation added locally. + # 3. The 'user' documentation directory, stored under the + # user's own home directory. + # + # There's contention about all this, but for now: + # + # system:: $datadir/ri//system/... + # site:: $datadir/ri//site/... + # user:: ~/.rdoc + + module Paths + + #:stopdoc: + require 'rbconfig' + + DOC_DIR = "doc/rdoc" + + version = Config::CONFIG['ruby_version'] + + base = File.join(Config::CONFIG['datadir'], "ri", version) + SYSDIR = File.join(base, "system") + SITEDIR = File.join(base, "site") + homedir = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH'] + + if homedir + HOMEDIR = File.join(homedir, ".rdoc") + else + HOMEDIR = nil + end + + # This is the search path for 'ri' + PATH = [ SYSDIR, SITEDIR, HOMEDIR ].find_all {|p| p && File.directory?(p)} + + begin + require 'rubygems' + GEMDIRS = Dir["#{Gem.path}/doc/*/ri"] + GEMDIRS.each { |path| RI::Paths::PATH << path } + rescue LoadError + GEMDIRS = nil + end + + # Returns the selected documentation directories as an Array, or PATH if no + # overriding directories were given. + + def self.path(use_system, use_site, use_home, use_gems, *extra_dirs) + path = raw_path(use_system, use_site, use_home, use_gems, *extra_dirs) + return path.select { |path| File.directory? path } + end + + # Returns the selected documentation directories including nonexistent + # directories. Used to print out what paths were searched if no ri was + # found. + + def self.raw_path(use_system, use_site, use_home, use_gems, *extra_dirs) + return PATH unless use_system or use_site or use_home or use_gems or + not extra_dirs.empty? + + path = [] + path << extra_dirs unless extra_dirs.empty? + path << RI::Paths::SYSDIR if use_system + path << RI::Paths::SITEDIR if use_site + path << RI::Paths::HOMEDIR if use_home + path << RI::Paths::GEMDIRS if use_gems + + return path.flatten.compact + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_reader.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_reader.rb new file mode 100644 index 00000000..fb2c373e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_reader.rb @@ -0,0 +1,100 @@ +require 'rdoc/ri/ri_descriptions' +require 'rdoc/ri/ri_writer' +require 'rdoc/markup/simple_markup/to_flow' + +module RI + class RiReader + + def initialize(ri_cache) + @cache = ri_cache + end + + def top_level_namespace + [ @cache.toplevel ] + end + + def lookup_namespace_in(target, namespaces) + result = [] + for n in namespaces + result.concat(n.contained_modules_matching(target)) + end + result + end + + def find_class_by_name(full_name) + names = full_name.split(/::/) + ns = @cache.toplevel + for name in names + ns = ns.contained_class_named(name) + return nil if ns.nil? + end + get_class(ns) + end + + def find_methods(name, is_class_method, namespaces) + result = [] + namespaces.each do |ns| + result.concat ns.methods_matching(name, is_class_method) + end + result + end + + # return the MethodDescription for a given MethodEntry + # by deserializing the YAML + def get_method(method_entry) + path = method_entry.path_name + File.open(path) { |f| RI::Description.deserialize(f) } + end + + # Return a class description + def get_class(class_entry) + result = nil + for path in class_entry.path_names + path = RiWriter.class_desc_path(path, class_entry) + desc = File.open(path) {|f| RI::Description.deserialize(f) } + if result + result.merge_in(desc) + else + result = desc + end + end + result + end + + # return the names of all classes and modules + def full_class_names + res = [] + find_classes_in(res, @cache.toplevel) + end + + # return a list of all classes, modules, and methods + def all_names + res = [] + find_names_in(res, @cache.toplevel) + end + + # ---- + private + # ---- + + def find_classes_in(res, klass) + classes = klass.classes_and_modules + for c in classes + res << c.full_name + find_classes_in(res, c) + end + res + end + + def find_names_in(res, klass) + classes = klass.classes_and_modules + for c in classes + res << c.full_name + res.concat c.all_method_names + find_names_in(res, c) + end + res + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_util.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_util.rb new file mode 100644 index 00000000..8a012558 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_util.rb @@ -0,0 +1,75 @@ +###################################################################### + +class RiError < Exception; end +# +# Break argument into its constituent class or module names, an +# optional method type, and a method name + +class NameDescriptor + + attr_reader :class_names + attr_reader :method_name + + # true and false have the obvious meaning. nil means we don't care + attr_reader :is_class_method + + # arg may be + # 1. a class or module name (optionally qualified with other class + # or module names (Kernel, File::Stat etc) + # 2. a method name + # 3. a method name qualified by a optionally fully qualified class + # or module name + # + # We're fairly casual about delimiters: folks can say Kernel::puts, + # Kernel.puts, or Kernel\#puts for example. There's one exception: + # if you say IO::read, we look for a class method, but if you + # say IO.read, we look for an instance method + + def initialize(arg) + @class_names = [] + separator = nil + + tokens = arg.split(/(\.|::|#)/) + + # Skip leading '::', '#' or '.', but remember it might + # be a method name qualifier + separator = tokens.shift if tokens[0] =~ /^(\.|::|#)/ + + # Skip leading '::', but remember we potentially have an inst + + # leading stuff must be class names + + while tokens[0] =~ /^[A-Z]/ + @class_names << tokens.shift + unless tokens.empty? + separator = tokens.shift + break unless separator == "::" + end + end + + # Now must have a single token, the method name, or an empty + # array + unless tokens.empty? + @method_name = tokens.shift + # We may now have a trailing !, ?, or = to roll into + # the method name + if !tokens.empty? && tokens[0] =~ /^[!?=]$/ + @method_name << tokens.shift + end + + if @method_name =~ /::|\.|#/ or !tokens.empty? + raise RiError.new("Bad argument: #{arg}") + end + if separator && separator != '.' + @is_class_method = separator == "::" + end + end + end + + # Return the full class name (with '::' between the components) + # or "" if there's no class name + + def full_class_name + @class_names.join("::") + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_writer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_writer.rb new file mode 100644 index 00000000..78c68e84 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/ri/ri_writer.rb @@ -0,0 +1,62 @@ +require 'fileutils' + +module RI + class RiWriter + + def RiWriter.class_desc_path(dir, class_desc) + File.join(dir, "cdesc-" + class_desc.name + ".yaml") + end + + + # Convert a name from internal form (containing punctuation) + # to an external form (where punctuation is replaced + # by %xx) + + def RiWriter.internal_to_external(name) + name.gsub(/\W/) { sprintf("%%%02x", $&[0]) } + end + + # And the reverse operation + def RiWriter.external_to_internal(name) + name.gsub(/%([0-9a-f]{2,2})/) { $1.to_i(16).chr } + end + + def initialize(base_dir) + @base_dir = base_dir + end + + def remove_class(class_desc) + FileUtils.rm_rf(path_to_dir(class_desc.full_name)) + end + + def add_class(class_desc) + dir = path_to_dir(class_desc.full_name) + FileUtils.mkdir_p(dir) + class_file_name = RiWriter.class_desc_path(dir, class_desc) + File.open(class_file_name, "w") do |f| + f.write(class_desc.serialize) + end + end + + def add_method(class_desc, method_desc) + dir = path_to_dir(class_desc.full_name) + file_name = RiWriter.internal_to_external(method_desc.name) + meth_file_name = File.join(dir, file_name) + if method_desc.is_singleton + meth_file_name += "-c.yaml" + else + meth_file_name += "-i.yaml" + end + + File.open(meth_file_name, "w") do |f| + f.write(method_desc.serialize) + end + end + + private + + def path_to_dir(class_name) + File.join(@base_dir, *class_name.split('::')) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/template.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/template.rb new file mode 100644 index 00000000..469e10fb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/template.rb @@ -0,0 +1,234 @@ +# Cheap-n-cheerful HTML page template system. You create a +# template containing: +# +# * variable names between percent signs (%fred%) +# * blocks of repeating stuff: +# +# START:key +# ... stuff +# END:key +# +# You feed the code a hash. For simple variables, the values +# are resolved directly from the hash. For blocks, the hash entry +# corresponding to +key+ will be an array of hashes. The block will +# be generated once for each entry. Blocks can be nested arbitrarily +# deeply. +# +# The template may also contain +# +# IF:key +# ... stuff +# ENDIF:key +# +# _stuff_ will only be included in the output if the corresponding +# key is set in the value hash. +# +# Usage: Given a set of templates T1, T2, etc +# +# values = { "name" => "Dave", state => "TX" } +# +# t = TemplatePage.new(T1, T2, T3) +# File.open(name, "w") {|f| t.write_html_on(f, values)} +# or +# res = '' +# t.write_html_on(res, values) +# +# + +class TemplatePage + + ########## + # A context holds a stack of key/value pairs (like a symbol + # table). When asked to resolve a key, it first searches the top of + # the stack, then the next level, and so on until it finds a match + # (or runs out of entries) + + class Context + def initialize + @stack = [] + end + + def push(hash) + @stack.push(hash) + end + + def pop + @stack.pop + end + + # Find a scalar value, throwing an exception if not found. This + # method is used when substituting the %xxx% constructs + + def find_scalar(key) + @stack.reverse_each do |level| + if val = level[key] + return val unless val.kind_of? Array + end + end + raise "Template error: can't find variable '#{key}'" + end + + # Lookup any key in the stack of hashes + + def lookup(key) + @stack.reverse_each do |level| + val = level[key] + return val if val + end + nil + end + end + + ######### + # Simple class to read lines out of a string + + class LineReader + # we're initialized with an array of lines + def initialize(lines) + @lines = lines + end + + # read the next line + def read + @lines.shift + end + + # Return a list of lines up to the line that matches + # a pattern. That last line is discarded. + def read_up_to(pattern) + res = [] + while line = read + if pattern.match(line) + return LineReader.new(res) + else + res << line + end + end + raise "Missing end tag in template: #{pattern.source}" + end + + # Return a copy of ourselves that can be modified without + # affecting us + def dup + LineReader.new(@lines.dup) + end + end + + + + # +templates+ is an array of strings containing the templates. + # We start at the first, and substitute in subsequent ones + # where the string !INCLUDE! occurs. For example, + # we could have the overall page template containing + # + # + #

    Master

    + # !INCLUDE! + # + # + # and substitute subpages in to it by passing [master, sub_page]. + # This gives us a cheap way of framing pages + + def initialize(*templates) + result = "!INCLUDE!" + templates.each do |content| + result.sub!(/!INCLUDE!/, content) + end + @lines = LineReader.new(result.split($/)) + end + + # Render the templates into HTML, storing the result on +op+ + # using the method <<. The value_hash contains + # key/value pairs used to drive the substitution (as described above) + + def write_html_on(op, value_hash) + @context = Context.new + op << substitute_into(@lines, value_hash).tr("\000", '\\') + end + + + # Substitute a set of key/value pairs into the given template. + # Keys with scalar values have them substituted directly into + # the page. Those with array values invoke substitute_array + # (below), which examples a block of the template once for each + # row in the array. + # + # This routine also copes with the IF:_key_ directive, + # removing chunks of the template if the corresponding key + # does not appear in the hash, and the START: directive, which + # loops its contents for each value in an array + + def substitute_into(lines, values) + @context.push(values) + skip_to = nil + result = [] + + while line = lines.read + + case line + + when /^IF:(\w+)/ + lines.read_up_to(/^ENDIF:#$1/) unless @context.lookup($1) + + when /^IFNOT:(\w+)/ + lines.read_up_to(/^ENDIF:#$1/) if @context.lookup($1) + + when /^ENDIF:/ + ; + + when /^START:(\w+)/ + tag = $1 + body = lines.read_up_to(/^END:#{tag}/) + inner_values = @context.lookup(tag) + raise "unknown tag: #{tag}" unless inner_values + raise "not array: #{tag}" unless inner_values.kind_of?(Array) + inner_values.each do |vals| + result << substitute_into(body.dup, vals) + end + else + result << expand_line(line.dup) + end + end + + @context.pop + + result.join("\n") + end + + # Given an individual line, we look for %xxx% constructs and + # HREF:ref:name: constructs, substituting for each. + + def expand_line(line) + # Generate a cross reference if a reference is given, + # otherwise just fill in the name part + + line.gsub!(/HREF:(\w+?):(\w+?):/) { + ref = @context.lookup($1) + name = @context.find_scalar($2) + + if ref and !ref.kind_of?(Array) + "#{name}" + else + name + end + } + + # Substitute in values for %xxx% constructs. This is made complex + # because the replacement string may contain characters that are + # meaningful to the regexp (like \1) + + line = line.gsub(/%([a-zA-Z]\w*)%/) { + val = @context.find_scalar($1) + val.tr('\\', "\000") + } + + + line + rescue Exception => e + $stderr.puts "Error in template: #{e}" + $stderr.puts "Original line: #{line}" + exit + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/tokenstream.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/tokenstream.rb new file mode 100644 index 00000000..0a0720d8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/tokenstream.rb @@ -0,0 +1,25 @@ +# A TokenStream is a list of tokens, gathered during the parse +# of some entity (say a method). Entities populate these streams +# by being registered with the lexer. Any class can collect tokens +# by including TokenStream. From the outside, you use such an object +# by calling the start_collecting_tokens method, followed by calls +# to add_token and pop_token + +module TokenStream + def token_stream + @token_stream + end + + def start_collecting_tokens + @token_stream = [] + end + def add_token(tk) + @token_stream << tk + end + def add_tokens(tks) + tks.each {|tk| add_token(tk)} + end + def pop_token + @token_stream.pop + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/usage.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/usage.rb new file mode 100644 index 00000000..def516b3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rdoc/usage.rb @@ -0,0 +1,210 @@ +# = Synopsis +# +# This library allows command-line tools to encapsulate their usage +# as a comment at the top of the main file. Calling RDoc::usage +# then displays some or all of that comment, and optionally exits +# the program with an exit status. We always look for the comment +# in the main program file, so it is safe to call this method +# from anywhere in the executing program. +# +# = Usage +# +# RDoc::usage( [ exit_status ], [ section, ...]) +# RDoc::usage_no_exit( [ section, ...]) +# +# where: +# +# exit_status:: +# the integer exit code (default zero). RDoc::usage will exit +# the calling program with this status. +# +# section:: +# an optional list of section names. If specified, only the +# sections with the given names as headings will be output. +# For example, this section is named 'Usage', and the next +# section is named 'Examples'. The section names are case +# insensitive. +# +# = Examples +# +# # Comment block describing usage +# # with (optional) section headings +# # . . . +# +# require 'rdoc/usage' +# +# # Display all usage and exit with a status of 0 +# +# RDoc::usage +# +# # Display all usage and exit with a status of 99 +# +# RDoc::usage(99) +# +# # Display usage in the 'Summary' section only, then +# # exit with a status of 99 +# +# RDoc::usage(99, 'Summary') +# +# # Display information in the Author and Copyright +# # sections, then exit 0. +# +# RDoc::usage('Author', 'Copyright') +# +# # Display information in the Author and Copyright +# # sections, but don't exit +# +# RDoc::usage_no_exit('Author', 'Copyright') +# +# = Author +# +# Dave Thomas, The Pragmatic Programmers, LLC +# +# = Copyright +# +# Copyright (c) 2004 Dave Thomas. +# Licensed under the same terms as Ruby +# + +require 'rdoc/markup/simple_markup' +require 'rdoc/markup/simple_markup/to_flow' +require 'rdoc/ri/ri_formatter' +require 'rdoc/ri/ri_options' + +module RDoc + + # Display usage information from the comment at the top of + # the file. String arguments identify specific sections of the + # comment to display. An optional integer first argument + # specifies the exit status (defaults to 0) + + def RDoc.usage(*args) + exit_code = 0 + + if args.size > 0 + status = args[0] + if status.respond_to?(:to_int) + exit_code = status.to_int + args.shift + end + end + + # display the usage and exit with the given code + usage_no_exit(*args) + exit(exit_code) + end + + # Display usage + def RDoc.usage_no_exit(*args) + main_program_file = caller[-1].sub(/:\d+$/, '') + comment = File.open(main_program_file) do |file| + find_comment(file) + end + + comment = comment.gsub(/^\s*#/, '') + + markup = SM::SimpleMarkup.new + flow_convertor = SM::ToFlow.new + + flow = markup.convert(comment, flow_convertor) + + format = "plain" + + unless args.empty? + flow = extract_sections(flow, args) + end + + options = RI::Options.instance + if args = ENV["RI"] + options.parse(args.split) + end + formatter = options.formatter.new(options, "") + formatter.display_flow(flow) + end + + ###################################################################### + + private + + # Find the first comment in the file (that isn't a shebang line) + # If the file doesn't start with a comment, report the fact + # and return empty string + + def RDoc.gets(file) + if (line = file.gets) && (line =~ /^#!/) # shebang + throw :exit, find_comment(file) + else + line + end + end + + def RDoc.find_comment(file) + catch(:exit) do + # skip leading blank lines + 0 while (line = gets(file)) && (line =~ /^\s*$/) + + comment = [] + while line && line =~ /^\s*#/ + comment << line + line = gets(file) + end + + 0 while line && (line = gets(file)) + return no_comment if comment.empty? + return comment.join + end + end + + + ##### + # Given an array of flow items and an array of section names, extract those + # sections from the flow which have headings corresponding to + # a section name in the list. Return them in the order + # of names in the +sections+ array. + + def RDoc.extract_sections(flow, sections) + result = [] + sections.each do |name| + name = name.downcase + copy_upto_level = nil + + flow.each do |item| + case item + when SM::Flow::H + if copy_upto_level && item.level >= copy_upto_level + copy_upto_level = nil + else + if item.text.downcase == name + result << item + copy_upto_level = item.level + end + end + else + if copy_upto_level + result << item + end + end + end + end + if result.empty? + puts "Note to developer: requested section(s) [#{sections.join(', ')}] " + + "not found" + result = flow + end + result + end + + ##### + # Report the fact that no doc comment count be found + def RDoc.no_comment + $stderr.puts "No usage information available for this program" + "" + end +end + + +if $0 == __FILE__ + + RDoc::usage(*ARGV) + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/readbytes.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/readbytes.rb new file mode 100644 index 00000000..ebb5fc0b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/readbytes.rb @@ -0,0 +1,41 @@ +# TruncatedDataError is raised when IO#readbytes fails to read enough data. + +class TruncatedDataError["210.251.121.21"], :search=>["ruby-lang.org"], :ndots=>1}) + +--- Resolv::DNS.open(config_info=nil) +--- Resolv::DNS.open(config_info=nil) {|dns| ...} + +=== methods +--- Resolv::DNS#close + +--- Resolv::DNS#getaddress(name) +--- Resolv::DNS#getaddresses(name) +--- Resolv::DNS#each_address(name) {|address| ...} + address lookup methods. + + ((|name|)) must be a instance of Resolv::DNS::Name or String. Lookupped + address is represented as an instance of Resolv::IPv4 or Resolv::IPv6. + +--- Resolv::DNS#getname(address) +--- Resolv::DNS#getnames(address) +--- Resolv::DNS#each_name(address) {|name| ...} + hostnames lookup methods. + + ((|address|)) must be a instance of Resolv::IPv4, Resolv::IPv6 or String. + Lookupped name is represented as an instance of Resolv::DNS::Name. + +--- Resolv::DNS#getresource(name, typeclass) +--- Resolv::DNS#getresources(name, typeclass) +--- Resolv::DNS#each_resource(name, typeclass) {|resource| ...} + They lookup DNS resources of ((|name|)). + ((|name|)) must be a instance of Resolv::Name or String. + + ((|typeclass|)) should be one of follows: + * Resolv::DNS::Resource::IN::ANY + * Resolv::DNS::Resource::IN::NS + * Resolv::DNS::Resource::IN::CNAME + * Resolv::DNS::Resource::IN::SOA + * Resolv::DNS::Resource::IN::HINFO + * Resolv::DNS::Resource::IN::MINFO + * Resolv::DNS::Resource::IN::MX + * Resolv::DNS::Resource::IN::TXT + * Resolv::DNS::Resource::IN::ANY + * Resolv::DNS::Resource::IN::A + * Resolv::DNS::Resource::IN::WKS + * Resolv::DNS::Resource::IN::PTR + * Resolv::DNS::Resource::IN::AAAA + + Lookupped resource is represented as an instance of (a subclass of) + Resolv::DNS::Resource. + (Resolv::DNS::Resource::IN::A, etc.) + +== Resolv::DNS::Resource::IN::NS class +--- name +== Resolv::DNS::Resource::IN::CNAME class +--- name +== Resolv::DNS::Resource::IN::SOA class +--- mname +--- rname +--- serial +--- refresh +--- retry +--- expire +--- minimum +== Resolv::DNS::Resource::IN::HINFO class +--- cpu +--- os +== Resolv::DNS::Resource::IN::MINFO class +--- rmailbx +--- emailbx +== Resolv::DNS::Resource::IN::MX class +--- preference +--- exchange +== Resolv::DNS::Resource::IN::TXT class +--- data +== Resolv::DNS::Resource::IN::A class +--- address +== Resolv::DNS::Resource::IN::WKS class +--- address +--- protocol +--- bitmap +== Resolv::DNS::Resource::IN::PTR class +--- name +== Resolv::DNS::Resource::IN::AAAA class +--- address + +== Resolv::DNS::Name class + +=== class methods +--- Resolv::DNS::Name.create(name) + +=== methods +--- Resolv::DNS::Name#to_s + +== Resolv::DNS::Resource class + +== Resolv::IPv4 class +=== class methods +--- Resolv::IPv4.create(address) + +=== methods +--- Resolv::IPv4#to_s +--- Resolv::IPv4#to_name + +=== constants +--- Resolv::IPv4::Regex + regular expression for IPv4 address. + +== Resolv::IPv6 class +=== class methods +--- Resolv::IPv6.create(address) + +=== methods +--- Resolv::IPv6#to_s +--- Resolv::IPv6#to_name + +=== constants +--- Resolv::IPv6::Regex + regular expression for IPv6 address. + +== Bugs +* NIS is not supported. +* /etc/nsswitch.conf is not supported. +* IPv6 is not supported. + +=end + +require 'socket' +require 'fcntl' +require 'timeout' +require 'thread' + +begin + require 'securerandom' +rescue LoadError +end + +class Resolv + def self.getaddress(name) + DefaultResolver.getaddress(name) + end + + def self.getaddresses(name) + DefaultResolver.getaddresses(name) + end + + def self.each_address(name, &block) + DefaultResolver.each_address(name, &block) + end + + def self.getname(address) + DefaultResolver.getname(address) + end + + def self.getnames(address) + DefaultResolver.getnames(address) + end + + def self.each_name(address, &proc) + DefaultResolver.each_name(address, &proc) + end + + def initialize(resolvers=[Hosts.new, DNS.new]) + @resolvers = resolvers + end + + def getaddress(name) + each_address(name) {|address| return address} + raise ResolvError.new("no address for #{name}") + end + + def getaddresses(name) + ret = [] + each_address(name) {|address| ret << address} + return ret + end + + def each_address(name) + if AddressRegex =~ name + yield name + return + end + yielded = false + @resolvers.each {|r| + r.each_address(name) {|address| + yield address.to_s + yielded = true + } + return if yielded + } + end + + def getname(address) + each_name(address) {|name| return name} + raise ResolvError.new("no name for #{address}") + end + + def getnames(address) + ret = [] + each_name(address) {|name| ret << name} + return ret + end + + def each_name(address) + yielded = false + @resolvers.each {|r| + r.each_name(address) {|name| + yield name.to_s + yielded = true + } + return if yielded + } + end + + class ResolvError < StandardError + end + + class ResolvTimeout < TimeoutError + end + + class Hosts + if /mswin32|mingw|bccwin/ =~ RUBY_PLATFORM + require 'win32/resolv' + DefaultFileName = Win32::Resolv.get_hosts_path + else + DefaultFileName = '/etc/hosts' + end + + def initialize(filename = DefaultFileName) + @filename = filename + @mutex = Mutex.new + @initialized = nil + end + + def lazy_initialize + @mutex.synchronize { + unless @initialized + @name2addr = {} + @addr2name = {} + open(@filename) {|f| + f.each {|line| + line.sub!(/#.*/, '') + addr, hostname, *aliases = line.split(/\s+/) + next unless addr + addr.untaint + hostname.untaint + @addr2name[addr] = [] unless @addr2name.include? addr + @addr2name[addr] << hostname + @addr2name[addr] += aliases + @name2addr[hostname] = [] unless @name2addr.include? hostname + @name2addr[hostname] << addr + aliases.each {|n| + n.untaint + @name2addr[n] = [] unless @name2addr.include? n + @name2addr[n] << addr + } + } + } + @name2addr.each {|name, arr| arr.reverse!} + @initialized = true + end + } + self + end + + def getaddress(name) + each_address(name) {|address| return address} + raise ResolvError.new("#{@filename} has no name: #{name}") + end + + def getaddresses(name) + ret = [] + each_address(name) {|address| ret << address} + return ret + end + + def each_address(name, &proc) + lazy_initialize + if @name2addr.include?(name) + @name2addr[name].each(&proc) + end + end + + def getname(address) + each_name(address) {|name| return name} + raise ResolvError.new("#{@filename} has no address: #{address}") + end + + def getnames(address) + ret = [] + each_name(address) {|name| ret << name} + return ret + end + + def each_name(address, &proc) + lazy_initialize + if @addr2name.include?(address) + @addr2name[address].each(&proc) + end + end + end + + class DNS + # STD0013 (RFC 1035, etc.) + # ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters + + Port = 53 + UDPSize = 512 + + DNSThreadGroup = ThreadGroup.new + + def self.open(*args) + dns = new(*args) + return dns unless block_given? + begin + yield dns + ensure + dns.close + end + end + + def initialize(config_info=nil) + @mutex = Mutex.new + @config = Config.new(config_info) + @initialized = nil + end + + def lazy_initialize + @mutex.synchronize { + unless @initialized + @config.lazy_initialize + @initialized = true + end + } + self + end + + def close + @mutex.synchronize { + if @initialized + @initialized = false + end + } + end + + def getaddress(name) + each_address(name) {|address| return address} + raise ResolvError.new("DNS result has no information for #{name}") + end + + def getaddresses(name) + ret = [] + each_address(name) {|address| ret << address} + return ret + end + + def each_address(name) + each_resource(name, Resource::IN::A) {|resource| yield resource.address} + end + + def getname(address) + each_name(address) {|name| return name} + raise ResolvError.new("DNS result has no information for #{address}") + end + + def getnames(address) + ret = [] + each_name(address) {|name| ret << name} + return ret + end + + def each_name(address) + case address + when Name + ptr = address + when IPv4::Regex + ptr = IPv4.create(address).to_name + when IPv6::Regex + ptr = IPv6.create(address).to_name + else + raise ResolvError.new("cannot interpret as address: #{address}") + end + each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name} + end + + def getresource(name, typeclass) + each_resource(name, typeclass) {|resource| return resource} + raise ResolvError.new("DNS result has no information for #{name}") + end + + def getresources(name, typeclass) + ret = [] + each_resource(name, typeclass) {|resource| ret << resource} + return ret + end + + def each_resource(name, typeclass, &proc) + lazy_initialize + requester = make_requester + senders = {} + begin + @config.resolv(name) {|candidate, tout, nameserver| + msg = Message.new + msg.rd = 1 + msg.add_question(candidate, typeclass) + unless sender = senders[[candidate, nameserver]] + sender = senders[[candidate, nameserver]] = + requester.sender(msg, candidate, nameserver) + end + reply, reply_name = requester.request(sender, tout) + case reply.rcode + when RCode::NoError + extract_resources(reply, reply_name, typeclass, &proc) + return + when RCode::NXDomain + raise Config::NXDomain.new(reply_name.to_s) + else + raise Config::OtherResolvError.new(reply_name.to_s) + end + } + ensure + requester.close + end + end + + def make_requester # :nodoc: + if nameserver = @config.single? + Requester::ConnectedUDP.new(nameserver) + else + Requester::UnconnectedUDP.new + end + end + + def extract_resources(msg, name, typeclass) + if typeclass < Resource::ANY + n0 = Name.create(name) + msg.each_answer {|n, ttl, data| + yield data if n0 == n + } + end + yielded = false + n0 = Name.create(name) + msg.each_answer {|n, ttl, data| + if n0 == n + case data + when typeclass + yield data + yielded = true + when Resource::CNAME + n0 = data.name + end + end + } + return if yielded + msg.each_answer {|n, ttl, data| + if n0 == n + case data + when typeclass + yield data + end + end + } + end + + if defined? SecureRandom + def self.random(arg) # :nodoc: + begin + SecureRandom.random_number(arg) + rescue NotImplementedError + rand(arg) + end + end + else + def self.random(arg) # :nodoc: + rand(arg) + end + end + + def self.rangerand(range) # :nodoc: + base = range.begin + len = range.end - range.begin + if !range.exclude_end? + len += 1 + end + base + random(len) + end + + RequestID = {} + RequestIDMutex = Mutex.new + + def self.allocate_request_id(host, port) # :nodoc: + id = nil + RequestIDMutex.synchronize { + h = (RequestID[[host, port]] ||= {}) + begin + id = rangerand(0x0000..0xffff) + end while h[id] + h[id] = true + } + id + end + + def self.free_request_id(host, port, id) # :nodoc: + RequestIDMutex.synchronize { + key = [host, port] + if h = RequestID[key] + h.delete id + if h.empty? + RequestID.delete key + end + end + } + end + + def self.bind_random_port(udpsock) # :nodoc: + begin + port = rangerand(1024..65535) + udpsock.bind("", port) + rescue Errno::EADDRINUSE + retry + end + end + + class Requester + def initialize + @senders = {} + @sock = nil + end + + def request(sender, tout) + timelimit = Time.now + tout + sender.send + while (now = Time.now) < timelimit + timeout = timelimit - now + if !IO.select([@sock], nil, nil, timeout) + raise ResolvTimeout + end + reply, from = recv_reply + begin + msg = Message.decode(reply) + rescue DecodeError + next # broken DNS message ignored + end + if s = @senders[[from,msg.id]] + break + else + # unexpected DNS message ignored + end + end + return msg, s.data + end + + def close + sock = @sock + @sock = nil + sock.close if sock + end + + class Sender # :nodoc: + def initialize(msg, data, sock) + @msg = msg + @data = data + @sock = sock + end + end + + class UnconnectedUDP < Requester + def initialize + super() + @sock = UDPSocket.new + @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + DNS.bind_random_port(@sock) + end + + def recv_reply + reply, from = @sock.recvfrom(UDPSize) + return reply, [from[3],from[1]] + end + + def sender(msg, data, host, port=Port) + service = [host, port] + id = DNS.allocate_request_id(host, port) + request = msg.encode + request[0,2] = [id].pack('n') + return @senders[[service, id]] = + Sender.new(request, data, @sock, host, port) + end + + def close + super + @senders.each_key {|service, id| + DNS.free_request_id(service[0], service[1], id) + } + end + + class Sender < Requester::Sender + def initialize(msg, data, sock, host, port) + super(msg, data, sock) + @host = host + @port = port + end + attr_reader :data + + def send + @sock.send(@msg, 0, @host, @port) + end + end + end + + class ConnectedUDP < Requester + def initialize(host, port=Port) + super() + @host = host + @port = port + @sock = UDPSocket.new(host.index(':') ? Socket::AF_INET6 : Socket::AF_INET) + DNS.bind_random_port(@sock) + @sock.connect(host, port) + @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + end + + def recv_reply + reply = @sock.recv(UDPSize) + return reply, nil + end + + def sender(msg, data, host=@host, port=@port) + unless host == @host && port == @port + raise RequestError.new("host/port don't match: #{host}:#{port}") + end + id = DNS.allocate_request_id(@host, @port) + request = msg.encode + request[0,2] = [id].pack('n') + return @senders[[nil,id]] = Sender.new(request, data, @sock) + end + + def close + super + @senders.each_key {|from, id| + DNS.free_request_id(@host, @port, id) + } + end + + class Sender < Requester::Sender + def send + @sock.send(@msg, 0) + end + attr_reader :data + end + end + + class TCP < Requester + def initialize(host, port=Port) + super() + @host = host + @port = port + @sock = TCPSocket.new(@host, @port) + @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + @senders = {} + end + + def recv_reply + len = @sock.read(2).unpack('n')[0] + reply = @sock.read(len) + return reply, nil + end + + def sender(msg, data, host=@host, port=@port) + unless host == @host && port == @port + raise RequestError.new("host/port don't match: #{host}:#{port}") + end + id = DNS.allocate_request_id(@host, @port) + request = msg.encode + request[0,2] = [request.length, id].pack('nn') + return @senders[[nil,id]] = Sender.new(request, data, @sock) + end + + class Sender < Requester::Sender + def send + @sock.print(@msg) + @sock.flush + end + attr_reader :data + end + + def close + super + @senders.each_key {|from,id| + DNS.free_request_id(@host, @port, id) + } + end + end + + class RequestError < StandardError + end + end + + class Config + def initialize(config_info=nil) + @mutex = Mutex.new + @config_info = config_info + @initialized = nil + end + + def Config.parse_resolv_conf(filename) + nameserver = [] + search = nil + ndots = 1 + open(filename) {|f| + f.each {|line| + line.sub!(/[#;].*/, '') + keyword, *args = line.split(/\s+/) + args.each { |arg| + arg.untaint + } + next unless keyword + case keyword + when 'nameserver' + nameserver += args + when 'domain' + next if args.empty? + search = [args[0]] + when 'search' + next if args.empty? + search = args + when 'options' + args.each {|arg| + case arg + when /\Andots:(\d+)\z/ + ndots = $1.to_i + end + } + end + } + } + return { :nameserver => nameserver, :search => search, :ndots => ndots } + end + + def Config.default_config_hash(filename="/etc/resolv.conf") + if File.exist? filename + config_hash = Config.parse_resolv_conf(filename) + else + if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM + require 'win32/resolv' + search, nameserver = Win32::Resolv.get_resolv_info + config_hash = {} + config_hash[:nameserver] = nameserver if nameserver + config_hash[:search] = [search].flatten if search + end + end + config_hash + end + + def lazy_initialize + @mutex.synchronize { + unless @initialized + @nameserver = [] + @search = nil + @ndots = 1 + case @config_info + when nil + config_hash = Config.default_config_hash + when String + config_hash = Config.parse_resolv_conf(@config_info) + when Hash + config_hash = @config_info.dup + if String === config_hash[:nameserver] + config_hash[:nameserver] = [config_hash[:nameserver]] + end + if String === config_hash[:search] + config_hash[:search] = [config_hash[:search]] + end + else + raise ArgumentError.new("invalid resolv configuration: #{@config_info.inspect}") + end + @nameserver = config_hash[:nameserver] if config_hash.include? :nameserver + @search = config_hash[:search] if config_hash.include? :search + @ndots = config_hash[:ndots] if config_hash.include? :ndots + + @nameserver = ['0.0.0.0'] if @nameserver.empty? + if @search + @search = @search.map {|arg| Label.split(arg) } + else + hostname = Socket.gethostname + if /\./ =~ hostname + @search = [Label.split($')] + else + @search = [[]] + end + end + + if !@nameserver.kind_of?(Array) || + !@nameserver.all? {|ns| String === ns } + raise ArgumentError.new("invalid nameserver config: #{@nameserver.inspect}") + end + + if !@search.kind_of?(Array) || + !@search.all? {|ls| ls.all? {|l| Label::Str === l } } + raise ArgumentError.new("invalid search config: #{@search.inspect}") + end + + if !@ndots.kind_of?(Integer) + raise ArgumentError.new("invalid ndots config: #{@ndots.inspect}") + end + + @initialized = true + end + } + self + end + + def single? + lazy_initialize + if @nameserver.length == 1 + return @nameserver[0] + else + return nil + end + end + + def generate_candidates(name) + candidates = nil + name = Name.create(name) + if name.absolute? + candidates = [name] + else + if @ndots <= name.length - 1 + candidates = [Name.new(name.to_a)] + else + candidates = [] + end + candidates.concat(@search.map {|domain| Name.new(name.to_a + domain)}) + end + return candidates + end + + InitialTimeout = 5 + + def generate_timeouts + ts = [InitialTimeout] + ts << ts[-1] * 2 / @nameserver.length + ts << ts[-1] * 2 + ts << ts[-1] * 2 + return ts + end + + def resolv(name) + candidates = generate_candidates(name) + timeouts = generate_timeouts + begin + candidates.each {|candidate| + begin + timeouts.each {|tout| + @nameserver.each {|nameserver| + begin + yield candidate, tout, nameserver + rescue ResolvTimeout + end + } + } + raise ResolvError.new("DNS resolv timeout: #{name}") + rescue NXDomain + end + } + rescue ResolvError + end + end + + class NXDomain < ResolvError + end + + class OtherResolvError < ResolvError + end + end + + module OpCode + Query = 0 + IQuery = 1 + Status = 2 + Notify = 4 + Update = 5 + end + + module RCode + NoError = 0 + FormErr = 1 + ServFail = 2 + NXDomain = 3 + NotImp = 4 + Refused = 5 + YXDomain = 6 + YXRRSet = 7 + NXRRSet = 8 + NotAuth = 9 + NotZone = 10 + BADVERS = 16 + BADSIG = 16 + BADKEY = 17 + BADTIME = 18 + BADMODE = 19 + BADNAME = 20 + BADALG = 21 + end + + class DecodeError < StandardError + end + + class EncodeError < StandardError + end + + module Label + def self.split(arg) + labels = [] + arg.scan(/[^\.]+/) {labels << Str.new($&)} + return labels + end + + class Str + def initialize(string) + @string = string + @downcase = string.downcase + end + attr_reader :string, :downcase + + def to_s + return @string + end + + def inspect + return "#<#{self.class} #{self.to_s}>" + end + + def ==(other) + return @downcase == other.downcase + end + + def eql?(other) + return self == other + end + + def hash + return @downcase.hash + end + end + end + + class Name + def self.create(arg) + case arg + when Name + return arg + when String + return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false) + else + raise ArgumentError.new("cannot interpret as DNS name: #{arg.inspect}") + end + end + + def initialize(labels, absolute=true) + @labels = labels + @absolute = absolute + end + + def inspect + "#<#{self.class}: #{self.to_s}#{@absolute ? '.' : ''}>" + end + + def absolute? + return @absolute + end + + def ==(other) + return false unless Name === other + return @labels == other.to_a && @absolute == other.absolute? + end + alias eql? == + + # tests subdomain-of relation. + # + # domain = Resolv::DNS::Name.create("y.z") + # p Resolv::DNS::Name.create("w.x.y.z").subdomain_of?(domain) #=> true + # p Resolv::DNS::Name.create("x.y.z").subdomain_of?(domain) #=> true + # p Resolv::DNS::Name.create("y.z").subdomain_of?(domain) #=> false + # p Resolv::DNS::Name.create("z").subdomain_of?(domain) #=> false + # p Resolv::DNS::Name.create("x.y.z.").subdomain_of?(domain) #=> false + # p Resolv::DNS::Name.create("w.z").subdomain_of?(domain) #=> false + # + def subdomain_of?(other) + raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other + return false if @absolute != other.absolute? + other_len = other.length + return false if @labels.length <= other_len + return @labels[-other_len, other_len] == other.to_a + end + + def hash + return @labels.hash ^ @absolute.hash + end + + def to_a + return @labels + end + + def length + return @labels.length + end + + def [](i) + return @labels[i] + end + + # returns the domain name as a string. + # + # The domain name doesn't have a trailing dot even if the name object is + # absolute. + # + # p Resolv::DNS::Name.create("x.y.z.").to_s #=> "x.y.z" + # p Resolv::DNS::Name.create("x.y.z").to_s #=> "x.y.z" + # + def to_s + return @labels.join('.') + end + end + + class Message + @@identifier = -1 + + def initialize(id = (@@identifier += 1) & 0xffff) + @id = id + @qr = 0 + @opcode = 0 + @aa = 0 + @tc = 0 + @rd = 0 # recursion desired + @ra = 0 # recursion available + @rcode = 0 + @question = [] + @answer = [] + @authority = [] + @additional = [] + end + + attr_accessor :id, :qr, :opcode, :aa, :tc, :rd, :ra, :rcode + attr_reader :question, :answer, :authority, :additional + + def ==(other) + return @id == other.id && + @qr == other.qr && + @opcode == other.opcode && + @aa == other.aa && + @tc == other.tc && + @rd == other.rd && + @ra == other.ra && + @rcode == other.rcode && + @question == other.question && + @answer == other.answer && + @authority == other.authority && + @additional == other.additional + end + + def add_question(name, typeclass) + @question << [Name.create(name), typeclass] + end + + def each_question + @question.each {|name, typeclass| + yield name, typeclass + } + end + + def add_answer(name, ttl, data) + @answer << [Name.create(name), ttl, data] + end + + def each_answer + @answer.each {|name, ttl, data| + yield name, ttl, data + } + end + + def add_authority(name, ttl, data) + @authority << [Name.create(name), ttl, data] + end + + def each_authority + @authority.each {|name, ttl, data| + yield name, ttl, data + } + end + + def add_additional(name, ttl, data) + @additional << [Name.create(name), ttl, data] + end + + def each_additional + @additional.each {|name, ttl, data| + yield name, ttl, data + } + end + + def each_resource + each_answer {|name, ttl, data| yield name, ttl, data} + each_authority {|name, ttl, data| yield name, ttl, data} + each_additional {|name, ttl, data| yield name, ttl, data} + end + + def encode + return MessageEncoder.new {|msg| + msg.put_pack('nnnnnn', + @id, + (@qr & 1) << 15 | + (@opcode & 15) << 11 | + (@aa & 1) << 10 | + (@tc & 1) << 9 | + (@rd & 1) << 8 | + (@ra & 1) << 7 | + (@rcode & 15), + @question.length, + @answer.length, + @authority.length, + @additional.length) + @question.each {|q| + name, typeclass = q + msg.put_name(name) + msg.put_pack('nn', typeclass::TypeValue, typeclass::ClassValue) + } + [@answer, @authority, @additional].each {|rr| + rr.each {|r| + name, ttl, data = r + msg.put_name(name) + msg.put_pack('nnN', data.class::TypeValue, data.class::ClassValue, ttl) + msg.put_length16 {data.encode_rdata(msg)} + } + } + }.to_s + end + + class MessageEncoder + def initialize + @data = '' + @names = {} + yield self + end + + def to_s + return @data + end + + def put_bytes(d) + @data << d + end + + def put_pack(template, *d) + @data << d.pack(template) + end + + def put_length16 + length_index = @data.length + @data << "\0\0" + data_start = @data.length + yield + data_end = @data.length + @data[length_index, 2] = [data_end - data_start].pack("n") + end + + def put_string(d) + self.put_pack("C", d.length) + @data << d + end + + def put_string_list(ds) + ds.each {|d| + self.put_string(d) + } + end + + def put_name(d) + put_labels(d.to_a) + end + + def put_labels(d) + d.each_index {|i| + domain = d[i..-1] + if idx = @names[domain] + self.put_pack("n", 0xc000 | idx) + return + else + @names[domain] = @data.length + self.put_label(d[i]) + end + } + @data << "\0" + end + + def put_label(d) + self.put_string(d.string) + end + end + + def Message.decode(m) + o = Message.new(0) + MessageDecoder.new(m) {|msg| + id, flag, qdcount, ancount, nscount, arcount = + msg.get_unpack('nnnnnn') + o.id = id + o.qr = (flag >> 15) & 1 + o.opcode = (flag >> 11) & 15 + o.aa = (flag >> 10) & 1 + o.tc = (flag >> 9) & 1 + o.rd = (flag >> 8) & 1 + o.ra = (flag >> 7) & 1 + o.rcode = flag & 15 + (1..qdcount).each { + name, typeclass = msg.get_question + o.add_question(name, typeclass) + } + (1..ancount).each { + name, ttl, data = msg.get_rr + o.add_answer(name, ttl, data) + } + (1..nscount).each { + name, ttl, data = msg.get_rr + o.add_authority(name, ttl, data) + } + (1..arcount).each { + name, ttl, data = msg.get_rr + o.add_additional(name, ttl, data) + } + } + return o + end + + class MessageDecoder + def initialize(data) + @data = data + @index = 0 + @limit = data.length + yield self + end + + def get_length16 + len, = self.get_unpack('n') + save_limit = @limit + @limit = @index + len + d = yield(len) + if @index < @limit + raise DecodeError.new("junk exists") + elsif @limit < @index + raise DecodeError.new("limit exceeded") + end + @limit = save_limit + return d + end + + def get_bytes(len = @limit - @index) + d = @data[@index, len] + @index += len + return d + end + + def get_unpack(template) + len = 0 + template.each_byte {|byte| + case byte + when ?c, ?C + len += 1 + when ?n + len += 2 + when ?N + len += 4 + else + raise StandardError.new("unsupported template: '#{byte.chr}' in '#{template}'") + end + } + raise DecodeError.new("limit exceeded") if @limit < @index + len + arr = @data.unpack("@#{@index}#{template}") + @index += len + return arr + end + + def get_string + len = @data[@index] + raise DecodeError.new("limit exceeded") if @limit < @index + 1 + len + d = @data[@index + 1, len] + @index += 1 + len + return d + end + + def get_string_list + strings = [] + while @index < @limit + strings << self.get_string + end + strings + end + + def get_name + return Name.new(self.get_labels) + end + + def get_labels(limit=nil) + limit = @index if !limit || @index < limit + d = [] + while true + case @data[@index] + when 0 + @index += 1 + return d + when 192..255 + idx = self.get_unpack('n')[0] & 0x3fff + if limit <= idx + raise DecodeError.new("non-backward name pointer") + end + save_index = @index + @index = idx + d += self.get_labels(limit) + @index = save_index + return d + else + d << self.get_label + end + end + return d + end + + def get_label + return Label::Str.new(self.get_string) + end + + def get_question + name = self.get_name + type, klass = self.get_unpack("nn") + return name, Resource.get_class(type, klass) + end + + def get_rr + name = self.get_name + type, klass, ttl = self.get_unpack('nnN') + typeclass = Resource.get_class(type, klass) + return name, ttl, self.get_length16 {typeclass.decode_rdata(self)} + end + end + end + + class Query + def encode_rdata(msg) + raise EncodeError.new("#{self.class} is query.") + end + + def self.decode_rdata(msg) + raise DecodeError.new("#{self.class} is query.") + end + end + + class Resource < Query + ClassHash = {} + + def encode_rdata(msg) + raise NotImplementedError.new + end + + def self.decode_rdata(msg) + raise NotImplementedError.new + end + + def ==(other) + return self.class == other.class && + self.instance_variables == other.instance_variables && + self.instance_variables.collect {|name| self.instance_eval name} == + other.instance_variables.collect {|name| other.instance_eval name} + end + + def eql?(other) + return self == other + end + + def hash + h = 0 + self.instance_variables.each {|name| + h ^= self.instance_eval("#{name}.hash") + } + return h + end + + def self.get_class(type_value, class_value) + return ClassHash[[type_value, class_value]] || + Generic.create(type_value, class_value) + end + + class Generic < Resource + def initialize(data) + @data = data + end + attr_reader :data + + def encode_rdata(msg) + msg.put_bytes(data) + end + + def self.decode_rdata(msg) + return self.new(msg.get_bytes) + end + + def self.create(type_value, class_value) + c = Class.new(Generic) + c.const_set(:TypeValue, type_value) + c.const_set(:ClassValue, class_value) + Generic.const_set("Type#{type_value}_Class#{class_value}", c) + ClassHash[[type_value, class_value]] = c + return c + end + end + + class DomainName < Resource + def initialize(name) + @name = name + end + attr_reader :name + + def encode_rdata(msg) + msg.put_name(@name) + end + + def self.decode_rdata(msg) + return self.new(msg.get_name) + end + end + + # Standard (class generic) RRs + ClassValue = nil + + class NS < DomainName + TypeValue = 2 + end + + class CNAME < DomainName + TypeValue = 5 + end + + class SOA < Resource + TypeValue = 6 + + def initialize(mname, rname, serial, refresh, retry_, expire, minimum) + @mname = mname + @rname = rname + @serial = serial + @refresh = refresh + @retry = retry_ + @expire = expire + @minimum = minimum + end + attr_reader :mname, :rname, :serial, :refresh, :retry, :expire, :minimum + + def encode_rdata(msg) + msg.put_name(@mname) + msg.put_name(@rname) + msg.put_pack('NNNNN', @serial, @refresh, @retry, @expire, @minimum) + end + + def self.decode_rdata(msg) + mname = msg.get_name + rname = msg.get_name + serial, refresh, retry_, expire, minimum = msg.get_unpack('NNNNN') + return self.new( + mname, rname, serial, refresh, retry_, expire, minimum) + end + end + + class PTR < DomainName + TypeValue = 12 + end + + class HINFO < Resource + TypeValue = 13 + + def initialize(cpu, os) + @cpu = cpu + @os = os + end + attr_reader :cpu, :os + + def encode_rdata(msg) + msg.put_string(@cpu) + msg.put_string(@os) + end + + def self.decode_rdata(msg) + cpu = msg.get_string + os = msg.get_string + return self.new(cpu, os) + end + end + + class MINFO < Resource + TypeValue = 14 + + def initialize(rmailbx, emailbx) + @rmailbx = rmailbx + @emailbx = emailbx + end + attr_reader :rmailbx, :emailbx + + def encode_rdata(msg) + msg.put_name(@rmailbx) + msg.put_name(@emailbx) + end + + def self.decode_rdata(msg) + rmailbx = msg.get_string + emailbx = msg.get_string + return self.new(rmailbx, emailbx) + end + end + + class MX < Resource + TypeValue= 15 + + def initialize(preference, exchange) + @preference = preference + @exchange = exchange + end + attr_reader :preference, :exchange + + def encode_rdata(msg) + msg.put_pack('n', @preference) + msg.put_name(@exchange) + end + + def self.decode_rdata(msg) + preference, = msg.get_unpack('n') + exchange = msg.get_name + return self.new(preference, exchange) + end + end + + class TXT < Resource + TypeValue = 16 + + def initialize(first_string, *rest_strings) + @strings = [first_string, *rest_strings] + end + attr_reader :strings + + def data + @strings[0] + end + + def encode_rdata(msg) + msg.put_string_list(@strings) + end + + def self.decode_rdata(msg) + strings = msg.get_string_list + return self.new(*strings) + end + end + + class ANY < Query + TypeValue = 255 + end + + ClassInsensitiveTypes = [ + NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY + ] + + # ARPA Internet specific RRs + module IN + ClassValue = 1 + + ClassInsensitiveTypes.each {|s| + c = Class.new(s) + c.const_set(:TypeValue, s::TypeValue) + c.const_set(:ClassValue, ClassValue) + ClassHash[[s::TypeValue, ClassValue]] = c + self.const_set(s.name.sub(/.*::/, ''), c) + } + + class A < Resource + ClassHash[[TypeValue = 1, ClassValue = ClassValue]] = self + + def initialize(address) + @address = IPv4.create(address) + end + attr_reader :address + + def encode_rdata(msg) + msg.put_bytes(@address.address) + end + + def self.decode_rdata(msg) + return self.new(IPv4.new(msg.get_bytes(4))) + end + end + + class WKS < Resource + ClassHash[[TypeValue = 11, ClassValue = ClassValue]] = self + + def initialize(address, protocol, bitmap) + @address = IPv4.create(address) + @protocol = protocol + @bitmap = bitmap + end + attr_reader :address, :protocol, :bitmap + + def encode_rdata(msg) + msg.put_bytes(@address.address) + msg.put_pack("n", @protocol) + msg.put_bytes(@bitmap) + end + + def self.decode_rdata(msg) + address = IPv4.new(msg.get_bytes(4)) + protocol, = msg.get_unpack("n") + bitmap = msg.get_bytes + return self.new(address, protocol, bitmap) + end + end + + class AAAA < Resource + ClassHash[[TypeValue = 28, ClassValue = ClassValue]] = self + + def initialize(address) + @address = IPv6.create(address) + end + attr_reader :address + + def encode_rdata(msg) + msg.put_bytes(@address.address) + end + + def self.decode_rdata(msg) + return self.new(IPv6.new(msg.get_bytes(16))) + end + end + + # SRV resource record defined in RFC 2782 + # + # These records identify the hostname and port that a service is + # available at. + # + # The format is: + # _Service._Proto.Name TTL Class SRV Priority Weight Port Target + # + # The fields specific to SRV are defined in RFC 2782 as meaning: + # - +priority+ The priority of this target host. A client MUST attempt + # to contact the target host with the lowest-numbered priority it can + # reach; target hosts with the same priority SHOULD be tried in an + # order defined by the weight field. The range is 0-65535. Note that + # it is not widely implemented and should be set to zero. + # + # - +weight+ A server selection mechanism. The weight field specifies + # a relative weight for entries with the same priority. Larger weights + # SHOULD be given a proportionately higher probability of being + # selected. The range of this number is 0-65535. Domain administrators + # SHOULD use Weight 0 when there isn't any server selection to do, to + # make the RR easier to read for humans (less noisy). Note that it is + # not widely implemented and should be set to zero. + # + # - +port+ The port on this target host of this service. The range is 0- + # 65535. + # + # - +target+ The domain name of the target host. A target of "." means + # that the service is decidedly not available at this domain. + class SRV < Resource + ClassHash[[TypeValue = 33, ClassValue = ClassValue]] = self + + # Create a SRV resource record. + def initialize(priority, weight, port, target) + @priority = priority.to_int + @weight = weight.to_int + @port = port.to_int + @target = Name.create(target) + end + + attr_reader :priority, :weight, :port, :target + + def encode_rdata(msg) + msg.put_pack("n", @priority) + msg.put_pack("n", @weight) + msg.put_pack("n", @port) + msg.put_name(@target) + end + + def self.decode_rdata(msg) + priority, = msg.get_unpack("n") + weight, = msg.get_unpack("n") + port, = msg.get_unpack("n") + target = msg.get_name + return self.new(priority, weight, port, target) + end + end + + end + end + end + + class IPv4 + Regex = /\A(\d+)\.(\d+)\.(\d+)\.(\d+)\z/ + + def self.create(arg) + case arg + when IPv4 + return arg + when Regex + if (0..255) === (a = $1.to_i) && + (0..255) === (b = $2.to_i) && + (0..255) === (c = $3.to_i) && + (0..255) === (d = $4.to_i) + return self.new([a, b, c, d].pack("CCCC")) + else + raise ArgumentError.new("IPv4 address with invalid value: " + arg) + end + else + raise ArgumentError.new("cannot interpret as IPv4 address: #{arg.inspect}") + end + end + + def initialize(address) + unless address.kind_of?(String) && address.length == 4 + raise ArgumentError.new('IPv4 address must be 4 bytes') + end + @address = address + end + attr_reader :address + + def to_s + return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC")) + end + + def inspect + return "#<#{self.class} #{self.to_s}>" + end + + def to_name + return DNS::Name.create( + '%d.%d.%d.%d.in-addr.arpa.' % @address.unpack('CCCC').reverse) + end + + def ==(other) + return @address == other.address + end + + def eql?(other) + return self == other + end + + def hash + return @address.hash + end + end + + class IPv6 + Regex_8Hex = /\A + (?:[0-9A-Fa-f]{1,4}:){7} + [0-9A-Fa-f]{1,4} + \z/x + + Regex_CompressedHex = /\A + ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) :: + ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) + \z/x + + Regex_6Hex4Dec = /\A + ((?:[0-9A-Fa-f]{1,4}:){6,6}) + (\d+)\.(\d+)\.(\d+)\.(\d+) + \z/x + + Regex_CompressedHex4Dec = /\A + ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) :: + ((?:[0-9A-Fa-f]{1,4}:)*) + (\d+)\.(\d+)\.(\d+)\.(\d+) + \z/x + + Regex = / + (?:#{Regex_8Hex}) | + (?:#{Regex_CompressedHex}) | + (?:#{Regex_6Hex4Dec}) | + (?:#{Regex_CompressedHex4Dec})/x + + def self.create(arg) + case arg + when IPv6 + return arg + when String + address = '' + if Regex_8Hex =~ arg + arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')} + elsif Regex_CompressedHex =~ arg + prefix = $1 + suffix = $2 + a1 = '' + a2 = '' + prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')} + suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')} + omitlen = 16 - a1.length - a2.length + address << a1 << "\0" * omitlen << a2 + elsif Regex_6Hex4Dec =~ arg + prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i + if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d + prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')} + address << [a, b, c, d].pack('CCCC') + else + raise ArgumentError.new("not numeric IPv6 address: " + arg) + end + elsif Regex_CompressedHex4Dec =~ arg + prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i + if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d + a1 = '' + a2 = '' + prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')} + suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')} + omitlen = 12 - a1.length - a2.length + address << a1 << "\0" * omitlen << a2 << [a, b, c, d].pack('CCCC') + else + raise ArgumentError.new("not numeric IPv6 address: " + arg) + end + else + raise ArgumentError.new("not numeric IPv6 address: " + arg) + end + return IPv6.new(address) + else + raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}") + end + end + + def initialize(address) + unless address.kind_of?(String) && address.length == 16 + raise ArgumentError.new('IPv6 address must be 16 bytes') + end + @address = address + end + attr_reader :address + + def to_s + address = sprintf("%X:%X:%X:%X:%X:%X:%X:%X", *@address.unpack("nnnnnnnn")) + unless address.sub!(/(^|:)0(:0)+(:|$)/, '::') + address.sub!(/(^|:)0(:|$)/, '::') + end + return address + end + + def inspect + return "#<#{self.class} #{self.to_s}>" + end + + def to_name + # ip6.arpa should be searched too. [RFC3152] + return DNS::Name.new( + @address.unpack("H32")[0].split(//).reverse + ['ip6', 'int']) + end + + def ==(other) + return @address == other.address + end + + def eql?(other) + return self == other + end + + def hash + return @address.hash + end + end + + DefaultResolver = self.new + AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/ +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/attlistdecl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/attlistdecl.rb new file mode 100644 index 00000000..d4b5c38a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/attlistdecl.rb @@ -0,0 +1,62 @@ +#vim:ts=2 sw=2 noexpandtab: +require 'rexml/child' +require 'rexml/source' + +module REXML + # This class needs: + # * Documentation + # * Work! Not all types of attlists are intelligently parsed, so we just + # spew back out what we get in. This works, but it would be better if + # we formatted the output ourselves. + # + # AttlistDecls provide *just* enough support to allow namespace + # declarations. If you need some sort of generalized support, or have an + # interesting idea about how to map the hideous, terrible design of DTD + # AttlistDecls onto an intuitive Ruby interface, let me know. I'm desperate + # for anything to make DTDs more palateable. + class AttlistDecl < Child + include Enumerable + + # What is this? Got me. + attr_reader :element_name + + # Create an AttlistDecl, pulling the information from a Source. Notice + # that this isn't very convenient; to create an AttlistDecl, you basically + # have to format it yourself, and then have the initializer parse it. + # Sorry, but for the forseeable future, DTD support in REXML is pretty + # weak on convenience. Have I mentioned how much I hate DTDs? + def initialize(source) + super() + if (source.kind_of? Array) + @element_name, @pairs, @contents = *source + end + end + + # Access the attlist attribute/value pairs. + # value = attlist_decl[ attribute_name ] + def [](key) + @pairs[key] + end + + # Whether an attlist declaration includes the given attribute definition + # if attlist_decl.include? "xmlns:foobar" + def include?(key) + @pairs.keys.include? key + end + + # Itterate over the key/value pairs: + # attlist_decl.each { |attribute_name, attribute_value| ... } + def each(&block) + @pairs.each(&block) + end + + # Write out exactly what we got in. + def write out, indent=-1 + out << @contents + end + + def node_type + :attlistdecl + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/attribute.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/attribute.rb new file mode 100644 index 00000000..22ecfc2d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/attribute.rb @@ -0,0 +1,185 @@ +require "rexml/namespace" +require 'rexml/text' + +module REXML + # Defines an Element Attribute; IE, a attribute=value pair, as in: + # . Attributes can be in their own + # namespaces. General users of REXML will not interact with the + # Attribute class much. + class Attribute + include Node + include Namespace + + # The element to which this attribute belongs + attr_reader :element + # The normalized value of this attribute. That is, the attribute with + # entities intact. + attr_writer :normalized + PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um + + # Constructor. + # FIXME: The parser doesn't catch illegal characters in attributes + # + # first:: + # Either: an Attribute, which this new attribute will become a + # clone of; or a String, which is the name of this attribute + # second:: + # If +first+ is an Attribute, then this may be an Element, or nil. + # If nil, then the Element parent of this attribute is the parent + # of the +first+ Attribute. If the first argument is a String, + # then this must also be a String, and is the content of the attribute. + # If this is the content, it must be fully normalized (contain no + # illegal characters). + # parent:: + # Ignored unless +first+ is a String; otherwise, may be the Element + # parent of this attribute, or nil. + # + # + # Attribute.new( attribute_to_clone ) + # Attribute.new( attribute_to_clone, parent_element ) + # Attribute.new( "attr", "attr_value" ) + # Attribute.new( "attr", "attr_value", parent_element ) + def initialize( first, second=nil, parent=nil ) + @normalized = @unnormalized = @element = nil + if first.kind_of? Attribute + self.name = first.expanded_name + @unnormalized = first.value + if second.kind_of? Element + @element = second + else + @element = first.element + end + elsif first.kind_of? String + @element = parent + self.name = first + @normalized = second.to_s + else + raise "illegal argument #{first.class.name} to Attribute constructor" + end + end + + # Returns the namespace of the attribute. + # + # e = Element.new( "elns:myelement" ) + # e.add_attribute( "nsa:a", "aval" ) + # e.add_attribute( "b", "bval" ) + # e.attributes.get_attribute( "a" ).prefix # -> "nsa" + # e.attributes.get_attribute( "b" ).prefix # -> "elns" + # a = Attribute.new( "x", "y" ) + # a.prefix # -> "" + def prefix + pf = super + if pf == "" + pf = @element.prefix if @element + end + pf + end + + # Returns the namespace URL, if defined, or nil otherwise + # + # e = Element.new("el") + # e.add_attributes({"xmlns:ns", "http://url"}) + # e.namespace( "ns" ) # -> "http://url" + def namespace arg=nil + arg = prefix if arg.nil? + @element.namespace arg + end + + # Returns true if other is an Attribute and has the same name and value, + # false otherwise. + def ==( other ) + other.kind_of?(Attribute) and other.name==name and other.value==value + end + + # Creates (and returns) a hash from both the name and value + def hash + name.hash ^ value.hash + end + + # Returns this attribute out as XML source, expanding the name + # + # a = Attribute.new( "x", "y" ) + # a.to_string # -> "x='y'" + # b = Attribute.new( "ns:x", "y" ) + # b.to_string # -> "ns:x='y'" + def to_string + if @element and @element.context and @element.context[:attribute_quote] == :quote + %Q^#@expanded_name="#{to_s().gsub(/"/, '"e;')}"^ + else + "#@expanded_name='#{to_s().gsub(/'/, ''')}'" + end + end + + # Returns the attribute value, with entities replaced + def to_s + return @normalized if @normalized + + doctype = nil + if @element + doc = @element.document + doctype = doc.doctype if doc + end + + @normalized = Text::normalize( @unnormalized, doctype ) + @unnormalized = nil + @normalized + end + + # Returns the UNNORMALIZED value of this attribute. That is, entities + # have been expanded to their values + def value + return @unnormalized if @unnormalized + doctype = nil + if @element + doc = @element.document + doctype = doc.doctype if doc + end + @unnormalized = Text::unnormalize( @normalized, doctype ) + @normalized = nil + @unnormalized + end + + # Returns a copy of this attribute + def clone + Attribute.new self + end + + # Sets the element of which this object is an attribute. Normally, this + # is not directly called. + # + # Returns this attribute + def element=( element ) + @element = element + self + end + + # Removes this Attribute from the tree, and returns true if successfull + # + # This method is usually not called directly. + def remove + @element.attributes.delete self.name unless @element.nil? + end + + # Writes this attribute (EG, puts 'key="value"' to the output) + def write( output, indent=-1 ) + output << to_string + end + + def node_type + :attribute + end + + def inspect + rv = "" + write( rv ) + rv + end + + def xpath + path = @element.xpath + path += "/@#{self.expanded_name}" + return path + end + end +end +#vim:ts=2 sw=2 noexpandtab: diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/cdata.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/cdata.rb new file mode 100644 index 00000000..efcb7116 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/cdata.rb @@ -0,0 +1,67 @@ +require "rexml/text" + +module REXML + class CData < Text + START = '' + ILLEGAL = /(\]\]>)/ + + # Constructor. CData is data between + # + # _Examples_ + # CData.new( source ) + # CData.new( "Here is some CDATA" ) + # CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element ) + def initialize( first, whitespace=true, parent=nil ) + super( first, whitespace, parent, true, true, ILLEGAL ) + end + + # Make a copy of this object + # + # _Examples_ + # c = CData.new( "Some text" ) + # d = c.clone + # d.to_s # -> "Some text" + def clone + CData.new self + end + + # Returns the content of this CData object + # + # _Examples_ + # c = CData.new( "Some text" ) + # c.to_s # -> "Some text" + def to_s + @string + end + + def value + @string + end + + # == DEPRECATED + # See the rexml/formatters package + # + # Generates XML output of this object + # + # output:: + # Where to write the string. Defaults to $stdout + # indent:: + # The amount to indent this node by + # transitive:: + # Ignored + # ie_hack:: + # Ignored + # + # _Examples_ + # c = CData.new( " Some text " ) + # c.write( $stdout ) #-> + def write( output=$stdout, indent=-1, transitive=false, ie_hack=false ) + Kernel.warn( "#{self.class.name}.write is deprecated" ) + indent( output, indent ) + output << START + output << @string + output << STOP + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/child.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/child.rb new file mode 100644 index 00000000..6d3c9df5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/child.rb @@ -0,0 +1,96 @@ +require "rexml/node" + +module REXML + ## + # A Child object is something contained by a parent, and this class + # contains methods to support that. Most user code will not use this + # class directly. + class Child + include Node + attr_reader :parent # The Parent of this object + + # Constructor. Any inheritors of this class should call super to make + # sure this method is called. + # parent:: + # if supplied, the parent of this child will be set to the + # supplied value, and self will be added to the parent + def initialize( parent = nil ) + @parent = nil + # Declare @parent, but don't define it. The next line sets the + # parent. + parent.add( self ) if parent + end + + # Replaces this object with another object. Basically, calls + # Parent.replace_child + # + # Returns:: self + def replace_with( child ) + @parent.replace_child( self, child ) + self + end + + # Removes this child from the parent. + # + # Returns:: self + def remove + unless @parent.nil? + @parent.delete self + end + self + end + + # Sets the parent of this child to the supplied argument. + # + # other:: + # Must be a Parent object. If this object is the same object as the + # existing parent of this child, no action is taken. Otherwise, this + # child is removed from the current parent (if one exists), and is added + # to the new parent. + # Returns:: The parent added + def parent=( other ) + return @parent if @parent == other + @parent.delete self if defined? @parent and @parent + @parent = other + end + + alias :next_sibling :next_sibling_node + alias :previous_sibling :previous_sibling_node + + # Sets the next sibling of this child. This can be used to insert a child + # after some other child. + # a = Element.new("a") + # b = a.add_element("b") + # c = Element.new("c") + # b.next_sibling = c + # # => + def next_sibling=( other ) + parent.insert_after self, other + end + + # Sets the previous sibling of this child. This can be used to insert a + # child before some other child. + # a = Element.new("a") + # b = a.add_element("b") + # c = Element.new("c") + # b.previous_sibling = c + # # => + def previous_sibling=(other) + parent.insert_before self, other + end + + # Returns:: the document this child belongs to, or nil if this child + # belongs to no document + def document + return parent.document unless parent.nil? + nil + end + + # This doesn't yet handle encodings + def bytes + encoding = document.encoding + + to_s + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/comment.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/comment.rb new file mode 100644 index 00000000..2b9b4b89 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/comment.rb @@ -0,0 +1,80 @@ +require "rexml/child" + +module REXML + ## + # Represents an XML comment; that is, text between \ + class Comment < Child + include Comparable + START = "" + + # The content text + + attr_accessor :string + + ## + # Constructor. The first argument can be one of three types: + # @param first If String, the contents of this comment are set to the + # argument. If Comment, the argument is duplicated. If + # Source, the argument is scanned for a comment. + # @param second If the first argument is a Source, this argument + # should be nil, not supplied, or a Parent to be set as the parent + # of this object + def initialize( first, second = nil ) + #puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}" + super(second) + if first.kind_of? String + @string = first + elsif first.kind_of? Comment + @string = first.string + end + end + + def clone + Comment.new self + end + + # == DEPRECATED + # See REXML::Formatters + # + # output:: + # Where to write the string + # indent:: + # An integer. If -1, no indenting will be used; otherwise, the + # indentation will be this number of spaces, and children will be + # indented an additional amount. + # transitive:: + # Ignored by this class. The contents of comments are never modified. + # ie_hack:: + # Needed for conformity to the child API, but not used by this class. + def write( output, indent=-1, transitive=false, ie_hack=false ) + Kernel.warn("Comment.write is deprecated. See REXML::Formatters") + indent( output, indent ) + output << START + output << @string + output << STOP + end + + alias :to_s :string + + ## + # Compares this Comment to another; the contents of the comment are used + # in the comparison. + def <=>(other) + other.to_s <=> @string + end + + ## + # Compares this Comment to another; the contents of the comment are used + # in the comparison. + def ==( other ) + other.kind_of? Comment and + (other <=> self) == 0 + end + + def node_type + :comment + end + end +end +#vim:ts=2 sw=2 noexpandtab: diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/doctype.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/doctype.rb new file mode 100644 index 00000000..05cd4ab3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/doctype.rb @@ -0,0 +1,271 @@ +require "rexml/parent" +require "rexml/parseexception" +require "rexml/namespace" +require 'rexml/entity' +require 'rexml/attlistdecl' +require 'rexml/xmltokens' + +module REXML + # Represents an XML DOCTYPE declaration; that is, the contents of . DOCTYPES can be used to declare the DTD of a document, as well as + # being used to declare entities used in the document. + class DocType < Parent + include XMLTokens + START = "" + SYSTEM = "SYSTEM" + PUBLIC = "PUBLIC" + DEFAULT_ENTITIES = { + 'gt'=>EntityConst::GT, + 'lt'=>EntityConst::LT, + 'quot'=>EntityConst::QUOT, + "apos"=>EntityConst::APOS + } + + # name is the name of the doctype + # external_id is the referenced DTD, if given + attr_reader :name, :external_id, :entities, :namespaces + + # Constructor + # + # dt = DocType.new( 'foo', '-//I/Hate/External/IDs' ) + # # + # dt = DocType.new( doctype_to_clone ) + # # Incomplete. Shallow clone of doctype + # + # +Note+ that the constructor: + # + # Doctype.new( Source.new( "" ) ) + # + # is _deprecated_. Do not use it. It will probably disappear. + def initialize( first, parent=nil ) + @entities = DEFAULT_ENTITIES + @long_name = @uri = nil + if first.kind_of? String + super() + @name = first + @external_id = parent + elsif first.kind_of? DocType + super( parent ) + @name = first.name + @external_id = first.external_id + elsif first.kind_of? Array + super( parent ) + @name = first[0] + @external_id = first[1] + @long_name = first[2] + @uri = first[3] + elsif first.kind_of? Source + super( parent ) + parser = Parsers::BaseParser.new( first ) + event = parser.pull + if event[0] == :start_doctype + @name, @external_id, @long_name, @uri, = event[1..-1] + end + else + super() + end + end + + def node_type + :doctype + end + + def attributes_of element + rv = [] + each do |child| + child.each do |key,val| + rv << Attribute.new(key,val) + end if child.kind_of? AttlistDecl and child.element_name == element + end + rv + end + + def attribute_of element, attribute + att_decl = find do |child| + child.kind_of? AttlistDecl and + child.element_name == element and + child.include? attribute + end + return nil unless att_decl + att_decl[attribute] + end + + def clone + DocType.new self + end + + # output:: + # Where to write the string + # indent:: + # An integer. If -1, no indentation will be used; otherwise, the + # indentation will be this number of spaces, and children will be + # indented an additional amount. + # transitive:: + # Ignored + # ie_hack:: + # Ignored + def write( output, indent=0, transitive=false, ie_hack=false ) + f = REXML::Formatters::Default.new + indent( output, indent ) + output << START + output << ' ' + output << @name + output << " #@external_id" if @external_id + output << " #{@long_name.inspect}" if @long_name + output << " #{@uri.inspect}" if @uri + unless @children.empty? + next_indent = indent + 1 + output << ' [' + child = nil # speed + @children.each { |child| + output << "\n" + f.write( child, output ) + } + output << "\n]" + end + output << STOP + end + + def context + @parent.context + end + + def entity( name ) + @entities[name].unnormalized if @entities[name] + end + + def add child + super(child) + @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES + @entities[ child.name ] = child if child.kind_of? Entity + end + + # This method retrieves the public identifier identifying the document's + # DTD. + # + # Method contributed by Henrik Martensson + def public + case @external_id + when "SYSTEM" + nil + when "PUBLIC" + strip_quotes(@long_name) + end + end + + # This method retrieves the system identifier identifying the document's DTD + # + # Method contributed by Henrik Martensson + def system + case @external_id + when "SYSTEM" + strip_quotes(@long_name) + when "PUBLIC" + @uri.kind_of?(String) ? strip_quotes(@uri) : nil + end + end + + # This method returns a list of notations that have been declared in the + # _internal_ DTD subset. Notations in the external DTD subset are not + # listed. + # + # Method contributed by Henrik Martensson + def notations + children().select {|node| node.kind_of?(REXML::NotationDecl)} + end + + # Retrieves a named notation. Only notations declared in the internal + # DTD subset can be retrieved. + # + # Method contributed by Henrik Martensson + def notation(name) + notations.find { |notation_decl| + notation_decl.name == name + } + end + + private + + # Method contributed by Henrik Martensson + def strip_quotes(quoted_string) + quoted_string =~ /^[\'\"].*[\´\"]$/ ? + quoted_string[1, quoted_string.length-2] : + quoted_string + end + end + + # We don't really handle any of these since we're not a validating + # parser, so we can be pretty dumb about them. All we need to be able + # to do is spew them back out on a write() + + # This is an abstract class. You never use this directly; it serves as a + # parent class for the specific declarations. + class Declaration < Child + def initialize src + super() + @string = src + end + + def to_s + @string+'>' + end + + # == DEPRECATED + # See REXML::Formatters + # + def write( output, indent ) + output << to_s + end + end + + public + class ElementDecl < Declaration + def initialize( src ) + super + end + end + + class ExternalEntity < Child + def initialize( src ) + super() + @entity = src + end + def to_s + @entity + end + def write( output, indent ) + output << @entity + end + end + + class NotationDecl < Child + attr_accessor :public, :system + def initialize name, middle, pub, sys + super(nil) + @name = name + @middle = middle + @public = pub + @system = sys + end + + def to_s + "" + end + + def write( output, indent=-1 ) + output << to_s + end + + # This method retrieves the name of the notation. + # + # Method contributed by Henrik Martensson + def name + @name + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/document.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/document.rb new file mode 100644 index 00000000..fbb13309 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/document.rb @@ -0,0 +1,208 @@ +require "rexml/element" +require "rexml/xmldecl" +require "rexml/source" +require "rexml/comment" +require "rexml/doctype" +require "rexml/instruction" +require "rexml/rexml" +require "rexml/parseexception" +require "rexml/output" +require "rexml/parsers/baseparser" +require "rexml/parsers/streamparser" +require "rexml/parsers/treeparser" + +module REXML + # Represents a full XML document, including PIs, a doctype, etc. A + # Document has a single child that can be accessed by root(). + # Note that if you want to have an XML declaration written for a document + # you create, you must add one; REXML documents do not write a default + # declaration for you. See |DECLARATION| and |write|. + class Document < Element + # A convenient default XML declaration. If you want an XML declaration, + # the easiest way to add one is mydoc << Document::DECLARATION + # +DEPRECATED+ + # Use: mydoc << XMLDecl.default + DECLARATION = XMLDecl.default + + # Constructor + # @param source if supplied, must be a Document, String, or IO. + # Documents have their context and Element attributes cloned. + # Strings are expected to be valid XML documents. IOs are expected + # to be sources of valid XML documents. + # @param context if supplied, contains the context of the document; + # this should be a Hash. + def initialize( source = nil, context = {} ) + super() + @context = context + return if source.nil? + if source.kind_of? Document + @context = source.context + super source + else + build( source ) + end + end + + def node_type + :document + end + + # Should be obvious + def clone + Document.new self + end + + # According to the XML spec, a root node has no expanded name + def expanded_name + '' + #d = doc_type + #d ? d.name : "UNDEFINED" + end + + alias :name :expanded_name + + # We override this, because XMLDecls and DocTypes must go at the start + # of the document + def add( child ) + if child.kind_of? XMLDecl + @children.unshift child + child.parent = self + elsif child.kind_of? DocType + # Find first Element or DocType node and insert the decl right + # before it. If there is no such node, just insert the child at the + # end. If there is a child and it is an DocType, then replace it. + insert_before_index = 0 + @children.find { |x| + insert_before_index += 1 + x.kind_of?(Element) || x.kind_of?(DocType) + } + if @children[ insert_before_index ] # Not null = not end of list + if @children[ insert_before_index ].kind_of DocType + @children[ insert_before_index ] = child + else + @children[ index_before_index-1, 0 ] = child + end + else # Insert at end of list + @children[insert_before_index] = child + end + child.parent = self + else + rv = super + raise "attempted adding second root element to document" if @elements.size > 1 + rv + end + end + alias :<< :add + + def add_element(arg=nil, arg2=nil) + rv = super + raise "attempted adding second root element to document" if @elements.size > 1 + rv + end + + # @return the root Element of the document, or nil if this document + # has no children. + def root + elements[1] + #self + #@children.find { |item| item.kind_of? Element } + end + + # @return the DocType child of the document, if one exists, + # and nil otherwise. + def doctype + @children.find { |item| item.kind_of? DocType } + end + + # @return the XMLDecl of this document; if no XMLDecl has been + # set, the default declaration is returned. + def xml_decl + rv = @children[0] + return rv if rv.kind_of? XMLDecl + rv = @children.unshift(XMLDecl.default)[0] + end + + # @return the XMLDecl version of this document as a String. + # If no XMLDecl has been set, returns the default version. + def version + xml_decl().version + end + + # @return the XMLDecl encoding of this document as a String. + # If no XMLDecl has been set, returns the default encoding. + def encoding + xml_decl().encoding + end + + # @return the XMLDecl standalone value of this document as a String. + # If no XMLDecl has been set, returns the default setting. + def stand_alone? + xml_decl().stand_alone? + end + + # Write the XML tree out, optionally with indent. This writes out the + # entire XML document, including XML declarations, doctype declarations, + # and processing instructions (if any are given). + # + # A controversial point is whether Document should always write the XML + # declaration () whether or not one is given by the + # user (or source document). REXML does not write one if one was not + # specified, because it adds unneccessary bandwidth to applications such + # as XML-RPC. + # + # See also the classes in the rexml/formatters package for the proper way + # to change the default formatting of XML output + # + # _Examples_ + # Document.new("").serialize + # + # output_string = "" + # tr = Transitive.new( output_string ) + # Document.new("").serialize( tr ) + # + # output:: + # output an object which supports '<< string'; this is where the + # document will be written. + # indent:: + # An integer. If -1, no indenting will be used; otherwise, the + # indentation will be twice this number of spaces, and children will be + # indented an additional amount. For a value of 3, every item will be + # indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1 + # trans:: + # If transitive is true and indent is >= 0, then the output will be + # pretty-printed in such a way that the added whitespace does not affect + # the absolute *value* of the document -- that is, it leaves the value + # and number of Text nodes in the document unchanged. + # ie_hack:: + # Internet Explorer is the worst piece of #### to have ever been + # written, with the possible exception of Windows itself. Since IE is + # unable to parse proper XML, we have to provide a hack to generate XML + # that IE's limited abilities can handle. This hack inserts a space + # before the /> on empty tags. Defaults to false + def write( output=$stdout, indent=-1, trans=false, ie_hack=false ) + if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output) + output = Output.new( output, xml_decl.encoding ) + end + formatter = if indent > -1 + if trans + REXML::Formatters::Transitive.new( indent, ie_hack ) + else + REXML::Formatters::Pretty.new( indent, ie_hack ) + end + else + REXML::Formatters::Default.new( ie_hack ) + end + formatter.write( self, output ) + end + + + def Document::parse_stream( source, listener ) + Parsers::StreamParser.new( source, listener ).parse + end + + private + def build( source ) + Parsers::TreeParser.new( source, self ).parse + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/attlistdecl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/attlistdecl.rb new file mode 100644 index 00000000..e176bb07 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/attlistdecl.rb @@ -0,0 +1,10 @@ +require "rexml/child" +module REXML + module DTD + class AttlistDecl < Child + START = ")/um + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/dtd.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/dtd.rb new file mode 100644 index 00000000..4f735d48 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/dtd.rb @@ -0,0 +1,51 @@ +require "rexml/dtd/elementdecl" +require "rexml/dtd/entitydecl" +require "rexml/comment" +require "rexml/dtd/notationdecl" +require "rexml/dtd/attlistdecl" +require "rexml/parent" + +module REXML + module DTD + class Parser + def Parser.parse( input ) + case input + when String + parse_helper input + when File + parse_helper input.read + end + end + + # Takes a String and parses it out + def Parser.parse_helper( input ) + contents = Parent.new + while input.size > 0 + case input + when ElementDecl.PATTERN_RE + match = $& + source = $' + contents << ElementDecl.new( match ) + when AttlistDecl.PATTERN_RE + matchdata = $~ + source = $' + contents << AttlistDecl.new( matchdata ) + when EntityDecl.PATTERN_RE + matchdata = $~ + source = $' + contents << EntityDecl.new( matchdata ) + when Comment.PATTERN_RE + matchdata = $~ + source = $' + contents << Comment.new( matchdata ) + when NotationDecl.PATTERN_RE + matchdata = $~ + source = $' + contents << NotationDecl.new( matchdata ) + end + end + contents + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/elementdecl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/elementdecl.rb new file mode 100644 index 00000000..c4e620f3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/elementdecl.rb @@ -0,0 +1,17 @@ +require "rexml/child" +module REXML + module DTD + class ElementDecl < Child + START = "/um + PATTERN_RE = /^\s*#{START}\s+((?:[:\w_][-\.\w_]*:)?[-!\*\.\w_]*)(.*?)>/ + #\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true) + + def initialize match + @name = match[1] + @rest = match[2] + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/entitydecl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/entitydecl.rb new file mode 100644 index 00000000..a5f1520f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/entitydecl.rb @@ -0,0 +1,56 @@ +require "rexml/child" +module REXML + module DTD + class EntityDecl < Child + START = "/um + SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um + PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um + PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um + # + # + def initialize src + super() + md = nil + if src.match( PUBLIC ) + md = src.match( PUBLIC, true ) + @middle = "PUBLIC" + @content = "#{md[2]} #{md[4]}" + elsif src.match( SYSTEM ) + md = src.match( SYSTEM, true ) + @middle = "SYSTEM" + @content = md[2] + elsif src.match( PLAIN ) + md = src.match( PLAIN, true ) + @middle = "" + @content = md[2] + elsif src.match( PERCENT ) + md = src.match( PERCENT, true ) + @middle = "" + @content = md[2] + end + raise ParseException.new("failed Entity match", src) if md.nil? + @name = md[1] + end + + def to_s + rv = " 0 + rv << @content + rv + end + + def write( output, indent ) + indent( output, indent ) + output << to_s + end + + def EntityDecl.parse_source source, listener + md = source.match( PATTERN_RE, true ) + thing = md[0].squeeze(" \t\n\r") + listener.send inspect.downcase, thing + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/notationdecl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/notationdecl.rb new file mode 100644 index 00000000..a47ff8f2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/dtd/notationdecl.rb @@ -0,0 +1,39 @@ +require "rexml/child" +module REXML + module DTD + class NotationDecl < Child + START = "/um + SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um + def initialize src + super() + if src.match( PUBLIC ) + md = src.match( PUBLIC, true ) + elsif src.match( SYSTEM ) + md = src.match( SYSTEM, true ) + else + raise ParseException.new( "error parsing notation: no matching pattern", src ) + end + @name = md[1] + @middle = md[2] + @rest = md[3] + end + + def to_s + "" + end + + def write( output, indent ) + indent( output, indent ) + output << to_s + end + + def NotationDecl.parse_source source, listener + md = source.match( PATTERN_RE, true ) + thing = md[0].squeeze(" \t\n\r") + listener.send inspect.downcase, thing + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/element.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/element.rb new file mode 100644 index 00000000..9764d34b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/element.rb @@ -0,0 +1,1227 @@ +require "rexml/parent" +require "rexml/namespace" +require "rexml/attribute" +require "rexml/cdata" +require "rexml/xpath" +require "rexml/parseexception" + +module REXML + # An implementation note about namespaces: + # As we parse, when we find namespaces we put them in a hash and assign + # them a unique ID. We then convert the namespace prefix for the node + # to the unique ID. This makes namespace lookup much faster for the + # cost of extra memory use. We save the namespace prefix for the + # context node and convert it back when we write it. + @@namespaces = {} + + # Represents a tagged XML element. Elements are characterized by + # having children, attributes, and names, and can themselves be + # children. + class Element < Parent + include Namespace + + UNDEFINED = "UNDEFINED"; # The default name + + # Mechanisms for accessing attributes and child elements of this + # element. + attr_reader :attributes, :elements + # The context holds information about the processing environment, such as + # whitespace handling. + attr_accessor :context + + # Constructor + # arg:: + # if not supplied, will be set to the default value. + # If a String, the name of this object will be set to the argument. + # If an Element, the object will be shallowly cloned; name, + # attributes, and namespaces will be copied. Children will +not+ be + # copied. + # parent:: + # if supplied, must be a Parent, and will be used as + # the parent of this object. + # context:: + # If supplied, must be a hash containing context items. Context items + # include: + # * :respect_whitespace the value of this is :+all+ or an array of + # strings being the names of the elements to respect + # whitespace for. Defaults to :+all+. + # * :compress_whitespace the value can be :+all+ or an array of + # strings being the names of the elements to ignore whitespace on. + # Overrides :+respect_whitespace+. + # * :ignore_whitespace_nodes the value can be :+all+ or an array + # of strings being the names of the elements in which to ignore + # whitespace-only nodes. If this is set, Text nodes which contain only + # whitespace will not be added to the document tree. + # * :raw can be :+all+, or an array of strings being the names of + # the elements to process in raw mode. In raw mode, special + # characters in text is not converted to or from entities. + def initialize( arg = UNDEFINED, parent=nil, context=nil ) + super(parent) + + @elements = Elements.new(self) + @attributes = Attributes.new(self) + @context = context + + if arg.kind_of? String + self.name = arg + elsif arg.kind_of? Element + self.name = arg.expanded_name + arg.attributes.each_attribute{ |attribute| + @attributes << Attribute.new( attribute ) + } + @context = arg.context + end + end + + def inspect + rv = "<#@expanded_name" + + @attributes.each_attribute do |attr| + rv << " " + attr.write( rv, 0 ) + end + + if children.size > 0 + rv << "> ... " + else + rv << "/>" + end + end + + + # Creates a shallow copy of self. + # d = Document.new "" + # new_a = d.root.clone + # puts new_a # => "" + def clone + self.class.new self + end + + # Evaluates to the root node of the document that this element + # belongs to. If this element doesn't belong to a document, but does + # belong to another Element, the parent's root will be returned, until the + # earliest ancestor is found. + # + # Note that this is not the same as the document element. + # In the following example, is the document element, and the root + # node is the parent node of the document element. You may ask yourself + # why the root node is useful: consider the doctype and XML declaration, + # and any processing instructions before the document element... they + # are children of the root node, or siblings of the document element. + # The only time this isn't true is when an Element is created that is + # not part of any Document. In this case, the ancestor that has no + # parent acts as the root node. + # d = Document.new '' + # a = d[1] ; c = a[1][1] + # d.root_node == d # TRUE + # a.root_node # namely, d + # c.root_node # again, d + def root_node + parent.nil? ? self : parent.root_node + end + + def root + return elements[1] if self.kind_of? Document + return self if parent.kind_of? Document or parent.nil? + return parent.root + end + + # Evaluates to the document to which this element belongs, or nil if this + # element doesn't belong to a document. + def document + rt = root + rt.parent if rt + end + + # Evaluates to +true+ if whitespace is respected for this element. This + # is the case if: + # 1. Neither :+respect_whitespace+ nor :+compress_whitespace+ has any value + # 2. The context has :+respect_whitespace+ set to :+all+ or + # an array containing the name of this element, and + # :+compress_whitespace+ isn't set to :+all+ or an array containing the + # name of this element. + # The evaluation is tested against +expanded_name+, and so is namespace + # sensitive. + def whitespace + @whitespace = nil + if @context + if @context[:respect_whitespace] + @whitespace = (@context[:respect_whitespace] == :all or + @context[:respect_whitespace].include? expanded_name) + end + @whitespace = false if (@context[:compress_whitespace] and + (@context[:compress_whitespace] == :all or + @context[:compress_whitespace].include? expanded_name) + ) + end + @whitespace = true unless @whitespace == false + @whitespace + end + + def ignore_whitespace_nodes + @ignore_whitespace_nodes = false + if @context + if @context[:ignore_whitespace_nodes] + @ignore_whitespace_nodes = + (@context[:ignore_whitespace_nodes] == :all or + @context[:ignore_whitespace_nodes].include? expanded_name) + end + end + end + + # Evaluates to +true+ if raw mode is set for this element. This + # is the case if the context has :+raw+ set to :+all+ or + # an array containing the name of this element. + # + # The evaluation is tested against +expanded_name+, and so is namespace + # sensitive. + def raw + @raw = (@context and @context[:raw] and + (@context[:raw] == :all or + @context[:raw].include? expanded_name)) + @raw + end + + #once :whitespace, :raw, :ignore_whitespace_nodes + + ################################################# + # Namespaces # + ################################################# + + # Evaluates to an +Array+ containing the prefixes (names) of all defined + # namespaces at this context node. + # doc = Document.new("") + # doc.elements['//b'].prefixes # -> ['x', 'y'] + def prefixes + prefixes = [] + prefixes = parent.prefixes if parent + prefixes |= attributes.prefixes + return prefixes + end + + def namespaces + namespaces = {} + namespaces = parent.namespaces if parent + namespaces = namespaces.merge( attributes.namespaces ) + return namespaces + end + + # Evalutas to the URI for a prefix, or the empty string if no such + # namespace is declared for this element. Evaluates recursively for + # ancestors. Returns the default namespace, if there is one. + # prefix:: + # the prefix to search for. If not supplied, returns the default + # namespace if one exists + # Returns:: + # the namespace URI as a String, or nil if no such namespace + # exists. If the namespace is undefined, returns an empty string + # doc = Document.new("") + # b = doc.elements['//b'] + # b.namespace # -> '1' + # b.namespace("y") # -> '2' + def namespace(prefix=nil) + if prefix.nil? + prefix = prefix() + end + if prefix == '' + prefix = "xmlns" + else + prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns' + end + ns = attributes[ prefix ] + ns = parent.namespace(prefix) if ns.nil? and parent + ns = '' if ns.nil? and prefix == 'xmlns' + return ns + end + + # Adds a namespace to this element. + # prefix:: + # the prefix string, or the namespace URI if +uri+ is not + # supplied + # uri:: + # the namespace URI. May be nil, in which +prefix+ is used as + # the URI + # Evaluates to: this Element + # a = Element.new("a") + # a.add_namespace("xmlns:foo", "bar" ) + # a.add_namespace("foo", "bar") # shorthand for previous line + # a.add_namespace("twiddle") + # puts a #-> + def add_namespace( prefix, uri=nil ) + unless uri + @attributes["xmlns"] = prefix + else + prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/ + @attributes[ prefix ] = uri + end + self + end + + # Removes a namespace from this node. This only works if the namespace is + # actually declared in this node. If no argument is passed, deletes the + # default namespace. + # + # Evaluates to: this element + # doc = Document.new "" + # doc.root.delete_namespace + # puts doc # -> + # doc.root.delete_namespace 'foo' + # puts doc # -> + def delete_namespace namespace="xmlns" + namespace = "xmlns:#{namespace}" unless namespace == 'xmlns' + attribute = attributes.get_attribute(namespace) + attribute.remove unless attribute.nil? + self + end + + ################################################# + # Elements # + ################################################# + + # Adds a child to this element, optionally setting attributes in + # the element. + # element:: + # optional. If Element, the element is added. + # Otherwise, a new Element is constructed with the argument (see + # Element.initialize). + # attrs:: + # If supplied, must be a Hash containing String name,value + # pairs, which will be used to set the attributes of the new Element. + # Returns:: the Element that was added + # el = doc.add_element 'my-tag' + # el = doc.add_element 'my-tag', {'attr1'=>'val1', 'attr2'=>'val2'} + # el = Element.new 'my-tag' + # doc.add_element el + def add_element element, attrs=nil + raise "First argument must be either an element name, or an Element object" if element.nil? + el = @elements.add(element) + attrs.each do |key, value| + el.attributes[key]=Attribute.new(key,value,self) + end if attrs.kind_of? Hash + el + end + + # Deletes a child element. + # element:: + # Must be an +Element+, +String+, or +Integer+. If Element, + # the element is removed. If String, the element is found (via XPath) + # and removed. This means that any parent can remove any + # descendant. If Integer, the Element indexed by that number will be + # removed. + # Returns:: the element that was removed. + # doc.delete_element "/a/b/c[@id='4']" + # doc.delete_element doc.elements["//k"] + # doc.delete_element 1 + def delete_element element + @elements.delete element + end + + # Evaluates to +true+ if this element has at least one child Element + # doc = Document.new "Text" + # doc.root.has_elements # -> true + # doc.elements["/a/b"].has_elements # -> false + # doc.elements["/a/c"].has_elements # -> false + def has_elements? + !@elements.empty? + end + + # Iterates through the child elements, yielding for each Element that + # has a particular attribute set. + # key:: + # the name of the attribute to search for + # value:: + # the value of the attribute + # max:: + # (optional) causes this method to return after yielding + # for this number of matching children + # name:: + # (optional) if supplied, this is an XPath that filters + # the children to check. + # + # doc = Document.new "" + # # Yields b, c, d + # doc.root.each_element_with_attribute( 'id' ) {|e| p e} + # # Yields b, d + # doc.root.each_element_with_attribute( 'id', '1' ) {|e| p e} + # # Yields b + # doc.root.each_element_with_attribute( 'id', '1', 1 ) {|e| p e} + # # Yields d + # doc.root.each_element_with_attribute( 'id', '1', 0, 'd' ) {|e| p e} + def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element + each_with_something( proc {|child| + if value.nil? + child.attributes[key] != nil + else + child.attributes[key]==value + end + }, max, name, &block ) + end + + # Iterates through the children, yielding for each Element that + # has a particular text set. + # text:: + # the text to search for. If nil, or not supplied, will itterate + # over all +Element+ children that contain at least one +Text+ node. + # max:: + # (optional) causes this method to return after yielding + # for this number of matching children + # name:: + # (optional) if supplied, this is an XPath that filters + # the children to check. + # + # doc = Document.new 'bbd' + # # Yields b, c, d + # doc.each_element_with_text {|e|p e} + # # Yields b, c + # doc.each_element_with_text('b'){|e|p e} + # # Yields b + # doc.each_element_with_text('b', 1){|e|p e} + # # Yields d + # doc.each_element_with_text(nil, 0, 'd'){|e|p e} + def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element + each_with_something( proc {|child| + if text.nil? + child.has_text? + else + child.text == text + end + }, max, name, &block ) + end + + # Synonym for Element.elements.each + def each_element( xpath=nil, &block ) # :yields: Element + @elements.each( xpath, &block ) + end + + # Synonym for Element.to_a + # This is a little slower than calling elements.each directly. + # xpath:: any XPath by which to search for elements in the tree + # Returns:: an array of Elements that match the supplied path + def get_elements( xpath ) + @elements.to_a( xpath ) + end + + # Returns the next sibling that is an element, or nil if there is + # no Element sibling after this one + # doc = Document.new 'text' + # doc.root.elements['b'].next_element #-> + # doc.root.elements['c'].next_element #-> nil + def next_element + element = next_sibling + element = element.next_sibling until element.nil? or element.kind_of? Element + return element + end + + # Returns the previous sibling that is an element, or nil if there is + # no Element sibling prior to this one + # doc = Document.new 'text' + # doc.root.elements['c'].previous_element #-> + # doc.root.elements['b'].previous_element #-> nil + def previous_element + element = previous_sibling + element = element.previous_sibling until element.nil? or element.kind_of? Element + return element + end + + + ################################################# + # Text # + ################################################# + + # Evaluates to +true+ if this element has at least one Text child + def has_text? + not text().nil? + end + + # A convenience method which returns the String value of the _first_ + # child text element, if one exists, and +nil+ otherwise. + # + # Note that an element may have multiple Text elements, perhaps + # separated by other children. Be aware that this method only returns + # the first Text node. + # + # This method returns the +value+ of the first text child node, which + # ignores the +raw+ setting, so always returns normalized text. See + # the Text::value documentation. + # + # doc = Document.new "

    some text this is bold! more text

    " + # # The element 'p' has two text elements, "some text " and " more text". + # doc.root.text #-> "some text " + def text( path = nil ) + rv = get_text(path) + return rv.value unless rv.nil? + nil + end + + # Returns the first child Text node, if any, or +nil+ otherwise. + # This method returns the actual +Text+ node, rather than the String content. + # doc = Document.new "

    some text this is bold! more text

    " + # # The element 'p' has two text elements, "some text " and " more text". + # doc.root.get_text.value #-> "some text " + def get_text path = nil + rv = nil + if path + element = @elements[ path ] + rv = element.get_text unless element.nil? + else + rv = @children.find { |node| node.kind_of? Text } + end + return rv + end + + # Sets the first Text child of this object. See text() for a + # discussion about Text children. + # + # If a Text child already exists, the child is replaced by this + # content. This means that Text content can be deleted by calling + # this method with a nil argument. In this case, the next Text + # child becomes the first Text child. In no case is the order of + # any siblings disturbed. + # text:: + # If a String, a new Text child is created and added to + # this Element as the first Text child. If Text, the text is set + # as the first Child element. If nil, then any existing first Text + # child is removed. + # Returns:: this Element. + # doc = Document.new '' + # doc.root.text = 'Sean' #-> 'Sean' + # doc.root.text = 'Elliott' #-> 'Elliott' + # doc.root.add_element 'c' #-> 'Elliott' + # doc.root.text = 'Russell' #-> 'Russell' + # doc.root.text = nil #-> '' + def text=( text ) + if text.kind_of? String + text = Text.new( text, whitespace(), nil, raw() ) + elsif text and !text.kind_of? Text + text = Text.new( text.to_s, whitespace(), nil, raw() ) + end + old_text = get_text + if text.nil? + old_text.remove unless old_text.nil? + else + if old_text.nil? + self << text + else + old_text.replace_with( text ) + end + end + return self + end + + # A helper method to add a Text child. Actual Text instances can + # be added with regular Parent methods, such as add() and <<() + # text:: + # if a String, a new Text instance is created and added + # to the parent. If Text, the object is added directly. + # Returns:: this Element + # e = Element.new('a') #-> + # e.add_text 'foo' #-> foo + # e.add_text Text.new(' bar') #-> foo bar + # Note that at the end of this example, the branch has 3 nodes; the 'e' + # element and 2 Text node children. + def add_text( text ) + if text.kind_of? String + if @children[-1].kind_of? Text + @children[-1] << text + return + end + text = Text.new( text, whitespace(), nil, raw() ) + end + self << text unless text.nil? + return self + end + + def node_type + :element + end + + def xpath + path_elements = [] + cur = self + path_elements << __to_xpath_helper( self ) + while cur.parent + cur = cur.parent + path_elements << __to_xpath_helper( cur ) + end + return path_elements.reverse.join( "/" ) + end + + ################################################# + # Attributes # + ################################################# + + def attribute( name, namespace=nil ) + prefix = nil + prefix = namespaces.index(namespace) if namespace + prefix = nil if prefix == 'xmlns' + attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" ) + end + + # Evaluates to +true+ if this element has any attributes set, false + # otherwise. + def has_attributes? + return !@attributes.empty? + end + + # Adds an attribute to this element, overwriting any existing attribute + # by the same name. + # key:: + # can be either an Attribute or a String. If an Attribute, + # the attribute is added to the list of Element attributes. If String, + # the argument is used as the name of the new attribute, and the value + # parameter must be supplied. + # value:: + # Required if +key+ is a String, and ignored if the first argument is + # an Attribute. This is a String, and is used as the value + # of the new Attribute. This should be the unnormalized value of the + # attribute (without entities). + # Returns:: the Attribute added + # e = Element.new 'e' + # e.add_attribute( 'a', 'b' ) #-> + # e.add_attribute( 'x:a', 'c' ) #-> + # e.add_attribute Attribute.new('b', 'd') #-> + def add_attribute( key, value=nil ) + if key.kind_of? Attribute + @attributes << key + else + @attributes[key] = value + end + end + + # Add multiple attributes to this element. + # hash:: is either a hash, or array of arrays + # el.add_attributes( {"name1"=>"value1", "name2"=>"value2"} ) + # el.add_attributes( [ ["name1","value1"], ["name2"=>"value2"] ] ) + def add_attributes hash + if hash.kind_of? Hash + hash.each_pair {|key, value| @attributes[key] = value } + elsif hash.kind_of? Array + hash.each { |value| @attributes[ value[0] ] = value[1] } + end + end + + # Removes an attribute + # key:: + # either an Attribute or a String. In either case, the + # attribute is found by matching the attribute name to the argument, + # and then removed. If no attribute is found, no action is taken. + # Returns:: + # the attribute removed, or nil if this Element did not contain + # a matching attribute + # e = Element.new('E') + # e.add_attribute( 'name', 'Sean' ) #-> + # r = e.add_attribute( 'sur:name', 'Russell' ) #-> + # e.delete_attribute( 'name' ) #-> + # e.delete_attribute( r ) #-> + def delete_attribute(key) + attr = @attributes.get_attribute(key) + attr.remove unless attr.nil? + end + + ################################################# + # Other Utilities # + ################################################# + + # Get an array of all CData children. + # IMMUTABLE + def cdatas + find_all { |child| child.kind_of? CData }.freeze + end + + # Get an array of all Comment children. + # IMMUTABLE + def comments + find_all { |child| child.kind_of? Comment }.freeze + end + + # Get an array of all Instruction children. + # IMMUTABLE + def instructions + find_all { |child| child.kind_of? Instruction }.freeze + end + + # Get an array of all Text children. + # IMMUTABLE + def texts + find_all { |child| child.kind_of? Text }.freeze + end + + # == DEPRECATED + # See REXML::Formatters + # + # Writes out this element, and recursively, all children. + # output:: + # output an object which supports '<< string'; this is where the + # document will be written. + # indent:: + # An integer. If -1, no indenting will be used; otherwise, the + # indentation will be this number of spaces, and children will be + # indented an additional amount. Defaults to -1 + # transitive:: + # If transitive is true and indent is >= 0, then the output will be + # pretty-printed in such a way that the added whitespace does not affect + # the parse tree of the document + # ie_hack:: + # Internet Explorer is the worst piece of #### to have ever been + # written, with the possible exception of Windows itself. Since IE is + # unable to parse proper XML, we have to provide a hack to generate XML + # that IE's limited abilities can handle. This hack inserts a space + # before the /> on empty tags. Defaults to false + # + # out = '' + # doc.write( out ) #-> doc is written to the string 'out' + # doc.write( $stdout ) #-> doc written to the console + def write(writer=$stdout, indent=-1, transitive=false, ie_hack=false) + Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters") + formatter = if indent > -1 + if transitive + REXML::Formatters::Transitive.new( indent, ie_hack ) + else + REXML::Formatters::Pretty.new( indent, ie_hack ) + end + else + REXML::Formatters::Default.new( ie_hack ) + end + formatter.write( self, output ) + end + + + private + def __to_xpath_helper node + rv = node.expanded_name.clone + if node.parent + results = node.parent.find_all {|n| + n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name + } + if results.length > 1 + idx = results.index( node ) + rv << "[#{idx+1}]" + end + end + rv + end + + # A private helper method + def each_with_something( test, max=0, name=nil ) + num = 0 + child=nil + @elements.each( name ){ |child| + yield child if test.call(child) and num += 1 + return if max>0 and num == max + } + end + end + + ######################################################################## + # ELEMENTS # + ######################################################################## + + # A class which provides filtering of children for Elements, and + # XPath search support. You are expected to only encounter this class as + # the element.elements object. Therefore, you are + # _not_ expected to instantiate this yourself. + class Elements + include Enumerable + # Constructor + # parent:: the parent Element + def initialize parent + @element = parent + end + + # Fetches a child element. Filters only Element children, regardless of + # the XPath match. + # index:: + # the search parameter. This is either an Integer, which + # will be used to find the index'th child Element, or an XPath, + # which will be used to search for the Element. Because + # of the nature of XPath searches, any element in the connected XML + # document can be fetched through any other element. The + # Integer index is 1-based, not 0-based. This means that the first + # child element is at index 1, not 0, and the +n+th element is at index + # +n+, not n-1. This is because XPath indexes element children + # starting from 1, not 0, and the indexes should be the same. + # name:: + # optional, and only used in the first argument is an + # Integer. In that case, the index'th child Element that has the + # supplied name will be returned. Note again that the indexes start at 1. + # Returns:: the first matching Element, or nil if no child matched + # doc = Document.new '' + # doc.root.elements[1] #-> + # doc.root.elements['c'] #-> + # doc.root.elements[2,'c'] #-> + def []( index, name=nil) + if index.kind_of? Integer + raise "index (#{index}) must be >= 1" if index < 1 + name = literalize(name) if name + num = 0 + child = nil + @element.find { |child| + child.kind_of? Element and + (name.nil? ? true : child.has_name?( name )) and + (num += 1) == index + } + else + return XPath::first( @element, index ) + #{ |element| + # return element if element.kind_of? Element + #} + #return nil + end + end + + # Sets an element, replacing any previous matching element. If no + # existing element is found ,the element is added. + # index:: Used to find a matching element to replace. See [](). + # element:: + # The element to replace the existing element with + # the previous element + # Returns:: nil if no previous element was found. + # + # doc = Document.new '' + # doc.root.elements[10] = Element.new('b') #-> + # doc.root.elements[1] #-> + # doc.root.elements[1] = Element.new('c') #-> + # doc.root.elements['c'] = Element.new('d') #-> + def []=( index, element ) + previous = self[index] + if previous.nil? + @element.add element + else + previous.replace_with element + end + return previous + end + + # Returns +true+ if there are no +Element+ children, +false+ otherwise + def empty? + @element.find{ |child| child.kind_of? Element}.nil? + end + + # Returns the index of the supplied child (starting at 1), or -1 if + # the element is not a child + # element:: an +Element+ child + def index element + rv = 0 + found = @element.find do |child| + child.kind_of? Element and + (rv += 1) and + child == element + end + return rv if found == element + return -1 + end + + # Deletes a child Element + # element:: + # Either an Element, which is removed directly; an + # xpath, where the first matching child is removed; or an Integer, + # where the n'th Element is removed. + # Returns:: the removed child + # doc = Document.new '' + # b = doc.root.elements[1] + # doc.root.elements.delete b #-> + # doc.elements.delete("a/c[@id='1']") #-> + # doc.root.elements.delete 1 #-> + def delete element + if element.kind_of? Element + @element.delete element + else + el = self[element] + el.remove if el + end + end + + # Removes multiple elements. Filters for Element children, regardless of + # XPath matching. + # xpath:: all elements matching this String path are removed. + # Returns:: an Array of Elements that have been removed + # doc = Document.new '' + # deleted = doc.elements.delete_all 'a/c' #-> [, , , ] + def delete_all( xpath ) + rv = [] + XPath::each( @element, xpath) {|element| + rv << element if element.kind_of? Element + } + rv.each do |element| + @element.delete element + element.remove + end + return rv + end + + # Adds an element + # element:: + # if supplied, is either an Element, String, or + # Source (see Element.initialize). If not supplied or nil, a + # new, default Element will be constructed + # Returns:: the added Element + # a = Element.new('a') + # a.elements.add(Element.new('b')) #-> + # a.elements.add('c') #-> + def add element=nil + rv = nil + if element.nil? + Element.new("", self, @element.context) + elsif not element.kind_of?(Element) + Element.new(element, self, @element.context) + else + @element << element + element.context = @element.context + element + end + end + + alias :<< :add + + # Iterates through all of the child Elements, optionally filtering + # them by a given XPath + # xpath:: + # optional. If supplied, this is a String XPath, and is used to + # filter the children, so that only matching children are yielded. Note + # that XPaths are automatically filtered for Elements, so that + # non-Element children will not be yielded + # doc = Document.new 'sean' + # doc.root.each {|e|p e} #-> Yields b, c, d, b, c, d elements + # doc.root.each('b') {|e|p e} #-> Yields b, b elements + # doc.root.each('child::node()') {|e|p e} + # #-> Yields , , , , , + # XPath.each(doc.root, 'child::node()', &block) + # #-> Yields , , , sean, , , + def each( xpath=nil, &block) + XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element } + end + + def collect( xpath=nil, &block ) + collection = [] + XPath::each( @element, xpath ) {|e| + collection << yield(e) if e.kind_of?(Element) + } + collection + end + + def inject( xpath=nil, initial=nil, &block ) + first = true + XPath::each( @element, xpath ) {|e| + if (e.kind_of? Element) + if (first and initial == nil) + initial = e + first = false + else + initial = yield( initial, e ) if e.kind_of? Element + end + end + } + initial + end + + # Returns the number of +Element+ children of the parent object. + # doc = Document.new 'seanelliottrussell' + # doc.root.size #-> 6, 3 element and 3 text nodes + # doc.root.elements.size #-> 3 + def size + count = 0 + @element.each {|child| count+=1 if child.kind_of? Element } + count + end + + # Returns an Array of Element children. An XPath may be supplied to + # filter the children. Only Element children are returned, even if the + # supplied XPath matches non-Element children. + # doc = Document.new 'seanelliott' + # doc.root.elements.to_a #-> [ , ] + # doc.root.elements.to_a("child::node()") #-> [ , ] + # XPath.match(doc.root, "child::node()") #-> [ sean, , elliott, ] + def to_a( xpath=nil ) + rv = XPath.match( @element, xpath ) + return rv.find_all{|e| e.kind_of? Element} if xpath + rv + end + + private + # Private helper class. Removes quotes from quoted strings + def literalize name + name = name[1..-2] if name[0] == ?' or name[0] == ?" #' + name + end + end + + ######################################################################## + # ATTRIBUTES # + ######################################################################## + + # A class that defines the set of Attributes of an Element and provides + # operations for accessing elements in that set. + class Attributes < Hash + # Constructor + # element:: the Element of which this is an Attribute + def initialize element + @element = element + end + + # Fetches an attribute value. If you want to get the Attribute itself, + # use get_attribute() + # name:: an XPath attribute name. Namespaces are relevant here. + # Returns:: + # the String value of the matching attribute, or +nil+ if no + # matching attribute was found. This is the unnormalized value + # (with entities expanded). + # + # doc = Document.new "" + # doc.root.attributes['att'] #-> '<' + # doc.root.attributes['bar:att'] #-> '2' + def [](name) + attr = get_attribute(name) + return attr.value unless attr.nil? + return nil + end + + def to_a + values.flatten + end + + # Returns the number of attributes the owning Element contains. + # doc = Document "" + # doc.root.attributes.length #-> 3 + def length + c = 0 + each_attribute { c+=1 } + c + end + alias :size :length + + # Itterates over the attributes of an Element. Yields actual Attribute + # nodes, not String values. + # + # doc = Document.new '' + # doc.root.attributes.each_attribute {|attr| + # p attr.expanded_name+" => "+attr.value + # } + def each_attribute # :yields: attribute + each_value do |val| + if val.kind_of? Attribute + yield val + else + val.each_value { |atr| yield atr } + end + end + end + + # Itterates over each attribute of an Element, yielding the expanded name + # and value as a pair of Strings. + # + # doc = Document.new '' + # doc.root.attributes.each {|name, value| p name+" => "+value } + def each + each_attribute do |attr| + yield attr.expanded_name, attr.value + end + end + + # Fetches an attribute + # name:: + # the name by which to search for the attribute. Can be a + # prefix:name namespace name. + # Returns:: The first matching attribute, or nil if there was none. This + # value is an Attribute node, not the String value of the attribute. + # doc = Document.new '' + # doc.root.attributes.get_attribute("foo").value #-> "2" + # doc.root.attributes.get_attribute("x:foo").value #-> "1" + def get_attribute( name ) + attr = fetch( name, nil ) + if attr.nil? + return nil if name.nil? + # Look for prefix + name =~ Namespace::NAMESPLIT + prefix, n = $1, $2 + if prefix + attr = fetch( n, nil ) + # check prefix + if attr == nil + elsif attr.kind_of? Attribute + return attr if prefix == attr.prefix + else + attr = attr[ prefix ] + return attr + end + end + element_document = @element.document + if element_document and element_document.doctype + expn = @element.expanded_name + expn = element_document.doctype.name if expn.size == 0 + attr_val = element_document.doctype.attribute_of(expn, name) + return Attribute.new( name, attr_val ) if attr_val + end + return nil + end + if attr.kind_of? Hash + attr = attr[ @element.prefix ] + end + return attr + end + + # Sets an attribute, overwriting any existing attribute value by the + # same name. Namespace is significant. + # name:: the name of the attribute + # value:: + # (optional) If supplied, the value of the attribute. If + # nil, any existing matching attribute is deleted. + # Returns:: + # Owning element + # doc = Document.new "" + # doc.root.attributes['y:foo'] = '2' + # doc.root.attributes['foo'] = '4' + # doc.root.attributes['x:foo'] = nil + def []=( name, value ) + if value.nil? # Delete the named attribute + attr = get_attribute(name) + delete attr + return + end + element_document = @element.document + unless value.kind_of? Attribute + if @element.document and @element.document.doctype + value = Text::normalize( value, @element.document.doctype ) + else + value = Text::normalize( value, nil ) + end + value = Attribute.new(name, value) + end + value.element = @element + old_attr = fetch(value.name, nil) + if old_attr.nil? + store(value.name, value) + elsif old_attr.kind_of? Hash + old_attr[value.prefix] = value + elsif old_attr.prefix != value.prefix + # Check for conflicting namespaces + raise ParseException.new( + "Namespace conflict in adding attribute \"#{value.name}\": "+ + "Prefix \"#{old_attr.prefix}\" = "+ + "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+ + "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if + value.prefix != "xmlns" and old_attr.prefix != "xmlns" and + @element.namespace( old_attr.prefix ) == + @element.namespace( value.prefix ) + store value.name, { old_attr.prefix => old_attr, + value.prefix => value } + else + store value.name, value + end + return @element + end + + # Returns an array of Strings containing all of the prefixes declared + # by this set of # attributes. The array does not include the default + # namespace declaration, if one exists. + # doc = Document.new("") + # prefixes = doc.root.attributes.prefixes #-> ['x', 'y'] + def prefixes + ns = [] + each_attribute do |attribute| + ns << attribute.name if attribute.prefix == 'xmlns' + end + if @element.document and @element.document.doctype + expn = @element.expanded_name + expn = @element.document.doctype.name if expn.size == 0 + @element.document.doctype.attributes_of(expn).each { + |attribute| + ns << attribute.name if attribute.prefix == 'xmlns' + } + end + ns + end + + def namespaces + namespaces = {} + each_attribute do |attribute| + namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns' + end + if @element.document and @element.document.doctype + expn = @element.expanded_name + expn = @element.document.doctype.name if expn.size == 0 + @element.document.doctype.attributes_of(expn).each { + |attribute| + namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns' + } + end + namespaces + end + + # Removes an attribute + # attribute:: + # either a String, which is the name of the attribute to remove -- + # namespaces are significant here -- or the attribute to remove. + # Returns:: the owning element + # doc = Document.new "" + # doc.root.attributes.delete 'foo' #-> " + # doc.root.attributes.delete 'x:foo' #-> " + # attr = doc.root.attributes.get_attribute('y:foo') + # doc.root.attributes.delete attr #-> " + def delete( attribute ) + name = nil + prefix = nil + if attribute.kind_of? Attribute + name = attribute.name + prefix = attribute.prefix + else + attribute =~ Namespace::NAMESPLIT + prefix, name = $1, $2 + prefix = '' unless prefix + end + old = fetch(name, nil) + attr = nil + if old.kind_of? Hash # the supplied attribute is one of many + attr = old.delete(prefix) + if old.size == 1 + repl = nil + old.each_value{|v| repl = v} + store name, repl + end + elsif old.nil? + return @element + else # the supplied attribute is a top-level one + attr = old + res = super(name) + end + @element + end + + # Adds an attribute, overriding any existing attribute by the + # same name. Namespaces are significant. + # attribute:: An Attribute + def add( attribute ) + self[attribute.name] = attribute + end + + alias :<< :add + + # Deletes all attributes matching a name. Namespaces are significant. + # name:: + # A String; all attributes that match this path will be removed + # Returns:: an Array of the Attributes that were removed + def delete_all( name ) + rv = [] + each_attribute { |attribute| + rv << attribute if attribute.expanded_name == name + } + rv.each{ |attr| attr.remove } + return rv + end + + # The +get_attribute_ns+ method retrieves a method by its namespace + # and name. Thus it is possible to reliably identify an attribute + # even if an XML processor has changed the prefix. + # + # Method contributed by Henrik Martensson + def get_attribute_ns(namespace, name) + each_attribute() { |attribute| + if name == attribute.name && + namespace == attribute.namespace() + return attribute + end + } + nil + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encoding.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encoding.rb new file mode 100644 index 00000000..a01763be --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encoding.rb @@ -0,0 +1,71 @@ +# -*- mode: ruby; ruby-indent-level: 2; indent-tabs-mode: t; tab-width: 2 -*- vim: sw=2 ts=2 +module REXML + module Encoding + @encoding_methods = {} + def self.register(enc, &block) + @encoding_methods[enc] = block + end + def self.apply(obj, enc) + @encoding_methods[enc][obj] + end + def self.encoding_method(enc) + @encoding_methods[enc] + end + + # Native, default format is UTF-8, so it is declared here rather than in + # an encodings/ definition. + UTF_8 = 'UTF-8' + UTF_16 = 'UTF-16' + UNILE = 'UNILE' + + # ID ---> Encoding name + attr_reader :encoding + def encoding=( enc ) + old_verbosity = $VERBOSE + begin + $VERBOSE = false + enc = enc.nil? ? nil : enc.upcase + return false if defined? @encoding and enc == @encoding + if enc and enc != UTF_8 + @encoding = enc + raise ArgumentError, "Bad encoding name #@encoding" unless @encoding =~ /^[\w-]+$/ + @encoding.untaint + begin + require 'rexml/encodings/ICONV.rb' + Encoding.apply(self, "ICONV") + rescue LoadError, Exception + begin + enc_file = File.join( "rexml", "encodings", "#@encoding.rb" ) + require enc_file + Encoding.apply(self, @encoding) + rescue LoadError => err + puts err.message + raise ArgumentError, "No decoder found for encoding #@encoding. Please install iconv." + end + end + else + @encoding = UTF_8 + require 'rexml/encodings/UTF-8.rb' + Encoding.apply(self, @encoding) + end + ensure + $VERBOSE = old_verbosity + end + true + end + + def check_encoding str + # We have to recognize UTF-16, LSB UTF-16, and UTF-8 + if str[0] == 0xfe && str[1] == 0xff + str[0,2] = "" + return UTF_16 + elsif str[0] == 0xff && str[1] == 0xfe + str[0,2] = "" + return UNILE + end + str =~ /^\s*<\?xml\s+version\s*=\s*(['"]).*?\1\s+encoding\s*=\s*(["'])(.*?)\2/um + return $3.upcase if $3 + return UTF_8 + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/CP-1252.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/CP-1252.rb new file mode 100644 index 00000000..8675f9ff --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/CP-1252.rb @@ -0,0 +1,103 @@ +# +# This class was contributed by Mikko Tiihonen mikko DOT tiihonen AT hut DOT fi +# +module REXML + module Encoding + register( "CP-1252" ) do |o| + class << o + alias encode encode_cp1252 + alias decode decode_cp1252 + end + end + + # Convert from UTF-8 + def encode_cp1252(content) + array_utf8 = content.unpack('U*') + array_enc = [] + array_utf8.each do |num| + case num + # shortcut first bunch basic characters + when 0..0xFF; array_enc << num + # characters added compared to iso-8859-1 + when 0x20AC; array_enc << 0x80 # 0xe2 0x82 0xac + when 0x201A; array_enc << 0x82 # 0xe2 0x82 0x9a + when 0x0192; array_enc << 0x83 # 0xc6 0x92 + when 0x201E; array_enc << 0x84 # 0xe2 0x82 0x9e + when 0x2026; array_enc << 0x85 # 0xe2 0x80 0xa6 + when 0x2020; array_enc << 0x86 # 0xe2 0x80 0xa0 + when 0x2021; array_enc << 0x87 # 0xe2 0x80 0xa1 + when 0x02C6; array_enc << 0x88 # 0xcb 0x86 + when 0x2030; array_enc << 0x89 # 0xe2 0x80 0xb0 + when 0x0160; array_enc << 0x8A # 0xc5 0xa0 + when 0x2039; array_enc << 0x8B # 0xe2 0x80 0xb9 + when 0x0152; array_enc << 0x8C # 0xc5 0x92 + when 0x017D; array_enc << 0x8E # 0xc5 0xbd + when 0x2018; array_enc << 0x91 # 0xe2 0x80 0x98 + when 0x2019; array_enc << 0x92 # 0xe2 0x80 0x99 + when 0x201C; array_enc << 0x93 # 0xe2 0x80 0x9c + when 0x201D; array_enc << 0x94 # 0xe2 0x80 0x9d + when 0x2022; array_enc << 0x95 # 0xe2 0x80 0xa2 + when 0x2013; array_enc << 0x96 # 0xe2 0x80 0x93 + when 0x2014; array_enc << 0x97 # 0xe2 0x80 0x94 + when 0x02DC; array_enc << 0x98 # 0xcb 0x9c + when 0x2122; array_enc << 0x99 # 0xe2 0x84 0xa2 + when 0x0161; array_enc << 0x9A # 0xc5 0xa1 + when 0x203A; array_enc << 0x9B # 0xe2 0x80 0xba + when 0x0152; array_enc << 0x9C # 0xc5 0x93 + when 0x017E; array_enc << 0x9E # 0xc5 0xbe + when 0x0178; array_enc << 0x9F # 0xc5 0xb8 + else + # all remaining basic characters can be used directly + if num <= 0xFF + array_enc << num + else + # Numeric entity (&#nnnn;); shard by Stefan Scholl + array_enc.concat "&\##{num};".unpack('C*') + end + end + end + array_enc.pack('C*') + end + + # Convert to UTF-8 + def decode_cp1252(str) + array_latin9 = str.unpack('C*') + array_enc = [] + array_latin9.each do |num| + case num + # characters that added compared to iso-8859-1 + when 0x80; array_enc << 0x20AC # 0xe2 0x82 0xac + when 0x82; array_enc << 0x201A # 0xe2 0x82 0x9a + when 0x83; array_enc << 0x0192 # 0xc6 0x92 + when 0x84; array_enc << 0x201E # 0xe2 0x82 0x9e + when 0x85; array_enc << 0x2026 # 0xe2 0x80 0xa6 + when 0x86; array_enc << 0x2020 # 0xe2 0x80 0xa0 + when 0x87; array_enc << 0x2021 # 0xe2 0x80 0xa1 + when 0x88; array_enc << 0x02C6 # 0xcb 0x86 + when 0x89; array_enc << 0x2030 # 0xe2 0x80 0xb0 + when 0x8A; array_enc << 0x0160 # 0xc5 0xa0 + when 0x8B; array_enc << 0x2039 # 0xe2 0x80 0xb9 + when 0x8C; array_enc << 0x0152 # 0xc5 0x92 + when 0x8E; array_enc << 0x017D # 0xc5 0xbd + when 0x91; array_enc << 0x2018 # 0xe2 0x80 0x98 + when 0x92; array_enc << 0x2019 # 0xe2 0x80 0x99 + when 0x93; array_enc << 0x201C # 0xe2 0x80 0x9c + when 0x94; array_enc << 0x201D # 0xe2 0x80 0x9d + when 0x95; array_enc << 0x2022 # 0xe2 0x80 0xa2 + when 0x96; array_enc << 0x2013 # 0xe2 0x80 0x93 + when 0x97; array_enc << 0x2014 # 0xe2 0x80 0x94 + when 0x98; array_enc << 0x02DC # 0xcb 0x9c + when 0x99; array_enc << 0x2122 # 0xe2 0x84 0xa2 + when 0x9A; array_enc << 0x0161 # 0xc5 0xa1 + when 0x9B; array_enc << 0x203A # 0xe2 0x80 0xba + when 0x9C; array_enc << 0x0152 # 0xc5 0x93 + when 0x9E; array_enc << 0x017E # 0xc5 0xbe + when 0x9F; array_enc << 0x0178 # 0xc5 0xb8 + else + array_enc << num + end + end + array_enc.pack('U*') + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/EUC-JP.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/EUC-JP.rb new file mode 100644 index 00000000..db37b6bf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/EUC-JP.rb @@ -0,0 +1,35 @@ +module REXML + module Encoding + begin + require 'uconv' + + def decode_eucjp(str) + Uconv::euctou8(str) + end + + def encode_eucjp content + Uconv::u8toeuc(content) + end + rescue LoadError + require 'nkf' + + EUCTOU8 = '-Ewm0' + U8TOEUC = '-Wem0' + + def decode_eucjp(str) + NKF.nkf(EUCTOU8, str) + end + + def encode_eucjp content + NKF.nkf(U8TOEUC, content) + end + end + + register("EUC-JP") do |obj| + class << obj + alias decode decode_eucjp + alias encode encode_eucjp + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ICONV.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ICONV.rb new file mode 100644 index 00000000..172fba7c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ICONV.rb @@ -0,0 +1,22 @@ +require "iconv" +raise LoadError unless defined? Iconv + +module REXML + module Encoding + def decode_iconv(str) + Iconv.conv(UTF_8, @encoding, str) + end + + def encode_iconv(content) + Iconv.conv(@encoding, UTF_8, content) + end + + register("ICONV") do |obj| + Iconv.conv(UTF_8, obj.encoding, nil) + class << obj + alias decode decode_iconv + alias encode encode_iconv + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ISO-8859-1.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ISO-8859-1.rb new file mode 100644 index 00000000..2873d13b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ISO-8859-1.rb @@ -0,0 +1,7 @@ +require 'rexml/encodings/US-ASCII' + +module REXML + module Encoding + register("ISO-8859-1", &encoding_method("US-ASCII")) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ISO-8859-15.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ISO-8859-15.rb new file mode 100644 index 00000000..8dea0d38 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/ISO-8859-15.rb @@ -0,0 +1,72 @@ +# +# This class was contributed by Mikko Tiihonen mikko DOT tiihonen AT hut DOT fi +# +module REXML + module Encoding + register("ISO-8859-15") do |o| + alias encode to_iso_8859_15 + alias decode from_iso_8859_15 + end + + # Convert from UTF-8 + def to_iso_8859_15(content) + array_utf8 = content.unpack('U*') + array_enc = [] + array_utf8.each do |num| + case num + # shortcut first bunch basic characters + when 0..0xA3; array_enc << num + # characters removed compared to iso-8859-1 + when 0xA4; array_enc << '¤' + when 0xA6; array_enc << '¦' + when 0xA8; array_enc << '¨' + when 0xB4; array_enc << '´' + when 0xB8; array_enc << '¸' + when 0xBC; array_enc << '¼' + when 0xBD; array_enc << '½' + when 0xBE; array_enc << '¾' + # characters added compared to iso-8859-1 + when 0x20AC; array_enc << 0xA4 # 0xe2 0x82 0xac + when 0x0160; array_enc << 0xA6 # 0xc5 0xa0 + when 0x0161; array_enc << 0xA8 # 0xc5 0xa1 + when 0x017D; array_enc << 0xB4 # 0xc5 0xbd + when 0x017E; array_enc << 0xB8 # 0xc5 0xbe + when 0x0152; array_enc << 0xBC # 0xc5 0x92 + when 0x0153; array_enc << 0xBD # 0xc5 0x93 + when 0x0178; array_enc << 0xBE # 0xc5 0xb8 + else + # all remaining basic characters can be used directly + if num <= 0xFF + array_enc << num + else + # Numeric entity (&#nnnn;); shard by Stefan Scholl + array_enc.concat "&\##{num};".unpack('C*') + end + end + end + array_enc.pack('C*') + end + + # Convert to UTF-8 + def from_iso_8859_15(str) + array_latin9 = str.unpack('C*') + array_enc = [] + array_latin9.each do |num| + case num + # characters that differ compared to iso-8859-1 + when 0xA4; array_enc << 0x20AC + when 0xA6; array_enc << 0x0160 + when 0xA8; array_enc << 0x0161 + when 0xB4; array_enc << 0x017D + when 0xB8; array_enc << 0x017E + when 0xBC; array_enc << 0x0152 + when 0xBD; array_enc << 0x0153 + when 0xBE; array_enc << 0x0178 + else + array_enc << num + end + end + array_enc.pack('U*') + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/SHIFT-JIS.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/SHIFT-JIS.rb new file mode 100644 index 00000000..9e0f4af2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/SHIFT-JIS.rb @@ -0,0 +1,37 @@ +module REXML + module Encoding + begin + require 'uconv' + + def decode_sjis content + Uconv::sjistou8(content) + end + + def encode_sjis(str) + Uconv::u8tosjis(str) + end + rescue LoadError + require 'nkf' + + SJISTOU8 = '-Swm0x' + U8TOSJIS = '-Wsm0x' + + def decode_sjis(str) + NKF.nkf(SJISTOU8, str) + end + + def encode_sjis content + NKF.nkf(U8TOSJIS, content) + end + end + + b = proc do |obj| + class << obj + alias decode decode_sjis + alias encode encode_sjis + end + end + register("SHIFT-JIS", &b) + register("SHIFT_JIS", &b) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/SHIFT_JIS.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/SHIFT_JIS.rb new file mode 100644 index 00000000..e355704a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/SHIFT_JIS.rb @@ -0,0 +1 @@ +require 'rexml/encodings/SHIFT-JIS' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UNILE.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UNILE.rb new file mode 100644 index 00000000..d054140c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UNILE.rb @@ -0,0 +1,34 @@ +module REXML + module Encoding + def encode_unile content + array_utf8 = content.unpack("U*") + array_enc = [] + array_utf8.each do |num| + if ((num>>16) > 0) + array_enc << ?? + array_enc << 0 + else + array_enc << (num & 0xFF) + array_enc << (num >> 8) + end + end + array_enc.pack('C*') + end + + def decode_unile(str) + array_enc=str.unpack('C*') + array_utf8 = [] + 0.step(array_enc.size-1, 2){|i| + array_utf8 << (array_enc.at(i) + array_enc.at(i+1)*0x100) + } + array_utf8.pack('U*') + end + + register(UNILE) do |obj| + class << obj + alias decode decode_unile + alias encode encode_unile + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/US-ASCII.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/US-ASCII.rb new file mode 100644 index 00000000..fb4c2170 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/US-ASCII.rb @@ -0,0 +1,30 @@ +module REXML + module Encoding + # Convert from UTF-8 + def encode_ascii content + array_utf8 = content.unpack('U*') + array_enc = [] + array_utf8.each do |num| + if num <= 0x7F + array_enc << num + else + # Numeric entity (&#nnnn;); shard by Stefan Scholl + array_enc.concat "&\##{num};".unpack('C*') + end + end + array_enc.pack('C*') + end + + # Convert to UTF-8 + def decode_ascii(str) + str.unpack('C*').pack('U*') + end + + register("US-ASCII") do |obj| + class << obj + alias decode decode_ascii + alias encode encode_ascii + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UTF-16.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UTF-16.rb new file mode 100644 index 00000000..007c493d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UTF-16.rb @@ -0,0 +1,35 @@ +module REXML + module Encoding + def encode_utf16 content + array_utf8 = content.unpack("U*") + array_enc = [] + array_utf8.each do |num| + if ((num>>16) > 0) + array_enc << 0 + array_enc << ?? + else + array_enc << (num >> 8) + array_enc << (num & 0xFF) + end + end + array_enc.pack('C*') + end + + def decode_utf16(str) + str = str[2..-1] if /^\376\377/n =~ str + array_enc=str.unpack('C*') + array_utf8 = [] + 0.step(array_enc.size-1, 2){|i| + array_utf8 << (array_enc.at(i+1) + array_enc.at(i)*0x100) + } + array_utf8.pack('U*') + end + + register(UTF_16) do |obj| + class << obj + alias decode decode_utf16 + alias encode encode_utf16 + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UTF-8.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UTF-8.rb new file mode 100644 index 00000000..bb08f441 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/encodings/UTF-8.rb @@ -0,0 +1,18 @@ +module REXML + module Encoding + def encode_utf8 content + content + end + + def decode_utf8(str) + str + end + + register(UTF_8) do |obj| + class << obj + alias decode decode_utf8 + alias encode encode_utf8 + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/entity.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/entity.rb new file mode 100644 index 00000000..4f47e65d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/entity.rb @@ -0,0 +1,165 @@ +require 'rexml/child' +require 'rexml/source' +require 'rexml/xmltokens' + +module REXML + # God, I hate DTDs. I really do. Why this ##### standard still + # plagues us is beyond me. + class Entity < Child + include XMLTokens + PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#" + SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))} + PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')} + EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))" + NDATADECL = "\\s+NDATA\\s+#{NAME}" + PEREFERENCE = "%#{NAME};" + ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))} + PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})" + ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))" + PEDECL = "" + GEDECL = "" + ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um + + attr_reader :name, :external, :ref, :ndata, :pubid + + # Create a new entity. Simple entities can be constructed by passing a + # name, value to the constructor; this creates a generic, plain entity + # reference. For anything more complicated, you have to pass a Source to + # the constructor with the entity definiton, or use the accessor methods. + # +WARNING+: There is no validation of entity state except when the entity + # is read from a stream. If you start poking around with the accessors, + # you can easily create a non-conformant Entity. The best thing to do is + # dump the stupid DTDs and use XMLSchema instead. + # + # e = Entity.new( 'amp', '&' ) + def initialize stream, value=nil, parent=nil, reference=false + super(parent) + @ndata = @pubid = @value = @external = nil + if stream.kind_of? Array + @name = stream[1] + if stream[-1] == '%' + @reference = true + stream.pop + else + @reference = false + end + if stream[2] =~ /SYSTEM|PUBLIC/ + @external = stream[2] + if @external == 'SYSTEM' + @ref = stream[3] + @ndata = stream[4] if stream.size == 5 + else + @pubid = stream[3] + @ref = stream[4] + end + else + @value = stream[2] + end + else + @reference = reference + @external = nil + @name = stream + @value = value + end + end + + # Evaluates whether the given string matchs an entity definition, + # returning true if so, and false otherwise. + def Entity::matches? string + (ENTITYDECL =~ string) == 0 + end + + # Evaluates to the unnormalized value of this entity; that is, replacing + # all entities -- both %ent; and &ent; entities. This differs from + # +value()+ in that +value+ only replaces %ent; entities. + def unnormalized + v = value() + return nil if v.nil? + @unnormalized = Text::unnormalize(v, parent) + @unnormalized + end + + #once :unnormalized + + # Returns the value of this entity unprocessed -- raw. This is the + # normalized value; that is, with all %ent; and &ent; entities intact + def normalized + @value + end + + # Write out a fully formed, correct entity definition (assuming the Entity + # object itself is valid.) + # + # out:: + # An object implementing << to which the entity will be + # output + # indent:: + # *DEPRECATED* and ignored + def write out, indent=-1 + out << '' + end + + # Returns this entity as a string. See write(). + def to_s + rv = '' + write rv + rv + end + + PEREFERENCE_RE = /#{PEREFERENCE}/um + # Returns the value of this entity. At the moment, only internal entities + # are processed. If the value contains internal references (IE, + # %blah;), those are replaced with their values. IE, if the doctype + # contains: + # + # + # then: + # doctype.entity('yada').value #-> "nanoo bar nanoo" + def value + if @value + matches = @value.scan(PEREFERENCE_RE) + rv = @value.clone + if @parent + matches.each do |entity_reference| + entity_value = @parent.entity( entity_reference[0] ) + rv.gsub!( /%#{entity_reference};/um, entity_value ) + end + end + return rv + end + nil + end + end + + # This is a set of entity constants -- the ones defined in the XML + # specification. These are +gt+, +lt+, +amp+, +quot+ and +apos+. + module EntityConst + # +>+ + GT = Entity.new( 'gt', '>' ) + # +<+ + LT = Entity.new( 'lt', '<' ) + # +&+ + AMP = Entity.new( 'amp', '&' ) + # +"+ + QUOT = Entity.new( 'quot', '"' ) + # +'+ + APOS = Entity.new( 'apos', "'" ) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/default.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/default.rb new file mode 100644 index 00000000..77381bdf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/default.rb @@ -0,0 +1,109 @@ +module REXML + module Formatters + class Default + # Prints out the XML document with no formatting -- except if id_hack is + # set. + # + # ie_hack:: + # If set to true, then inserts whitespace before the close of an empty + # tag, so that IE's bad XML parser doesn't choke. + def initialize( ie_hack=false ) + @ie_hack = ie_hack + end + + # Writes the node to some output. + # + # node:: + # The node to write + # output:: + # A class implementing <<. Pass in an Output object to + # change the output encoding. + def write( node, output ) + case node + + when Document + if node.xml_decl.encoding != "UTF-8" && !output.kind_of?(Output) + output = Output.new( output, node.xml_decl.encoding ) + end + write_document( node, output ) + + when Element + write_element( node, output ) + + when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity, + Attribute, AttlistDecl + node.write( output,-1 ) + + when Instruction + write_instruction( node, output ) + + when DocType, XMLDecl + node.write( output ) + + when Comment + write_comment( node, output ) + + when CData + write_cdata( node, output ) + + when Text + write_text( node, output ) + + else + raise Exception.new("XML FORMATTING ERROR") + + end + end + + protected + def write_document( node, output ) + node.children.each { |child| write( child, output ) } + end + + def write_element( node, output ) + output << "<#{node.expanded_name}" + + node.attributes.each_attribute do |attr| + output << " " + attr.write( output ) + end unless node.attributes.empty? + + if node.children.empty? + output << " " if @ie_hack + output << "/" + else + output << ">" + node.children.each { |child| + write( child, output ) + } + output << "" + end + + def write_text( node, output ) + output << node.to_s() + end + + def write_comment( node, output ) + output << Comment::START + output << node.to_s + output << Comment::STOP + end + + def write_cdata( node, output ) + output << CData::START + output << node.to_s + output << CData::STOP + end + + def write_instruction( node, output ) + output << Instruction::START.sub(/\\/u, '') + output << node.target + output << ' ' + output << node.content + output << Instruction::STOP.sub(/\\/u, '') + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/pretty.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/pretty.rb new file mode 100644 index 00000000..22b6d857 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/pretty.rb @@ -0,0 +1,137 @@ +require 'rexml/formatters/default' + +module REXML + module Formatters + # Pretty-prints an XML document. This destroys whitespace in text nodes + # and will insert carriage returns and indentations. + # + # TODO: Add an option to print attributes on new lines + class Pretty < Default + + # If compact is set to true, then the formatter will attempt to use as + # little space as possible + attr_accessor :compact + # The width of a page. Used for formatting text + attr_accessor :width + + # Create a new pretty printer. + # + # output:: + # An object implementing '<<(String)', to which the output will be written. + # indentation:: + # An integer greater than 0. The indentation of each level will be + # this number of spaces. If this is < 1, the behavior of this object + # is undefined. Defaults to 2. + # ie_hack:: + # If true, the printer will insert whitespace before closing empty + # tags, thereby allowing Internet Explorer's feeble XML parser to + # function. Defaults to false. + def initialize( indentation=2, ie_hack=false ) + @indentation = indentation + @level = 0 + @ie_hack = ie_hack + @width = 80 + end + + protected + def write_element(node, output) + output << ' '*@level + output << "<#{node.expanded_name}" + + node.attributes.each_attribute do |attr| + output << " " + attr.write( output ) + end unless node.attributes.empty? + + if node.children.empty? + if @ie_hack + output << " " + end + output << "/" + else + output << ">" + # If compact and all children are text, and if the formatted output + # is less than the specified width, then try to print everything on + # one line + skip = false + if compact + if node.children.inject(true) {|s,c| s & c.kind_of?(Text)} + string = "" + old_level = @level + @level = 0 + node.children.each { |child| write( child, string ) } + @level = old_level + if string.length < @width + output << string + skip = true + end + end + end + unless skip + output << "\n" + @level += @indentation + node.children.each { |child| + next if child.kind_of?(Text) and child.to_s.strip.length == 0 + write( child, output ) + output << "\n" + } + @level -= @indentation + output << ' '*@level + end + output << "" + end + + def write_text( node, output ) + s = node.to_s() + s.gsub!(/\s/,' ') + s.squeeze!(" ") + s = wrap(s, 80-@level) + s = indent_text(s, @level, " ", true) + output << (' '*@level + s) + end + + def write_comment( node, output) + output << ' ' * @level + super + end + + def write_cdata( node, output) + output << ' ' * @level + super + end + + def write_document( node, output ) + # Ok, this is a bit odd. All XML documents have an XML declaration, + # but it may not write itself if the user didn't specifically add it, + # either through the API or in the input document. If it doesn't write + # itself, then we don't need a carriage return... which makes this + # logic more complex. + node.children.each { |child| + next if child == node.children[-1] and child.instance_of?(Text) + unless child == node.children[0] or child.instance_of?(Text) or + (child == node.children[1] and !node.children[0].writethis) + output << "\n" + end + write( child, output ) + } + end + + private + def indent_text(string, level=1, style="\t", indentfirstline=true) + return string if level < 0 + string.gsub(/\n/, "\n#{style*level}") + end + + def wrap(string, width) + # Recursivly wrap string at width. + return string if string.length <= width + place = string.rindex(' ', width) # Position in string with last ' ' before cutoff + return string[0,place] + "\n" + wrap(string[place+1..-1], width) + end + + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/transitive.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/transitive.rb new file mode 100644 index 00000000..1d80f21f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/formatters/transitive.rb @@ -0,0 +1,56 @@ +require 'rexml/formatters/pretty' + +module REXML + module Formatters + # The Transitive formatter writes an XML document that parses to an + # identical document as the source document. This means that no extra + # whitespace nodes are inserted, and whitespace within text nodes is + # preserved. Within these constraints, the document is pretty-printed, + # with whitespace inserted into the metadata to introduce formatting. + # + # Note that this is only useful if the original XML is not already + # formatted. Since this formatter does not alter whitespace nodes, the + # results of formatting already formatted XML will be odd. + class Transitive < Default + def initialize( indentation=2 ) + @indentation = indentation + @level = 0 + end + + protected + def write_element( node, output ) + output << "<#{node.expanded_name}" + + node.attributes.each_attribute do |attr| + output << " " + attr.write( output ) + end unless node.attributes.empty? + + output << "\n" + output << ' '*@level + if node.children.empty? + output << "/" + else + output << ">" + # If compact and all children are text, and if the formatted output + # is less than the specified width, then try to print everything on + # one line + skip = false + @level += @indentation + node.children.each { |child| + write( child, output ) + } + @level -= @indentation + output << "" + end + + def write_text( node, output ) + output << node.to_s() + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/functions.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/functions.rb new file mode 100644 index 00000000..8293e9c5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/functions.rb @@ -0,0 +1,382 @@ +module REXML + # If you add a method, keep in mind two things: + # (1) the first argument will always be a list of nodes from which to + # filter. In the case of context methods (such as position), the function + # should return an array with a value for each child in the array. + # (2) all method calls from XML will have "-" replaced with "_". + # Therefore, in XML, "local-name()" is identical (and actually becomes) + # "local_name()" + module Functions + @@context = nil + @@namespace_context = {} + @@variables = {} + + def Functions::namespace_context=(x) ; @@namespace_context=x ; end + def Functions::variables=(x) ; @@variables=x ; end + def Functions::namespace_context ; @@namespace_context ; end + def Functions::variables ; @@variables ; end + + def Functions::context=(value); @@context = value; end + + def Functions::text( ) + if @@context[:node].node_type == :element + return @@context[:node].find_all{|n| n.node_type == :text}.collect{|n| n.value} + elsif @@context[:node].node_type == :text + return @@context[:node].value + else + return false + end + end + + def Functions::last( ) + @@context[:size] + end + + def Functions::position( ) + @@context[:index] + end + + def Functions::count( node_set ) + node_set.size + end + + # Since REXML is non-validating, this method is not implemented as it + # requires a DTD + def Functions::id( object ) + end + + # UNTESTED + def Functions::local_name( node_set=nil ) + get_namespace( node_set ) do |node| + return node.local_name + end + end + + def Functions::namespace_uri( node_set=nil ) + get_namespace( node_set ) {|node| node.namespace} + end + + def Functions::name( node_set=nil ) + get_namespace( node_set ) do |node| + node.expanded_name + end + end + + # Helper method. + def Functions::get_namespace( node_set = nil ) + if node_set == nil + yield @@context[:node] if defined? @@context[:node].namespace + else + if node_set.respond_to? :each + node_set.each { |node| yield node if defined? node.namespace } + elsif node_set.respond_to? :namespace + yield node_set + end + end + end + + # A node-set is converted to a string by returning the string-value of the + # node in the node-set that is first in document order. If the node-set is + # empty, an empty string is returned. + # + # A number is converted to a string as follows + # + # NaN is converted to the string NaN + # + # positive zero is converted to the string 0 + # + # negative zero is converted to the string 0 + # + # positive infinity is converted to the string Infinity + # + # negative infinity is converted to the string -Infinity + # + # if the number is an integer, the number is represented in decimal form + # as a Number with no decimal point and no leading zeros, preceded by a + # minus sign (-) if the number is negative + # + # otherwise, the number is represented in decimal form as a Number + # including a decimal point with at least one digit before the decimal + # point and at least one digit after the decimal point, preceded by a + # minus sign (-) if the number is negative; there must be no leading zeros + # before the decimal point apart possibly from the one required digit + # immediately before the decimal point; beyond the one required digit + # after the decimal point there must be as many, but only as many, more + # digits as are needed to uniquely distinguish the number from all other + # IEEE 754 numeric values. + # + # The boolean false value is converted to the string false. The boolean + # true value is converted to the string true. + # + # An object of a type other than the four basic types is converted to a + # string in a way that is dependent on that type. + def Functions::string( object=nil ) + #object = @context unless object + if object.instance_of? Array + string( object[0] ) + elsif defined? object.node_type + if object.node_type == :attribute + object.value + elsif object.node_type == :element || object.node_type == :document + string_value(object) + else + object.to_s + end + elsif object.nil? + return "" + else + object.to_s + end + end + + def Functions::string_value( o ) + rv = "" + o.children.each { |e| + if e.node_type == :text + rv << e.to_s + elsif e.node_type == :element + rv << string_value( e ) + end + } + rv + end + + # UNTESTED + def Functions::concat( *objects ) + objects.join + end + + # Fixed by Mike Stok + def Functions::starts_with( string, test ) + string(string).index(string(test)) == 0 + end + + # Fixed by Mike Stok + def Functions::contains( string, test ) + string(string).include?(string(test)) + end + + # Kouhei fixed this + def Functions::substring_before( string, test ) + ruby_string = string(string) + ruby_index = ruby_string.index(string(test)) + if ruby_index.nil? + "" + else + ruby_string[ 0...ruby_index ] + end + end + + # Kouhei fixed this too + def Functions::substring_after( string, test ) + ruby_string = string(string) + test_string = string(test) + return $1 if ruby_string =~ /#{test}(.*)/ + "" + end + + # Take equal portions of Mike Stok and Sean Russell; mix + # vigorously, and pour into a tall, chilled glass. Serves 10,000. + def Functions::substring( string, start, length=nil ) + ruby_string = string(string) + ruby_length = if length.nil? + ruby_string.length.to_f + else + number(length) + end + ruby_start = number(start) + + # Handle the special cases + return '' if ( + ruby_length.nan? or + ruby_start.nan? or + ruby_start.infinite? + ) + + infinite_length = ruby_length.infinite? == 1 + ruby_length = ruby_string.length if infinite_length + + # Now, get the bounds. The XPath bounds are 1..length; the ruby bounds + # are 0..length. Therefore, we have to offset the bounds by one. + ruby_start = ruby_start.round - 1 + ruby_length = ruby_length.round + + if ruby_start < 0 + ruby_length += ruby_start unless infinite_length + ruby_start = 0 + end + return '' if ruby_length <= 0 + ruby_string[ruby_start,ruby_length] + end + + # UNTESTED + def Functions::string_length( string ) + string(string).length + end + + # UNTESTED + def Functions::normalize_space( string=nil ) + string = string(@@context[:node]) if string.nil? + if string.kind_of? Array + string.collect{|x| string.to_s.strip.gsub(/\s+/um, ' ') if string} + else + string.to_s.strip.gsub(/\s+/um, ' ') + end + end + + # This is entirely Mike Stok's beast + def Functions::translate( string, tr1, tr2 ) + from = string(tr1) + to = string(tr2) + + # the map is our translation table. + # + # if a character occurs more than once in the + # from string then we ignore the second & + # subsequent mappings + # + # if a charactcer maps to nil then we delete it + # in the output. This happens if the from + # string is longer than the to string + # + # there's nothing about - or ^ being special in + # http://www.w3.org/TR/xpath#function-translate + # so we don't build ranges or negated classes + + map = Hash.new + 0.upto(from.length - 1) { |pos| + from_char = from[pos] + unless map.has_key? from_char + map[from_char] = + if pos < to.length + to[pos] + else + nil + end + end + } + + string(string).unpack('U*').collect { |c| + if map.has_key? c then map[c] else c end + }.compact.pack('U*') + end + + # UNTESTED + def Functions::boolean( object=nil ) + if object.kind_of? String + if object =~ /\d+/u + return object.to_f != 0 + else + return object.size > 0 + end + elsif object.kind_of? Array + object = object.find{|x| x and true} + end + return object ? true : false + end + + # UNTESTED + def Functions::not( object ) + not boolean( object ) + end + + # UNTESTED + def Functions::true( ) + true + end + + # UNTESTED + def Functions::false( ) + false + end + + # UNTESTED + def Functions::lang( language ) + lang = false + node = @@context[:node] + attr = nil + until node.nil? + if node.node_type == :element + attr = node.attributes["xml:lang"] + unless attr.nil? + lang = compare_language(string(language), attr) + break + else + end + end + node = node.parent + end + lang + end + + def Functions::compare_language lang1, lang2 + lang2.downcase.index(lang1.downcase) == 0 + end + + # a string that consists of optional whitespace followed by an optional + # minus sign followed by a Number followed by whitespace is converted to + # the IEEE 754 number that is nearest (according to the IEEE 754 + # round-to-nearest rule) to the mathematical value represented by the + # string; any other string is converted to NaN + # + # boolean true is converted to 1; boolean false is converted to 0 + # + # a node-set is first converted to a string as if by a call to the string + # function and then converted in the same way as a string argument + # + # an object of a type other than the four basic types is converted to a + # number in a way that is dependent on that type + def Functions::number( object=nil ) + object = @@context[:node] unless object + case object + when true + Float(1) + when false + Float(0) + when Array + number(string( object )) + when Numeric + object.to_f + else + str = string( object ) + # If XPath ever gets scientific notation... + #if str =~ /^\s*-?(\d*\.?\d+|\d+\.)([Ee]\d*)?\s*$/ + if str =~ /^\s*-?(\d*\.?\d+|\d+\.)\s*$/ + str.to_f + else + (0.0 / 0.0) + end + end + end + + def Functions::sum( nodes ) + nodes = [nodes] unless nodes.kind_of? Array + nodes.inject(0) { |r,n| r += number(string(n)) } + end + + def Functions::floor( number ) + number(number).floor + end + + def Functions::ceiling( number ) + number(number).ceil + end + + def Functions::round( number ) + begin + number(number).round + rescue FloatDomainError + number(number) + end + end + + def Functions::processing_instruction( node ) + node.node_type == :processing_instruction + end + + def Functions::method_missing( id ) + puts "METHOD MISSING #{id.id2name}" + XPath.match( @@context[:node], id.id2name ) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/instruction.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/instruction.rb new file mode 100644 index 00000000..c16b894b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/instruction.rb @@ -0,0 +1,70 @@ +require "rexml/child" +require "rexml/source" + +module REXML + # Represents an XML Instruction; IE, + # TODO: Add parent arg (3rd arg) to constructor + class Instruction < Child + START = '<\?' + STOP = '\?>' + + # target is the "name" of the Instruction; IE, the "tag" in + # content is everything else. + attr_accessor :target, :content + + # Constructs a new Instruction + # @param target can be one of a number of things. If String, then + # the target of this instruction is set to this. If an Instruction, + # then the Instruction is shallowly cloned (target and content are + # copied). If a Source, then the source is scanned and parsed for + # an Instruction declaration. + # @param content Must be either a String, or a Parent. Can only + # be a Parent if the target argument is a Source. Otherwise, this + # String is set as the content of this instruction. + def initialize(target, content=nil) + if target.kind_of? String + super() + @target = target + @content = content + elsif target.kind_of? Instruction + super(content) + @target = target.target + @content = target.content + end + @content.strip! if @content + end + + def clone + Instruction.new self + end + + # == DEPRECATED + # See the rexml/formatters package + # + def write writer, indent=-1, transitive=false, ie_hack=false + Kernel.warn( "#{self.class.name}.write is deprecated" ) + indent(writer, indent) + writer << START.sub(/\\/u, '') + writer << @target + writer << ' ' + writer << @content + writer << STOP.sub(/\\/u, '') + end + + # @return true if other is an Instruction, and the content and target + # of the other matches the target and content of this object. + def ==( other ) + other.kind_of? Instruction and + other.target == @target and + other.content == @content + end + + def node_type + :processing_instruction + end + + def inspect + "" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/light/node.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/light/node.rb new file mode 100644 index 00000000..943ec5f1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/light/node.rb @@ -0,0 +1,196 @@ +require 'rexml/xmltokens' +require 'rexml/light/node' + +# [ :element, parent, name, attributes, children* ] + # a = Node.new + # a << "B" # => B + # a.b # => B + # a.b[1] # => B + # a.b[1]["x"] = "y" # => B + # a.b[0].c # => B + # a.b.c << "D" # => BD +module REXML + module Light + # Represents a tagged XML element. Elements are characterized by + # having children, attributes, and names, and can themselves be + # children. + class Node + NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u + PARENTS = [ :element, :document, :doctype ] + # Create a new element. + def initialize node=nil + @node = node + if node.kind_of? String + node = [ :text, node ] + elsif node.nil? + node = [ :document, nil, nil ] + elsif node[0] == :start_element + node[0] = :element + elsif node[0] == :start_doctype + node[0] = :doctype + elsif node[0] == :start_document + node[0] = :document + end + end + + def size + if PARENTS.include? @node[0] + @node[-1].size + else + 0 + end + end + + def each( &block ) + size.times { |x| yield( at(x+4) ) } + end + + def name + at(2) + end + + def name=( name_str, ns=nil ) + pfx = '' + pfx = "#{prefix(ns)}:" if ns + _old_put(2, "#{pfx}#{name_str}") + end + + def parent=( node ) + _old_put(1,node) + end + + def local_name + namesplit + @name + end + + def local_name=( name_str ) + _old_put( 1, "#@prefix:#{name_str}" ) + end + + def prefix( namespace=nil ) + prefix_of( self, namespace ) + end + + def namespace( prefix=prefix() ) + namespace_of( self, prefix ) + end + + def namespace=( namespace ) + @prefix = prefix( namespace ) + pfx = '' + pfx = "#@prefix:" if @prefix.size > 0 + _old_put(1, "#{pfx}#@name") + end + + def []( reference, ns=nil ) + if reference.kind_of? String + pfx = '' + pfx = "#{prefix(ns)}:" if ns + at(3)["#{pfx}#{reference}"] + elsif reference.kind_of? Range + _old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) ) + else + _old_get( 4+reference ) + end + end + + def =~( path ) + XPath.match( self, path ) + end + + # Doesn't handle namespaces yet + def []=( reference, ns, value=nil ) + if reference.kind_of? String + value = ns unless value + at( 3 )[reference] = value + elsif reference.kind_of? Range + _old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns ) + else + if value + _old_put( 4+reference, ns, value ) + else + _old_put( 4+reference, ns ) + end + end + end + + # Append a child to this element, optionally under a provided namespace. + # The namespace argument is ignored if the element argument is an Element + # object. Otherwise, the element argument is a string, the namespace (if + # provided) is the namespace the element is created in. + def << element + if node_type() == :text + at(-1) << element + else + newnode = Node.new( element ) + newnode.parent = self + self.push( newnode ) + end + at(-1) + end + + def node_type + _old_get(0) + end + + def text=( foo ) + replace = at(4).kind_of?(String)? 1 : 0 + self._old_put(4,replace, normalizefoo) + end + + def root + context = self + context = context.at(1) while context.at(1) + end + + def has_name?( name, namespace = '' ) + at(3) == name and namespace() == namespace + end + + def children + self + end + + def parent + at(1) + end + + def to_s + + end + + private + + def namesplit + return if @name.defined? + at(2) =~ NAMESPLIT + @prefix = '' || $1 + @name = $2 + end + + def namespace_of( node, prefix=nil ) + if not prefix + name = at(2) + name =~ NAMESPLIT + prefix = $1 + end + to_find = 'xmlns' + to_find = "xmlns:#{prefix}" if not prefix.nil? + ns = at(3)[ to_find ] + ns ? ns : namespace_of( @node[0], prefix ) + end + + def prefix_of( node, namespace=nil ) + if not namespace + name = node.name + name =~ NAMESPLIT + $1 + else + ns = at(3).find { |k,v| v == namespace } + ns ? ns : prefix_of( node.parent, namespace ) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/namespace.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/namespace.rb new file mode 100644 index 00000000..3e879058 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/namespace.rb @@ -0,0 +1,47 @@ +require 'rexml/xmltokens' + +module REXML + # Adds named attributes to an object. + module Namespace + # The name of the object, valid if set + attr_reader :name, :expanded_name + # The expanded name of the object, valid if name is set + attr_accessor :prefix + include XMLTokens + NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u + + # Sets the name and the expanded name + def name=( name ) + @expanded_name = name + name =~ NAMESPLIT + if $1 + @prefix = $1 + else + @prefix = "" + @namespace = "" + end + @name = $2 + end + + # Compares names optionally WITH namespaces + def has_name?( other, ns=nil ) + if ns + return (namespace() == ns and name() == other) + elsif other.include? ":" + return fully_expanded_name == other + else + return name == other + end + end + + alias :local_name :name + + # Fully expand the name, even if the prefix wasn't specified in the + # source file. + def fully_expanded_name + ns = prefix + return "#{ns}:#@name" if ns.size > 0 + return @name + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/node.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/node.rb new file mode 100644 index 00000000..97803768 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/node.rb @@ -0,0 +1,75 @@ +require "rexml/parseexception" +require "rexml/formatters/pretty" +require "rexml/formatters/default" + +module REXML + # Represents a node in the tree. Nodes are never encountered except as + # superclasses of other objects. Nodes have siblings. + module Node + # @return the next sibling (nil if unset) + def next_sibling_node + return nil if @parent.nil? + @parent[ @parent.index(self) + 1 ] + end + + # @return the previous sibling (nil if unset) + def previous_sibling_node + return nil if @parent.nil? + ind = @parent.index(self) + return nil if ind == 0 + @parent[ ind - 1 ] + end + + # indent:: + # *DEPRECATED* This parameter is now ignored. See the formatters in the + # REXML::Formatters package for changing the output style. + def to_s indent=nil + unless indent.nil? + Kernel.warn( "#{self.class.name}.to_s(indent) parameter is deprecated" ) + f = REXML::Formatters::Pretty.new( indent ) + f.write( self, rv, indent ) + else + f = REXML::Formatters::Default.new + f.write( self, rv = "" ) + end + return rv + end + + def indent to, ind + if @parent and @parent.context and not @parent.context[:indentstyle].nil? then + indentstyle = @parent.context[:indentstyle] + else + indentstyle = ' ' + end + to << indentstyle*ind unless ind<1 + end + + def parent? + false; + end + + + # Visit all subnodes of +self+ recursively + def each_recursive(&block) # :yields: node + self.elements.each {|node| + block.call(node) + node.each_recursive(&block) + } + end + + # Find (and return) first subnode (recursively) for which the block + # evaluates to true. Returns +nil+ if none was found. + def find_first_recursive(&block) # :yields: node + each_recursive {|node| + return node if block.call(node) + } + return nil + end + + # Returns the position that +self+ holds in its parent's array, indexed + # from 1. + def index_in_parent + parent.index(self)+1 + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/output.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/output.rb new file mode 100644 index 00000000..be4d23d4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/output.rb @@ -0,0 +1,24 @@ +require 'rexml/encoding' + +module REXML + class Output + include Encoding + + attr_reader :encoding + + def initialize real_IO, encd="iso-8859-1" + @output = real_IO + self.encoding = encd + + @to_utf = encd == UTF_8 ? false : true + end + + def <<( content ) + @output << (@to_utf ? self.encode(content) : content) + end + + def to_s + "Output[#{encoding}]" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parent.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parent.rb new file mode 100644 index 00000000..a20aaaef --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parent.rb @@ -0,0 +1,166 @@ +require "rexml/child" + +module REXML + # A parent has children, and has methods for accessing them. The Parent + # class is never encountered except as the superclass for some other + # object. + class Parent < Child + include Enumerable + + # Constructor + # @param parent if supplied, will be set as the parent of this object + def initialize parent=nil + super(parent) + @children = [] + end + + def add( object ) + #puts "PARENT GOTS #{size} CHILDREN" + object.parent = self + @children << object + #puts "PARENT NOW GOTS #{size} CHILDREN" + object + end + + alias :push :add + alias :<< :push + + def unshift( object ) + object.parent = self + @children.unshift object + end + + def delete( object ) + found = false + @children.delete_if {|c| c.equal?(object) and found = true } + object.parent = nil if found + end + + def each(&block) + @children.each(&block) + end + + def delete_if( &block ) + @children.delete_if(&block) + end + + def delete_at( index ) + @children.delete_at index + end + + def each_index( &block ) + @children.each_index(&block) + end + + # Fetches a child at a given index + # @param index the Integer index of the child to fetch + def []( index ) + @children[index] + end + + alias :each_child :each + + + + # Set an index entry. See Array.[]= + # @param index the index of the element to set + # @param opt either the object to set, or an Integer length + # @param child if opt is an Integer, this is the child to set + # @return the parent (self) + def []=( *args ) + args[-1].parent = self + @children[*args[0..-2]] = args[-1] + end + + # Inserts an child before another child + # @param child1 this is either an xpath or an Element. If an Element, + # child2 will be inserted before child1 in the child list of the parent. + # If an xpath, child2 will be inserted before the first child to match + # the xpath. + # @param child2 the child to insert + # @return the parent (self) + def insert_before( child1, child2 ) + if child1.kind_of? String + child1 = XPath.first( self, child1 ) + child1.parent.insert_before child1, child2 + else + ind = index(child1) + child2.parent.delete(child2) if child2.parent + @children[ind,0] = child2 + child2.parent = self + end + self + end + + # Inserts an child after another child + # @param child1 this is either an xpath or an Element. If an Element, + # child2 will be inserted after child1 in the child list of the parent. + # If an xpath, child2 will be inserted after the first child to match + # the xpath. + # @param child2 the child to insert + # @return the parent (self) + def insert_after( child1, child2 ) + if child1.kind_of? String + child1 = XPath.first( self, child1 ) + child1.parent.insert_after child1, child2 + else + ind = index(child1)+1 + child2.parent.delete(child2) if child2.parent + @children[ind,0] = child2 + child2.parent = self + end + self + end + + def to_a + @children.dup + end + + # Fetches the index of a given child + # @param child the child to get the index of + # @return the index of the child, or nil if the object is not a child + # of this parent. + def index( child ) + count = -1 + @children.find { |i| count += 1 ; i.hash == child.hash } + count + end + + # @return the number of children of this parent + def size + @children.size + end + + alias :length :size + + # Replaces one child with another, making sure the nodelist is correct + # @param to_replace the child to replace (must be a Child) + # @param replacement the child to insert into the nodelist (must be a + # Child) + def replace_child( to_replace, replacement ) + @children.map! {|c| c.equal?( to_replace ) ? replacement : c } + to_replace.parent = nil + replacement.parent = self + end + + # Deeply clones this object. This creates a complete duplicate of this + # Parent, including all descendants. + def deep_clone + cl = clone() + each do |child| + if child.kind_of? Parent + cl << child.deep_clone + else + cl << child.clone + end + end + cl + end + + alias :children :to_a + + def parent? + true + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parseexception.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parseexception.rb new file mode 100644 index 00000000..feb7a7e6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parseexception.rb @@ -0,0 +1,51 @@ +module REXML + class ParseException < RuntimeError + attr_accessor :source, :parser, :continued_exception + + def initialize( message, source=nil, parser=nil, exception=nil ) + super(message) + @source = source + @parser = parser + @continued_exception = exception + end + + def to_s + # Quote the original exception, if there was one + if @continued_exception + err = @continued_exception.inspect + err << "\n" + err << @continued_exception.backtrace.join("\n") + err << "\n...\n" + else + err = "" + end + + # Get the stack trace and error message + err << super + + # Add contextual information + if @source + err << "\nLine: #{line}\n" + err << "Position: #{position}\n" + err << "Last 80 unconsumed characters:\n" + err << @source.buffer[0..80].gsub(/\n/, ' ') + end + + err + end + + def position + @source.current_line[0] if @source and defined? @source.current_line and + @source.current_line + end + + def line + @source.current_line[2] if @source and defined? @source.current_line and + @source.current_line + end + + def context + @source.current_line + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/baseparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/baseparser.rb new file mode 100644 index 00000000..fc2354a6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/baseparser.rb @@ -0,0 +1,503 @@ +require 'rexml/parseexception' +require 'rexml/undefinednamespaceexception' +require 'rexml/source' +require 'set' + +module REXML + module Parsers + # = Using the Pull Parser + # This API is experimental, and subject to change. + # parser = PullParser.new( "texttxet" ) + # while parser.has_next? + # res = parser.next + # puts res[1]['att'] if res.start_tag? and res[0] == 'b' + # end + # See the PullEvent class for information on the content of the results. + # The data is identical to the arguments passed for the various events to + # the StreamListener API. + # + # Notice that: + # parser = PullParser.new( "BAD DOCUMENT" ) + # while parser.has_next? + # res = parser.next + # raise res[1] if res.error? + # end + # + # Nat Price gave me some good ideas for the API. + class BaseParser + NCNAME_STR= '[\w:][\-\w\d.]*' + NAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})" + UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}" + + NAMECHAR = '[\-\w\d\.:]' + NAME = "([\\w:]#{NAMECHAR}*)" + NMTOKEN = "(?:#{NAMECHAR})+" + NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*" + REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)" + REFERENCE_RE = /#{REFERENCE}/ + + DOCTYPE_START = /\A\s*)/um + ATTRIBUTE_PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\4/um + COMMENT_START = /\A/um + CDATA_START = /\A/um + CDATA_PATTERN = //um + XMLDECL_START = /\A<\?xml\s/u; + XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>/um + INSTRUCTION_START = /\A<\?/u + INSTRUCTION_PATTERN = /<\?(.*?)(\s+.*?)?\?>/um + TAG_MATCH = /^<((?>#{NAME_STR}))\s*((?>\s+#{UNAME_STR}\s*=\s*(["']).*?\5)*)\s*(\/)?>/um + CLOSE_MATCH = /^\s*<\/(#{NAME_STR})\s*>/um + + VERSION = /\bversion\s*=\s*["'](.*?)['"]/um + ENCODING = /\bencoding\s*=\s*["'](.*?)['"]/um + STANDALONE = /\bstandalone\s*=\s["'](.*?)['"]/um + + ENTITY_START = /^\s*/um + SYSTEMENTITY = /^\s*(%.*?;)\s*$/um + ENUMERATION = "\\(\\s*#{NMTOKEN}(?:\\s*\\|\\s*#{NMTOKEN})*\\s*\\)" + NOTATIONTYPE = "NOTATION\\s+\\(\\s*#{NAME}(?:\\s*\\|\\s*#{NAME})*\\s*\\)" + ENUMERATEDTYPE = "(?:(?:#{NOTATIONTYPE})|(?:#{ENUMERATION}))" + ATTTYPE = "(CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|#{ENUMERATEDTYPE})" + ATTVALUE = "(?:\"((?:[^<&\"]|#{REFERENCE})*)\")|(?:'((?:[^<&']|#{REFERENCE})*)')" + DEFAULTDECL = "(#REQUIRED|#IMPLIED|(?:(#FIXED\\s+)?#{ATTVALUE}))" + ATTDEF = "\\s+#{NAME}\\s+#{ATTTYPE}\\s+#{DEFAULTDECL}" + ATTDEF_RE = /#{ATTDEF}/ + ATTLISTDECL_START = /^\s*/um + NOTATIONDECL_START = /^\s*/um + SYSTEM = /^\s*/um + + TEXT_PATTERN = /\A([^<]*)/um + + # Entity constants + PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#" + SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))} + PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')} + EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))" + NDATADECL = "\\s+NDATA\\s+#{NAME}" + PEREFERENCE = "%#{NAME};" + ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))} + PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})" + ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))" + PEDECL = "" + GEDECL = "" + ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um + + EREFERENCE = /&(?!#{NAME};)/ + + DEFAULT_ENTITIES = { + 'gt' => [/>/, '>', '>', />/], + 'lt' => [/</, '<', '<', / [/"/, '"', '"', /"/], + "apos" => [/'/, "'", "'", /'/] + } + + + ###################################################################### + # These are patterns to identify common markup errors, to make the + # error messages more informative. + ###################################################################### + MISSING_ATTRIBUTE_QUOTES = /^<#{NAME_STR}\s+#{NAME_STR}\s*=\s*[^"']/um + + def initialize( source ) + self.stream = source + end + + def add_listener( listener ) + if !defined?(@listeners) or !@listeners + @listeners = [] + instance_eval <<-EOL + alias :_old_pull :pull + def pull + event = _old_pull + @listeners.each do |listener| + listener.receive event + end + event + end + EOL + end + @listeners << listener + end + + attr_reader :source + + def stream=( source ) + @source = SourceFactory.create_from( source ) + @closed = nil + @document_status = nil + @tags = [] + @stack = [] + @entities = [] + @nsstack = [] + end + + def position + if @source.respond_to? :position + @source.position + else + # FIXME + 0 + end + end + + # Returns true if there are no more events + def empty? + return (@source.empty? and @stack.empty?) + end + + # Returns true if there are more events. Synonymous with !empty? + def has_next? + return !(@source.empty? and @stack.empty?) + end + + # Push an event back on the head of the stream. This method + # has (theoretically) infinite depth. + def unshift token + @stack.unshift(token) + end + + # Peek at the +depth+ event in the stack. The first element on the stack + # is at depth 0. If +depth+ is -1, will parse to the end of the input + # stream and return the last event, which is always :end_document. + # Be aware that this causes the stream to be parsed up to the +depth+ + # event, so you can effectively pre-parse the entire document (pull the + # entire thing into memory) using this method. + def peek depth=0 + raise %Q[Illegal argument "#{depth}"] if depth < -1 + temp = [] + if depth == -1 + temp.push(pull()) until empty? + else + while @stack.size+temp.size < depth+1 + temp.push(pull()) + end + end + @stack += temp if temp.size > 0 + @stack[depth] + end + + # Returns the next event. This is a +PullEvent+ object. + def pull + if @closed + x, @closed = @closed, nil + return [ :end_element, x ] + end + return [ :end_document ] if empty? + return @stack.shift if @stack.size > 0 + #STDERR.puts @source.encoding + @source.read if @source.buffer.size<2 + #STDERR.puts "BUFFER = #{@source.buffer.inspect}" + if @document_status == nil + #@source.consume( /^\s*/um ) + word = @source.match( /^((?:\s+)|(?:<[^>]*>))/um ) + word = word[1] unless word.nil? + #STDERR.puts "WORD = #{word.inspect}" + case word + when COMMENT_START + return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ] + when XMLDECL_START + #STDERR.puts "XMLDECL" + results = @source.match( XMLDECL_PATTERN, true )[1] + version = VERSION.match( results ) + version = version[1] unless version.nil? + encoding = ENCODING.match(results) + encoding = encoding[1] unless encoding.nil? + @source.encoding = encoding + standalone = STANDALONE.match(results) + standalone = standalone[1] unless standalone.nil? + return [ :xmldecl, version, encoding, standalone ] + when INSTRUCTION_START + return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ] + when DOCTYPE_START + md = @source.match( DOCTYPE_PATTERN, true ) + @nsstack.unshift(curr_ns=Set.new) + identity = md[1] + close = md[2] + identity =~ IDENTITY + name = $1 + raise REXML::ParseException.new("DOCTYPE is missing a name") if name.nil? + pub_sys = $2.nil? ? nil : $2.strip + long_name = $4.nil? ? nil : $4.strip + uri = $6.nil? ? nil : $6.strip + args = [ :start_doctype, name, pub_sys, long_name, uri ] + if close == ">" + @document_status = :after_doctype + @source.read if @source.buffer.size<2 + md = @source.match(/^\s*/um, true) + @stack << [ :end_doctype ] + else + @document_status = :in_doctype + end + return args + when /^\s+/ + else + @document_status = :after_doctype + @source.read if @source.buffer.size<2 + md = @source.match(/\s*/um, true) + end + end + if @document_status == :in_doctype + md = @source.match(/\s*(.*?>)/um) + case md[1] + when SYSTEMENTITY + match = @source.match( SYSTEMENTITY, true )[1] + return [ :externalentity, match ] + + when ELEMENTDECL_START + return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ] + + when ENTITY_START + match = @source.match( ENTITYDECL, true ).to_a.compact + match[0] = :entitydecl + ref = false + if match[1] == '%' + ref = true + match.delete_at 1 + end + # Now we have to sort out what kind of entity reference this is + if match[2] == 'SYSTEM' + # External reference + match[3] = match[3][1..-2] # PUBID + match.delete_at(4) if match.size > 4 # Chop out NDATA decl + # match is [ :entity, name, SYSTEM, pubid(, ndata)? ] + elsif match[2] == 'PUBLIC' + # External reference + match[3] = match[3][1..-2] # PUBID + match[4] = match[4][1..-2] # HREF + # match is [ :entity, name, PUBLIC, pubid, href ] + else + match[2] = match[2][1..-2] + match.pop if match.size == 4 + # match is [ :entity, name, value ] + end + match << '%' if ref + return match + when ATTLISTDECL_START + md = @source.match( ATTLISTDECL_PATTERN, true ) + raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil? + element = md[1] + contents = md[0] + + pairs = {} + values = md[0].scan( ATTDEF_RE ) + values.each do |attdef| + unless attdef[3] == "#IMPLIED" + attdef.compact! + val = attdef[3] + val = attdef[4] if val == "#FIXED " + pairs[attdef[0]] = val + if attdef[0] =~ /^xmlns:(.*)/ + @nsstack[0] << $1 + end + end + end + return [ :attlistdecl, element, pairs, contents ] + when NOTATIONDECL_START + md = nil + if @source.match( PUBLIC ) + md = @source.match( PUBLIC, true ) + vals = [md[1],md[2],md[4],md[6]] + elsif @source.match( SYSTEM ) + md = @source.match( SYSTEM, true ) + vals = [md[1],md[2],nil,md[4]] + else + raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source ) + end + return [ :notationdecl, *vals ] + when CDATA_END + @document_status = :after_doctype + @source.match( CDATA_END, true ) + return [ :end_doctype ] + end + end + begin + if @source.buffer[0] == ?< + if @source.buffer[1] == ?/ + @nsstack.shift + last_tag = @tags.pop + #md = @source.match_to_consume( '>', CLOSE_MATCH) + md = @source.match( CLOSE_MATCH, true ) + raise REXML::ParseException.new( "Missing end tag for "+ + "'#{last_tag}' (got \"#{md[1]}\")", + @source) unless last_tag == md[1] + return [ :end_element, last_tag ] + elsif @source.buffer[1] == ?! + md = @source.match(/\A(\s*[^>]*>)/um) + #STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}" + raise REXML::ParseException.new("Malformed node", @source) unless md + if md[0][2] == ?- + md = @source.match( COMMENT_PATTERN, true ) + return [ :comment, md[1] ] if md + else + md = @source.match( CDATA_PATTERN, true ) + return [ :cdata, md[1] ] if md + end + raise REXML::ParseException.new( "Declarations can only occur "+ + "in the doctype declaration.", @source) + elsif @source.buffer[1] == ?? + md = @source.match( INSTRUCTION_PATTERN, true ) + return [ :processing_instruction, md[1], md[2] ] if md + raise REXML::ParseException.new( "Bad instruction declaration", + @source) + else + # Get the next tag + md = @source.match(TAG_MATCH, true) + unless md + # Check for missing attribute quotes + raise REXML::ParseException.new("missing attribute quote", @source) if @source.match(MISSING_ATTRIBUTE_QUOTES ) + raise REXML::ParseException.new("malformed XML: missing tag start", @source) + end + attributes = {} + prefixes = Set.new + prefixes << md[2] if md[2] + @nsstack.unshift(curr_ns=Set.new) + if md[4].size > 0 + attrs = md[4].scan( ATTRIBUTE_PATTERN ) + raise REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0 + attrs.each { |a,b,c,d,e| + if b == "xmlns" + if c == "xml" + if d != "http://www.w3.org/XML/1998/namespace" + msg = "The 'xml' prefix must not be bound to any other namespace "+ + "(http://www.w3.org/TR/REC-xml-names/#ns-decl)" + raise REXML::ParseException.new( msg, @source, self ) + end + elsif c == "xmlns" + msg = "The 'xmlns' prefix must not be declared "+ + "(http://www.w3.org/TR/REC-xml-names/#ns-decl)" + raise REXML::ParseException.new( msg, @source, self) + end + curr_ns << c + elsif b + prefixes << b unless b == "xml" + end + attributes[a] = e + } + end + + # Verify that all of the prefixes have been defined + for prefix in prefixes + unless @nsstack.find{|k| k.member?(prefix)} + raise UndefinedNamespaceException.new(prefix,@source,self) + end + end + + if md[6] + @closed = md[1] + @nsstack.shift + else + @tags.push( md[1] ) + end + return [ :start_element, md[1], attributes ] + end + else + md = @source.match( TEXT_PATTERN, true ) + if md[0].length == 0 + @source.match( /(\s+)/, true ) + end + #STDERR.puts "GOT #{md[1].inspect}" unless md[0].length == 0 + #return [ :text, "" ] if md[0].length == 0 + # unnormalized = Text::unnormalize( md[1], self ) + # return PullEvent.new( :text, md[1], unnormalized ) + return [ :text, md[1] ] + end + rescue REXML::UndefinedNamespaceException + raise + rescue REXML::ParseException + raise + rescue Exception, NameError => error + raise REXML::ParseException.new( "Exception parsing", + @source, self, (error ? error : $!) ) + end + return [ :dummy ] + end + + def entity( reference, entities ) + value = nil + value = entities[ reference ] if entities + if not value + value = DEFAULT_ENTITIES[ reference ] + value = value[2] if value + end + unnormalize( value, entities ) if value + end + + # Escapes all possible entities + def normalize( input, entities=nil, entity_filter=nil ) + copy = input.clone + # Doing it like this rather than in a loop improves the speed + copy.gsub!( EREFERENCE, '&' ) + entities.each do |key, value| + copy.gsub!( value, "&#{key};" ) unless entity_filter and + entity_filter.include?(entity) + end if entities + copy.gsub!( EREFERENCE, '&' ) + DEFAULT_ENTITIES.each do |key, value| + copy.gsub!( value[3], value[1] ) + end + copy + end + + # Unescapes all possible entities + def unnormalize( string, entities=nil, filter=nil ) + rv = string.clone + rv.gsub!( /\r\n?/, "\n" ) + matches = rv.scan( REFERENCE_RE ) + return rv if matches.size == 0 + rv.gsub!( /�*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {|m| + m=$1 + m = "0#{m}" if m[0] == ?x + [Integer(m)].pack('U*') + } + matches.collect!{|x|x[0]}.compact! + if matches.size > 0 + matches.each do |entity_reference| + unless filter and filter.include?(entity_reference) + entity_value = entity( entity_reference, entities ) + if entity_value + re = /&#{entity_reference};/ + rv.gsub!( re, entity_value ) + end + end + end + matches.each do |entity_reference| + unless filter and filter.include?(entity_reference) + er = DEFAULT_ENTITIES[entity_reference] + rv.gsub!( er[0], er[2] ) if er + end + end + rv.gsub!( /&/, '&' ) + end + rv + end + end + end +end + +=begin + case event[0] + when :start_element + when :text + when :end_element + when :processing_instruction + when :cdata + when :comment + when :xmldecl + when :start_doctype + when :end_doctype + when :externalentity + when :elementdecl + when :entity + when :attlistdecl + when :notationdecl + when :end_doctype + end +=end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/lightparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/lightparser.rb new file mode 100644 index 00000000..0f350349 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/lightparser.rb @@ -0,0 +1,60 @@ +require 'rexml/parsers/streamparser' +require 'rexml/parsers/baseparser' +require 'rexml/light/node' + +module REXML + module Parsers + class LightParser + def initialize stream + @stream = stream + @parser = REXML::Parsers::BaseParser.new( stream ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def rewind + @stream.rewind + @parser.stream = @stream + end + + def parse + root = context = [ :document ] + while true + event = @parser.pull + case event[0] + when :end_document + break + when :end_doctype + context = context[1] + when :start_element, :start_doctype + new_node = event + context << new_node + new_node[1,0] = [context] + context = new_node + when :end_element, :end_doctype + context = context[1] + else + new_node = event + context << new_node + new_node[1,0] = [context] + end + end + root + end + end + + # An element is an array. The array contains: + # 0 The parent element + # 1 The tag name + # 2 A hash of attributes + # 3..-1 The child elements + # An element is an array of size > 3 + # Text is a String + # PIs are [ :processing_instruction, target, data ] + # Comments are [ :comment, data ] + # DocTypes are DocType structs + # The root is an array with XMLDecls, Text, DocType, Array, Text + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/pullparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/pullparser.rb new file mode 100644 index 00000000..36dc7160 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/pullparser.rb @@ -0,0 +1,196 @@ +require 'forwardable' + +require 'rexml/parseexception' +require 'rexml/parsers/baseparser' +require 'rexml/xmltokens' + +module REXML + module Parsers + # = Using the Pull Parser + # This API is experimental, and subject to change. + # parser = PullParser.new( "texttxet" ) + # while parser.has_next? + # res = parser.next + # puts res[1]['att'] if res.start_tag? and res[0] == 'b' + # end + # See the PullEvent class for information on the content of the results. + # The data is identical to the arguments passed for the various events to + # the StreamListener API. + # + # Notice that: + # parser = PullParser.new( "BAD DOCUMENT" ) + # while parser.has_next? + # res = parser.next + # raise res[1] if res.error? + # end + # + # Nat Price gave me some good ideas for the API. + class PullParser + include XMLTokens + extend Forwardable + + def_delegators( :@parser, :has_next? ) + def_delegators( :@parser, :entity ) + def_delegators( :@parser, :empty? ) + def_delegators( :@parser, :source ) + + def initialize stream + @entities = {} + @listeners = nil + @parser = BaseParser.new( stream ) + @my_stack = [] + end + + def add_listener( listener ) + @listeners = [] unless @listeners + @listeners << listener + end + + def each + while has_next? + yield self.pull + end + end + + def peek depth=0 + if @my_stack.length <= depth + (depth - @my_stack.length + 1).times { + e = PullEvent.new(@parser.pull) + @my_stack.push(e) + } + end + @my_stack[depth] + end + + def pull + return @my_stack.shift if @my_stack.length > 0 + + event = @parser.pull + case event[0] + when :entitydecl + @entities[ event[1] ] = + event[2] unless event[2] =~ /PUBLIC|SYSTEM/ + when :text + unnormalized = @parser.unnormalize( event[1], @entities ) + event << unnormalized + end + PullEvent.new( event ) + end + + def unshift token + @my_stack.unshift token + end + end + + # A parsing event. The contents of the event are accessed as an +Array?, + # and the type is given either by the ...? methods, or by accessing the + # +type+ accessor. The contents of this object vary from event to event, + # but are identical to the arguments passed to +StreamListener+s for each + # event. + class PullEvent + # The type of this event. Will be one of :tag_start, :tag_end, :text, + # :processing_instruction, :comment, :doctype, :attlistdecl, :entitydecl, + # :notationdecl, :entity, :cdata, :xmldecl, or :error. + def initialize(arg) + @contents = arg + end + + def []( start, endd=nil) + if start.kind_of? Range + @contents.slice( start.begin+1 .. start.end ) + elsif start.kind_of? Numeric + if endd.nil? + @contents.slice( start+1 ) + else + @contents.slice( start+1, endd ) + end + else + raise "Illegal argument #{start.inspect} (#{start.class})" + end + end + + def event_type + @contents[0] + end + + # Content: [ String tag_name, Hash attributes ] + def start_element? + @contents[0] == :start_element + end + + # Content: [ String tag_name ] + def end_element? + @contents[0] == :end_element + end + + # Content: [ String raw_text, String unnormalized_text ] + def text? + @contents[0] == :text + end + + # Content: [ String text ] + def instruction? + @contents[0] == :processing_instruction + end + + # Content: [ String text ] + def comment? + @contents[0] == :comment + end + + # Content: [ String name, String pub_sys, String long_name, String uri ] + def doctype? + @contents[0] == :start_doctype + end + + # Content: [ String text ] + def attlistdecl? + @contents[0] == :attlistdecl + end + + # Content: [ String text ] + def elementdecl? + @contents[0] == :elementdecl + end + + # Due to the wonders of DTDs, an entity declaration can be just about + # anything. There's no way to normalize it; you'll have to interpret the + # content yourself. However, the following is true: + # + # * If the entity declaration is an internal entity: + # [ String name, String value ] + # Content: [ String text ] + def entitydecl? + @contents[0] == :entitydecl + end + + # Content: [ String text ] + def notationdecl? + @contents[0] == :notationdecl + end + + # Content: [ String text ] + def entity? + @contents[0] == :entity + end + + # Content: [ String text ] + def cdata? + @contents[0] == :cdata + end + + # Content: [ String version, String encoding, String standalone ] + def xmldecl? + @contents[0] == :xmldecl + end + + def error? + @contents[0] == :error + end + + def inspect + @contents[0].to_s + ": " + @contents[1..-1].inspect + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/sax2parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/sax2parser.rb new file mode 100644 index 00000000..e402eb77 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/sax2parser.rb @@ -0,0 +1,238 @@ +require 'rexml/parsers/baseparser' +require 'rexml/parseexception' +require 'rexml/namespace' +require 'rexml/text' + +module REXML + module Parsers + # SAX2Parser + class SAX2Parser + def initialize source + @parser = BaseParser.new(source) + @listeners = [] + @procs = [] + @namespace_stack = [] + @has_listeners = false + @tag_stack = [] + @entities = {} + end + + def source + @parser.source + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + # Listen arguments: + # + # Symbol, Array, Block + # Listen to Symbol events on Array elements + # Symbol, Block + # Listen to Symbol events + # Array, Listener + # Listen to all events on Array elements + # Array, Block + # Listen to :start_element events on Array elements + # Listener + # Listen to All events + # + # Symbol can be one of: :start_element, :end_element, + # :start_prefix_mapping, :end_prefix_mapping, :characters, + # :processing_instruction, :doctype, :attlistdecl, :elementdecl, + # :entitydecl, :notationdecl, :cdata, :xmldecl, :comment + # + # There is an additional symbol that can be listened for: :progress. + # This will be called for every event generated, passing in the current + # stream position. + # + # Array contains regular expressions or strings which will be matched + # against fully qualified element names. + # + # Listener must implement the methods in SAX2Listener + # + # Block will be passed the same arguments as a SAX2Listener method would + # be, where the method name is the same as the matched Symbol. + # See the SAX2Listener for more information. + def listen( *args, &blok ) + if args[0].kind_of? Symbol + if args.size == 2 + args[1].each { |match| @procs << [args[0], match, blok] } + else + add( [args[0], nil, blok] ) + end + elsif args[0].kind_of? Array + if args.size == 2 + args[0].each { |match| add( [nil, match, args[1]] ) } + else + args[0].each { |match| add( [ :start_element, match, blok ] ) } + end + else + add([nil, nil, args[0]]) + end + end + + def deafen( listener=nil, &blok ) + if listener + @listeners.delete_if {|item| item[-1] == listener } + @has_listeners = false if @listeners.size == 0 + else + @procs.delete_if {|item| item[-1] == blok } + end + end + + def parse + @procs.each { |sym,match,block| block.call if sym == :start_document } + @listeners.each { |sym,match,block| + block.start_document if sym == :start_document or sym.nil? + } + root = context = [] + while true + event = @parser.pull + case event[0] + when :end_document + handle( :end_document ) + break + when :start_doctype + handle( :doctype, *event[1..-1]) + when :end_doctype + context = context[1] + when :start_element + @tag_stack.push(event[1]) + # find the observers for namespaces + procs = get_procs( :start_prefix_mapping, event[1] ) + listeners = get_listeners( :start_prefix_mapping, event[1] ) + if procs or listeners + # break out the namespace declarations + # The attributes live in event[2] + event[2].each {|n, v| event[2][n] = @parser.normalize(v)} + nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ } + nsdecl.collect! { |n, value| [ n[6..-1], value ] } + @namespace_stack.push({}) + nsdecl.each do |n,v| + @namespace_stack[-1][n] = v + # notify observers of namespaces + procs.each { |ob| ob.call( n, v ) } if procs + listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners + end + end + event[1] =~ Namespace::NAMESPLIT + prefix = $1 + local = $2 + uri = get_namespace(prefix) + # find the observers for start_element + procs = get_procs( :start_element, event[1] ) + listeners = get_listeners( :start_element, event[1] ) + # notify observers + procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs + listeners.each { |ob| + ob.start_element( uri, local, event[1], event[2] ) + } if listeners + when :end_element + @tag_stack.pop + event[1] =~ Namespace::NAMESPLIT + prefix = $1 + local = $2 + uri = get_namespace(prefix) + # find the observers for start_element + procs = get_procs( :end_element, event[1] ) + listeners = get_listeners( :end_element, event[1] ) + # notify observers + procs.each { |ob| ob.call( uri, local, event[1] ) } if procs + listeners.each { |ob| + ob.end_element( uri, local, event[1] ) + } if listeners + + namespace_mapping = @namespace_stack.pop + # find the observers for namespaces + procs = get_procs( :end_prefix_mapping, event[1] ) + listeners = get_listeners( :end_prefix_mapping, event[1] ) + if procs or listeners + namespace_mapping.each do |prefix, uri| + # notify observers of namespaces + procs.each { |ob| ob.call( prefix ) } if procs + listeners.each { |ob| ob.end_prefix_mapping(prefix) } if listeners + end + end + when :text + #normalized = @parser.normalize( event[1] ) + #handle( :characters, normalized ) + copy = event[1].clone + @entities.each { |key, value| copy = copy.gsub("&#{key};", value) } + copy.gsub!( Text::NUMERICENTITY ) {|m| + m=$1 + m = "0#{m}" if m[0] == ?x + [Integer(m)].pack('U*') + } + handle( :characters, copy ) + when :entitydecl + @entities[ event[1] ] = event[2] if event.size == 3 + handle( *event ) + when :processing_instruction, :comment, :attlistdecl, + :elementdecl, :cdata, :notationdecl, :xmldecl + handle( *event ) + end + handle( :progress, @parser.position ) + end + end + + private + def handle( symbol, *arguments ) + tag = @tag_stack[-1] + procs = get_procs( symbol, tag ) + listeners = get_listeners( symbol, tag ) + # notify observers + procs.each { |ob| ob.call( *arguments ) } if procs + listeners.each { |l| + l.send( symbol.to_s, *arguments ) + } if listeners + end + + # The following methods are duplicates, but it is faster than using + # a helper + def get_procs( symbol, name ) + return nil if @procs.size == 0 + @procs.find_all do |sym, match, block| + #puts sym.inspect+"=="+symbol.inspect+ "\t"+match.inspect+"=="+name.inspect+ "\t"+( (sym.nil? or symbol == sym) and ((name.nil? and match.nil?) or match.nil? or ( (name == match) or (match.kind_of? Regexp and name =~ match)))).to_s + ( + (sym.nil? or symbol == sym) and + ((name.nil? and match.nil?) or match.nil? or ( + (name == match) or + (match.kind_of? Regexp and name =~ match) + ) + ) + ) + end.collect{|x| x[-1]} + end + def get_listeners( symbol, name ) + return nil if @listeners.size == 0 + @listeners.find_all do |sym, match, block| + ( + (sym.nil? or symbol == sym) and + ((name.nil? and match.nil?) or match.nil? or ( + (name == match) or + (match.kind_of? Regexp and name =~ match) + ) + ) + ) + end.collect{|x| x[-1]} + end + + def add( pair ) + if pair[-1].respond_to? :call + @procs << pair unless @procs.include? pair + else + @listeners << pair unless @listeners.include? pair + @has_listeners = true + end + end + + def get_namespace( prefix ) + uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) || + (@namespace_stack.find { |ns| not ns[nil].nil? }) + uris[-1][prefix] unless uris.nil? or 0 == uris.size + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/streamparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/streamparser.rb new file mode 100644 index 00000000..256d0f61 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/streamparser.rb @@ -0,0 +1,46 @@ +module REXML + module Parsers + class StreamParser + def initialize source, listener + @listener = listener + @parser = BaseParser.new( source ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def parse + # entity string + while true + event = @parser.pull + case event[0] + when :end_document + return + when :start_element + attrs = event[2].each do |n, v| + event[2][n] = @parser.unnormalize( v ) + end + @listener.tag_start( event[1], attrs ) + when :end_element + @listener.tag_end( event[1] ) + when :text + normalized = @parser.unnormalize( event[1] ) + @listener.text( normalized ) + when :processing_instruction + @listener.instruction( *event[1,2] ) + when :start_doctype + @listener.doctype( *event[1..-1] ) + when :end_doctype + # FIXME: remove this condition for milestone:3.2 + @listener.doctype_end if @listener.respond_to? :doctype_end + when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl + @listener.send( event[0].to_s, *event[1..-1] ) + when :entitydecl, :notationdecl + @listener.send( event[0].to_s, event[1..-1] ) + end + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/treeparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/treeparser.rb new file mode 100644 index 00000000..5c3e142e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/treeparser.rb @@ -0,0 +1,97 @@ +require 'rexml/validation/validationexception' +require 'rexml/undefinednamespaceexception' + +module REXML + module Parsers + class TreeParser + def initialize( source, build_context = Document.new ) + @build_context = build_context + @parser = Parsers::BaseParser.new( source ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def parse + tag_stack = [] + in_doctype = false + entities = nil + begin + while true + event = @parser.pull + #STDERR.puts "TREEPARSER GOT #{event.inspect}" + case event[0] + when :end_document + unless tag_stack.empty? + #raise ParseException.new("No close tag for #{tag_stack.inspect}") + raise ParseException.new("No close tag for #{@build_context.xpath}") + end + return + when :start_element + tag_stack.push(event[1]) + el = @build_context = @build_context.add_element( event[1], event[2] ) + when :end_element + tag_stack.pop + @build_context = @build_context.parent + when :text + if not in_doctype + if @build_context[-1].instance_of? Text + @build_context[-1] << event[1] + else + @build_context.add( + Text.new(event[1], @build_context.whitespace, nil, true) + ) unless ( + @build_context.ignore_whitespace_nodes and + event[1].strip.size==0 + ) + end + end + when :comment + c = Comment.new( event[1] ) + @build_context.add( c ) + when :cdata + c = CData.new( event[1] ) + @build_context.add( c ) + when :processing_instruction + @build_context.add( Instruction.new( event[1], event[2] ) ) + when :end_doctype + in_doctype = false + entities.each { |k,v| entities[k] = @build_context.entities[k].value } + @build_context = @build_context.parent + when :start_doctype + doctype = DocType.new( event[1..-1], @build_context ) + @build_context = doctype + entities = {} + in_doctype = true + when :attlistdecl + n = AttlistDecl.new( event[1..-1] ) + @build_context.add( n ) + when :externalentity + n = ExternalEntity.new( event[1] ) + @build_context.add( n ) + when :elementdecl + n = ElementDecl.new( event[1] ) + @build_context.add(n) + when :entitydecl + entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/ + @build_context.add(Entity.new(event)) + when :notationdecl + n = NotationDecl.new( *event[1..-1] ) + @build_context.add( n ) + when :xmldecl + x = XMLDecl.new( event[1], event[2], event[3] ) + @build_context.add( x ) + end + end + rescue REXML::Validation::ValidationException + raise + rescue REXML::UndefinedNamespaceException + raise + rescue + raise ParseException.new( $!.message, @parser.source, @parser, $! ) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/ultralightparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/ultralightparser.rb new file mode 100644 index 00000000..adc4af18 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/ultralightparser.rb @@ -0,0 +1,56 @@ +require 'rexml/parsers/streamparser' +require 'rexml/parsers/baseparser' + +module REXML + module Parsers + class UltraLightParser + def initialize stream + @stream = stream + @parser = REXML::Parsers::BaseParser.new( stream ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def rewind + @stream.rewind + @parser.stream = @stream + end + + def parse + root = context = [] + while true + event = @parser.pull + case event[0] + when :end_document + break + when :end_doctype + context = context[1] + when :start_element, :doctype + context << event + event[1,0] = [context] + context = event + when :end_element + context = context[1] + else + context << event + end + end + root + end + end + + # An element is an array. The array contains: + # 0 The parent element + # 1 The tag name + # 2 A hash of attributes + # 3..-1 The child elements + # An element is an array of size > 3 + # Text is a String + # PIs are [ :processing_instruction, target, data ] + # Comments are [ :comment, data ] + # DocTypes are DocType structs + # The root is an array with XMLDecls, Text, DocType, Array, Text + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/xpathparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/xpathparser.rb new file mode 100644 index 00000000..de2530e3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/parsers/xpathparser.rb @@ -0,0 +1,698 @@ +require 'rexml/namespace' +require 'rexml/xmltokens' + +module REXML + module Parsers + # You don't want to use this class. Really. Use XPath, which is a wrapper + # for this class. Believe me. You don't want to poke around in here. + # There is strange, dark magic at work in this code. Beware. Go back! Go + # back while you still can! + class XPathParser + include XMLTokens + LITERAL = /^'([^']*)'|^"([^"]*)"/u + + def namespaces=( namespaces ) + Functions::namespace_context = namespaces + @namespaces = namespaces + end + + def parse path + path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces + path.gsub!( /\s+([\]\)])/, '\1' ) + parsed = [] + path = OrExpr(path, parsed) + parsed + end + + def predicate path + parsed = [] + Predicate( "[#{path}]", parsed ) + parsed + end + + def abbreviate( path ) + path = path.kind_of?(String) ? parse( path ) : path + string = "" + document = false + while path.size > 0 + op = path.shift + case op + when :node + when :attribute + string << "/" if string.size > 0 + string << "@" + when :child + string << "/" if string.size > 0 + when :descendant_or_self + string << "/" + when :self + string << "." + when :parent + string << ".." + when :any + string << "*" + when :text + string << "text()" + when :following, :following_sibling, + :ancestor, :ancestor_or_self, :descendant, + :namespace, :preceding, :preceding_sibling + string << "/" unless string.size == 0 + string << op.to_s.tr("_", "-") + string << "::" + when :qname + prefix = path.shift + name = path.shift + string << prefix+":" if prefix.size > 0 + string << name + when :predicate + string << '[' + string << predicate_to_string( path.shift ) {|x| abbreviate( x ) } + string << ']' + when :document + document = true + when :function + string << path.shift + string << "( " + string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )} + string << " )" + when :literal + string << %Q{ "#{path.shift}" } + else + string << "/" unless string.size == 0 + string << "UNKNOWN(" + string << op.inspect + string << ")" + end + end + string = "/"+string if document + return string + end + + def expand( path ) + path = path.kind_of?(String) ? parse( path ) : path + string = "" + document = false + while path.size > 0 + op = path.shift + case op + when :node + string << "node()" + when :attribute, :child, :following, :following_sibling, + :ancestor, :ancestor_or_self, :descendant, :descendant_or_self, + :namespace, :preceding, :preceding_sibling, :self, :parent + string << "/" unless string.size == 0 + string << op.to_s.tr("_", "-") + string << "::" + when :any + string << "*" + when :qname + prefix = path.shift + name = path.shift + string << prefix+":" if prefix.size > 0 + string << name + when :predicate + string << '[' + string << predicate_to_string( path.shift ) { |x| expand(x) } + string << ']' + when :document + document = true + else + string << "/" unless string.size == 0 + string << "UNKNOWN(" + string << op.inspect + string << ")" + end + end + string = "/"+string if document + return string + end + + def predicate_to_string( path, &block ) + string = "" + case path[0] + when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union + op = path.shift + case op + when :eq + op = "=" + when :lt + op = "<" + when :gt + op = ">" + when :lteq + op = "<=" + when :gteq + op = ">=" + when :neq + op = "!=" + when :union + op = "|" + end + left = predicate_to_string( path.shift, &block ) + right = predicate_to_string( path.shift, &block ) + string << " " + string << left + string << " " + string << op.to_s + string << " " + string << right + string << " " + when :function + path.shift + name = path.shift + string << name + string << "( " + string << predicate_to_string( path.shift, &block ) + string << " )" + when :literal + path.shift + string << " " + string << path.shift.inspect + string << " " + else + string << " " + string << yield( path ) + string << " " + end + return string.squeeze(" ") + end + + private + #LocationPath + # | RelativeLocationPath + # | '/' RelativeLocationPath? + # | '//' RelativeLocationPath + def LocationPath path, parsed + #puts "LocationPath '#{path}'" + path = path.strip + if path[0] == ?/ + parsed << :document + if path[1] == ?/ + parsed << :descendant_or_self + parsed << :node + path = path[2..-1] + else + path = path[1..-1] + end + end + #puts parsed.inspect + return RelativeLocationPath( path, parsed ) if path.size > 0 + end + + #RelativeLocationPath + # | Step + # | (AXIS_NAME '::' | '@' | '') AxisSpecifier + # NodeTest + # Predicate + # | '.' | '..' AbbreviatedStep + # | RelativeLocationPath '/' Step + # | RelativeLocationPath '//' Step + AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/ + def RelativeLocationPath path, parsed + #puts "RelativeLocationPath #{path}" + while path.size > 0 + # (axis or @ or ) nodetest predicate > + # OR > / Step + # (. or ..) > + if path[0] == ?. + if path[1] == ?. + parsed << :parent + parsed << :node + path = path[2..-1] + else + parsed << :self + parsed << :node + path = path[1..-1] + end + else + if path[0] == ?@ + #puts "ATTRIBUTE" + parsed << :attribute + path = path[1..-1] + # Goto Nodetest + elsif path =~ AXIS + parsed << $1.tr('-','_').intern + path = $' + # Goto Nodetest + else + parsed << :child + end + + #puts "NODETESTING '#{path}'" + n = [] + path = NodeTest( path, n) + #puts "NODETEST RETURNED '#{path}'" + + if path[0] == ?[ + path = Predicate( path, n ) + end + + parsed.concat(n) + end + + if path.size > 0 + if path[0] == ?/ + if path[1] == ?/ + parsed << :descendant_or_self + parsed << :node + path = path[2..-1] + else + path = path[1..-1] + end + else + return path + end + end + end + return path + end + + # Returns a 1-1 map of the nodeset + # The contents of the resulting array are either: + # true/false, if a positive match + # String, if a name match + #NodeTest + # | ('*' | NCNAME ':' '*' | QNAME) NameTest + # | NODE_TYPE '(' ')' NodeType + # | PI '(' LITERAL ')' PI + # | '[' expr ']' Predicate + NCNAMETEST= /^(#{NCNAME_STR}):\*/u + QNAME = Namespace::NAMESPLIT + NODE_TYPE = /^(comment|text|node)\(\s*\)/m + PI = /^processing-instruction\(/ + def NodeTest path, parsed + #puts "NodeTest with #{path}" + res = nil + case path + when /^\*/ + path = $' + parsed << :any + when NODE_TYPE + type = $1 + path = $' + parsed << type.tr('-', '_').intern + when PI + path = $' + literal = nil + if path !~ /^\s*\)/ + path =~ LITERAL + literal = $1 + path = $' + raise ParseException.new("Missing ')' after processing instruction") if path[0] != ?) + path = path[1..-1] + end + parsed << :processing_instruction + parsed << (literal || '') + when NCNAMETEST + #puts "NCNAMETEST" + prefix = $1 + path = $' + parsed << :namespace + parsed << prefix + when QNAME + #puts "QNAME" + prefix = $1 + name = $2 + path = $' + prefix = "" unless prefix + parsed << :qname + parsed << prefix + parsed << name + end + return path + end + + # Filters the supplied nodeset on the predicate(s) + def Predicate path, parsed + #puts "PREDICATE with #{path}" + return nil unless path[0] == ?[ + predicates = [] + while path[0] == ?[ + path, expr = get_group(path) + predicates << expr[1..-2] if expr + end + #puts "PREDICATES = #{predicates.inspect}" + predicates.each{ |expr| + #puts "ORING #{expr}" + preds = [] + parsed << :predicate + parsed << preds + OrExpr(expr, preds) + } + #puts "PREDICATES = #{predicates.inspect}" + path + end + + # The following return arrays of true/false, a 1-1 mapping of the + # supplied nodeset, except for axe(), which returns a filtered + # nodeset + + #| OrExpr S 'or' S AndExpr + #| AndExpr + def OrExpr path, parsed + #puts "OR >>> #{path}" + n = [] + rest = AndExpr( path, n ) + #puts "OR <<< #{rest}" + if rest != path + while rest =~ /^\s*( or )/ + n = [ :or, n, [] ] + rest = AndExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| AndExpr S 'and' S EqualityExpr + #| EqualityExpr + def AndExpr path, parsed + #puts "AND >>> #{path}" + n = [] + rest = EqualityExpr( path, n ) + #puts "AND <<< #{rest}" + if rest != path + while rest =~ /^\s*( and )/ + n = [ :and, n, [] ] + #puts "AND >>> #{rest}" + rest = EqualityExpr( $', n[-1] ) + #puts "AND <<< #{rest}" + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| EqualityExpr ('=' | '!=') RelationalExpr + #| RelationalExpr + def EqualityExpr path, parsed + #puts "EQUALITY >>> #{path}" + n = [] + rest = RelationalExpr( path, n ) + #puts "EQUALITY <<< #{rest}" + if rest != path + while rest =~ /^\s*(!?=)\s*/ + if $1[0] == ?! + n = [ :neq, n, [] ] + else + n = [ :eq, n, [] ] + end + rest = RelationalExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| RelationalExpr ('<' | '>' | '<=' | '>=') AdditiveExpr + #| AdditiveExpr + def RelationalExpr path, parsed + #puts "RELATION >>> #{path}" + n = [] + rest = AdditiveExpr( path, n ) + #puts "RELATION <<< #{rest}" + if rest != path + while rest =~ /^\s*([<>]=?)\s*/ + if $1[0] == ?< + sym = "lt" + else + sym = "gt" + end + sym << "eq" if $1[-1] == ?= + n = [ sym.intern, n, [] ] + rest = AdditiveExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| AdditiveExpr ('+' | S '-') MultiplicativeExpr + #| MultiplicativeExpr + def AdditiveExpr path, parsed + #puts "ADDITIVE >>> #{path}" + n = [] + rest = MultiplicativeExpr( path, n ) + #puts "ADDITIVE <<< #{rest}" + if rest != path + while rest =~ /^\s*(\+| -)\s*/ + if $1[0] == ?+ + n = [ :plus, n, [] ] + else + n = [ :minus, n, [] ] + end + rest = MultiplicativeExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| MultiplicativeExpr ('*' | S ('div' | 'mod') S) UnaryExpr + #| UnaryExpr + def MultiplicativeExpr path, parsed + #puts "MULT >>> #{path}" + n = [] + rest = UnaryExpr( path, n ) + #puts "MULT <<< #{rest}" + if rest != path + while rest =~ /^\s*(\*| div | mod )\s*/ + if $1[0] == ?* + n = [ :mult, n, [] ] + elsif $1.include?( "div" ) + n = [ :div, n, [] ] + else + n = [ :mod, n, [] ] + end + rest = UnaryExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| '-' UnaryExpr + #| UnionExpr + def UnaryExpr path, parsed + path =~ /^(\-*)/ + path = $' + if $1 and (($1.size % 2) != 0) + mult = -1 + else + mult = 1 + end + parsed << :neg if mult < 0 + + #puts "UNARY >>> #{path}" + n = [] + path = UnionExpr( path, n ) + #puts "UNARY <<< #{path}" + parsed.concat( n ) + path + end + + #| UnionExpr '|' PathExpr + #| PathExpr + def UnionExpr path, parsed + #puts "UNION >>> #{path}" + n = [] + rest = PathExpr( path, n ) + #puts "UNION <<< #{rest}" + if rest != path + while rest =~ /^\s*(\|)\s*/ + n = [ :union, n, [] ] + rest = PathExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace( n ) + elsif n.size > 0 + parsed << n + end + rest + end + + #| LocationPath + #| FilterExpr ('/' | '//') RelativeLocationPath + def PathExpr path, parsed + path =~ /^\s*/ + path = $' + #puts "PATH >>> #{path}" + n = [] + rest = FilterExpr( path, n ) + #puts "PATH <<< '#{rest}'" + if rest != path + if rest and rest[0] == ?/ + return RelativeLocationPath(rest, n) + end + end + #puts "BEFORE WITH '#{rest}'" + rest = LocationPath(rest, n) if rest =~ /\A[\/\.\@\[\w_*]/ + parsed.concat(n) + return rest + end + + #| FilterExpr Predicate + #| PrimaryExpr + def FilterExpr path, parsed + #puts "FILTER >>> #{path}" + n = [] + path = PrimaryExpr( path, n ) + #puts "FILTER <<< #{path}" + path = Predicate(path, n) if path and path[0] == ?[ + #puts "FILTER <<< #{path}" + parsed.concat(n) + path + end + + #| VARIABLE_REFERENCE + #| '(' expr ')' + #| LITERAL + #| NUMBER + #| FunctionCall + VARIABLE_REFERENCE = /^\$(#{NAME_STR})/u + NUMBER = /^(\d*\.?\d+)/ + NT = /^comment|text|processing-instruction|node$/ + def PrimaryExpr path, parsed + arry = [] + case path + when VARIABLE_REFERENCE + varname = $1 + path = $' + parsed << :variable + parsed << varname + #arry << @variables[ varname ] + when /^(\w[-\w]*)(?:\()/ + #puts "PrimaryExpr :: Function >>> #$1 -- '#$''" + fname = $1 + tmp = $' + #puts "#{fname} =~ #{NT.inspect}" + return path if fname =~ NT + path = tmp + parsed << :function + parsed << fname + path = FunctionCall(path, parsed) + when NUMBER + #puts "LITERAL or NUMBER: #$1" + varname = $1.nil? ? $2 : $1 + path = $' + parsed << :literal + parsed << (varname.include?('.') ? varname.to_f : varname.to_i) + when LITERAL + #puts "LITERAL or NUMBER: #$1" + varname = $1.nil? ? $2 : $1 + path = $' + parsed << :literal + parsed << varname + when /^\(/ #/ + path, contents = get_group(path) + contents = contents[1..-2] + n = [] + OrExpr( contents, n ) + parsed.concat(n) + end + path + end + + #| FUNCTION_NAME '(' ( expr ( ',' expr )* )? ')' + def FunctionCall rest, parsed + path, arguments = parse_args(rest) + argset = [] + for argument in arguments + args = [] + OrExpr( argument, args ) + argset << args + end + parsed << argset + path + end + + # get_group( '[foo]bar' ) -> ['bar', '[foo]'] + def get_group string + ind = 0 + depth = 0 + st = string[0,1] + en = (st == "(" ? ")" : "]") + begin + case string[ind,1] + when st + depth += 1 + when en + depth -= 1 + end + ind += 1 + end while depth > 0 and ind < string.length + return nil unless depth==0 + [string[ind..-1], string[0..ind-1]] + end + + def parse_args( string ) + arguments = [] + ind = 0 + inquot = false + inapos = false + depth = 1 + begin + case string[ind] + when ?" + inquot = !inquot unless inapos + when ?' + inapos = !inapos unless inquot + else + unless inquot or inapos + case string[ind] + when ?( + depth += 1 + if depth == 1 + string = string[1..-1] + ind -= 1 + end + when ?) + depth -= 1 + if depth == 0 + s = string[0,ind].strip + arguments << s unless s == "" + string = string[ind+1..-1] + end + when ?, + if depth == 1 + s = string[0,ind].strip + arguments << s unless s == "" + string = string[ind+1..-1] + ind = -1 + end + end + end + end + ind += 1 + end while depth > 0 and ind < string.length + return nil unless depth==0 + [string,arguments] + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/quickpath.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/quickpath.rb new file mode 100644 index 00000000..c099db85 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/quickpath.rb @@ -0,0 +1,266 @@ +require 'rexml/functions' +require 'rexml/xmltokens' + +module REXML + class QuickPath + include Functions + include XMLTokens + + EMPTY_HASH = {} + + def QuickPath::first element, path, namespaces=EMPTY_HASH + match(element, path, namespaces)[0] + end + + def QuickPath::each element, path, namespaces=EMPTY_HASH, &block + path = "*" unless path + match(element, path, namespaces).each( &block ) + end + + def QuickPath::match element, path, namespaces=EMPTY_HASH + raise "nil is not a valid xpath" unless path + results = nil + Functions::namespace_context = namespaces + case path + when /^\/([^\/]|$)/u + # match on root + path = path[1..-1] + return [element.root.parent] if path == '' + results = filter([element.root], path) + when /^[-\w]*::/u + results = filter([element], path) + when /^\*/u + results = filter(element.to_a, path) + when /^[\[!\w:]/u + # match on child + matches = [] + children = element.to_a + results = filter(children, path) + else + results = filter([element], path) + end + return results + end + + # Given an array of nodes it filters the array based on the path. The + # result is that when this method returns, the array will contain elements + # which match the path + def QuickPath::filter elements, path + return elements if path.nil? or path == '' or elements.size == 0 + case path + when /^\/\//u # Descendant + return axe( elements, "descendant-or-self", $' ) + when /^\/?\b(\w[-\w]*)\b::/u # Axe + axe_name = $1 + rest = $' + return axe( elements, $1, $' ) + when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child + rest = $' + results = [] + elements.each do |element| + results |= filter( element.to_a, rest ) + end + return results + when /^\/?(\w[-\w]*)\(/u # / Function + return function( elements, $1, $' ) + when Namespace::NAMESPLIT # Element name + name = $2 + ns = $1 + rest = $' + elements.delete_if do |element| + !(element.kind_of? Element and + (element.expanded_name == name or + (element.name == name and + element.namespace == Functions.namespace_context[ns]))) + end + return filter( elements, rest ) + when /^\/\[/u + matches = [] + elements.each do |element| + matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element + end + return matches + when /^\[/u # Predicate + return predicate( elements, path ) + when /^\/?\.\.\./u # Ancestor + return axe( elements, "ancestor", $' ) + when /^\/?\.\./u # Parent + return filter( elements.collect{|e|e.parent}, $' ) + when /^\/?\./u # Self + return filter( elements, $' ) + when /^\*/u # Any + results = [] + elements.each do |element| + results |= filter( [element], $' ) if element.kind_of? Element + #if element.kind_of? Element + # children = element.to_a + # children.delete_if { |child| !child.kind_of?(Element) } + # results |= filter( children, $' ) + #end + end + return results + end + return [] + end + + def QuickPath::axe( elements, axe_name, rest ) + matches = [] + matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u + case axe_name + when /^descendant/u + elements.each do |element| + matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element + end + when /^ancestor/u + elements.each do |element| + while element.parent + matches << element.parent + element = element.parent + end + end + matches = filter( matches, rest ) + when "self" + matches = filter( elements, rest ) + when "child" + elements.each do |element| + matches |= filter( element.to_a, rest ) if element.kind_of? Element + end + when "attribute" + elements.each do |element| + matches << element.attributes[ rest ] if element.kind_of? Element + end + when "parent" + matches = filter(elements.collect{|element| element.parent}.uniq, rest) + when "following-sibling" + matches = filter(elements.collect{|element| element.next_sibling}.uniq, + rest) + when "previous-sibling" + matches = filter(elements.collect{|element| + element.previous_sibling}.uniq, rest ) + end + return matches.uniq + end + + # A predicate filters a node-set with respect to an axis to produce a + # new node-set. For each node in the node-set to be filtered, the + # PredicateExpr is evaluated with that node as the context node, with + # the number of nodes in the node-set as the context size, and with the + # proximity position of the node in the node-set with respect to the + # axis as the context position; if PredicateExpr evaluates to true for + # that node, the node is included in the new node-set; otherwise, it is + # not included. + # + # A PredicateExpr is evaluated by evaluating the Expr and converting + # the result to a boolean. If the result is a number, the result will + # be converted to true if the number is equal to the context position + # and will be converted to false otherwise; if the result is not a + # number, then the result will be converted as if by a call to the + # boolean function. Thus a location path para[3] is equivalent to + # para[position()=3]. + def QuickPath::predicate( elements, path ) + ind = 1 + bcount = 1 + while bcount > 0 + bcount += 1 if path[ind] == ?[ + bcount -= 1 if path[ind] == ?] + ind += 1 + end + ind -= 1 + predicate = path[1..ind-1] + rest = path[ind+1..-1] + + # have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c' + predicate.gsub!( /([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)/u ) { + "#$1 #$2 #$3 and #$3 #$4 #$5" + } + # Let's do some Ruby trickery to avoid some work: + predicate.gsub!( /&/u, "&&" ) + predicate.gsub!( /=/u, "==" ) + predicate.gsub!( /@(\w[-\w.]*)/u ) { + "attribute(\"#$1\")" + } + predicate.gsub!( /\bmod\b/u, "%" ) + predicate.gsub!( /\b(\w[-\w.]*\()/u ) { + fname = $1 + fname.gsub( /-/u, "_" ) + } + + Functions.pair = [ 0, elements.size ] + results = [] + elements.each do |element| + Functions.pair[0] += 1 + Functions.node = element + res = eval( predicate ) + case res + when true + results << element + when Fixnum + results << element if Functions.pair[0] == res + when String + results << element + end + end + return filter( results, rest ) + end + + def QuickPath::attribute( name ) + return Functions.node.attributes[name] if Functions.node.kind_of? Element + end + + def QuickPath::name() + return Functions.node.name if Functions.node.kind_of? Element + end + + def QuickPath::method_missing( id, *args ) + begin + Functions.send( id.id2name, *args ) + rescue Exception + raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}" + end + end + + def QuickPath::function( elements, fname, rest ) + args = parse_args( elements, rest ) + Functions.pair = [0, elements.size] + results = [] + elements.each do |element| + Functions.pair[0] += 1 + Functions.node = element + res = Functions.send( fname, *args ) + case res + when true + results << element + when Fixnum + results << element if Functions.pair[0] == res + end + end + return results + end + + def QuickPath::parse_args( element, string ) + # /.*?(?:\)|,)/ + arguments = [] + buffer = "" + while string and string != "" + c = string[0] + string.sub!(/^./u, "") + case c + when ?, + # if depth = 1, then we start a new argument + arguments << evaluate( buffer ) + #arguments << evaluate( string[0..count] ) + when ?( + # start a new method call + function( element, buffer, string ) + buffer = "" + when ?) + # close the method call and return arguments + return arguments + else + buffer << c + end + end + "" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/rexml.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/rexml.rb new file mode 100644 index 00000000..c7b9c624 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/rexml.rb @@ -0,0 +1,32 @@ +# -*- encoding: utf-8 -*- +# REXML is an XML toolkit for Ruby[http://www.ruby-lang.org], in Ruby. +# +# REXML is a _pure_ Ruby, XML 1.0 conforming, +# non-validating[http://www.w3.org/TR/2004/REC-xml-20040204/#sec-conformance] +# toolkit with an intuitive API. REXML passes 100% of the non-validating Oasis +# tests[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml], +# and provides tree, stream, SAX2, pull, and lightweight APIs. REXML also +# includes a full XPath[http://www.w3c.org/tr/xpath] 1.0 implementation. Since +# Ruby 1.8, REXML is included in the standard Ruby distribution. +# +# Main page:: http://www.germane-software.com/software/rexml +# Author:: Sean Russell +# Version:: 3.1.7.2 +# Date:: 2007/275 +# Revision:: $Revision: 13815 $ +# +# This API documentation can be downloaded from the REXML home page, or can +# be accessed online[http://www.germane-software.com/software/rexml_doc] +# +# A tutorial is available in the REXML distribution in docs/tutorial.html, +# or can be accessed +# online[http://www.germane-software.com/software/rexml/docs/tutorial.html] +module REXML + COPYRIGHT = "Copyright \xC2\xA9 2001-2006 Sean Russell " + VERSION = "3.1.7.2" + DATE = "2007/275" + REVISION = "$Revision: 13815 $".gsub(/\$Revision:|\$/,'').strip + + Copyright = COPYRIGHT + Version = VERSION +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/sax2listener.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/sax2listener.rb new file mode 100644 index 00000000..8db1389d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/sax2listener.rb @@ -0,0 +1,97 @@ +module REXML + # A template for stream parser listeners. + # Note that the declarations (attlistdecl, elementdecl, etc) are trivially + # processed; REXML doesn't yet handle doctype entity declarations, so you + # have to parse them out yourself. + # === Missing methods from SAX2 + # ignorable_whitespace + # === Methods extending SAX2 + # +WARNING+ + # These methods are certainly going to change, until DTDs are fully + # supported. Be aware of this. + # start_document + # end_document + # doctype + # elementdecl + # attlistdecl + # entitydecl + # notationdecl + # cdata + # xmldecl + # comment + module SAX2Listener + def start_document + end + def end_document + end + def start_prefix_mapping prefix, uri + end + def end_prefix_mapping prefix + end + def start_element uri, localname, qname, attributes + end + def end_element uri, localname, qname + end + def characters text + end + def processing_instruction target, data + end + # Handles a doctype declaration. Any attributes of the doctype which are + # not supplied will be nil. # EG, + # @p name the name of the doctype; EG, "me" + # @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC" + # @p long_name the supplied long name, or nil. EG, "foo" + # @p uri the uri of the doctype, or nil. EG, "bar" + def doctype name, pub_sys, long_name, uri + end + # If a doctype includes an ATTLIST declaration, it will cause this + # method to be called. The content is the declaration itself, unparsed. + # EG, will come to this method as "el + # attr CDATA #REQUIRED". This is the same for all of the .*decl + # methods. + def attlistdecl(element, pairs, contents) + end + # + def elementdecl content + end + # + # The argument passed to this method is an array of the entity + # declaration. It can be in a number of formats, but in general it + # returns (example, result): + # + # ["%", "YN", "'\"Yes\"'", "\""] + # + # ["%", "YN", "'Yes'", "s"] + # + # ["WhatHeSaid", "\"He said %YN;\"", "YN"] + # + # ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""] + # + # ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""] + # + # ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"] + def entitydecl name, decl + end + # + def notationdecl content + end + # Called when is encountered in a document. + # @p content "..." + def cdata content + end + # Called when an XML PI is encountered in the document. + # EG: + # @p version the version attribute value. EG, "1.0" + # @p encoding the encoding attribute value, or nil. EG, "utf" + # @p standalone the standalone attribute value, or nil. EG, nil + # @p spaced the declaration is followed by a line break + def xmldecl version, encoding, standalone + end + # Called when a comment is encountered. + # @p comment The content of the comment + def comment comment + end + def progress position + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/source.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/source.rb new file mode 100644 index 00000000..ce7a2c98 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/source.rb @@ -0,0 +1,251 @@ +require 'rexml/encoding' + +module REXML + # Generates Source-s. USE THIS CLASS. + class SourceFactory + # Generates a Source object + # @param arg Either a String, or an IO + # @return a Source, or nil if a bad argument was given + def SourceFactory::create_from(arg) + if arg.kind_of? String + Source.new(arg) + elsif arg.respond_to? :read and + arg.respond_to? :readline and + arg.respond_to? :nil? and + arg.respond_to? :eof? + IOSource.new(arg) + elsif arg.kind_of? Source + arg + else + raise "#{arg.class} is not a valid input stream. It must walk \n"+ + "like either a String, an IO, or a Source." + end + end + end + + # A Source can be searched for patterns, and wraps buffers and other + # objects and provides consumption of text + class Source + include Encoding + # The current buffer (what we're going to read next) + attr_reader :buffer + # The line number of the last consumed text + attr_reader :line + attr_reader :encoding + + # Constructor + # @param arg must be a String, and should be a valid XML document + # @param encoding if non-null, sets the encoding of the source to this + # value, overriding all encoding detection + def initialize(arg, encoding=nil) + @orig = @buffer = arg + if encoding + self.encoding = encoding + else + self.encoding = check_encoding( @buffer ) + end + @line = 0 + end + + + # Inherited from Encoding + # Overridden to support optimized en/decoding + def encoding=(enc) + return unless super + @line_break = encode( '>' ) + if enc != UTF_8 + @buffer = decode(@buffer) + @to_utf = true + else + @to_utf = false + end + end + + # Scans the source for a given pattern. Note, that this is not your + # usual scan() method. For one thing, the pattern argument has some + # requirements; for another, the source can be consumed. You can easily + # confuse this method. Originally, the patterns were easier + # to construct and this method more robust, because this method + # generated search regexes on the fly; however, this was + # computationally expensive and slowed down the entire REXML package + # considerably, since this is by far the most commonly called method. + # @param pattern must be a Regexp, and must be in the form of + # /^\s*(#{your pattern, with no groups})(.*)/. The first group + # will be returned; the second group is used if the consume flag is + # set. + # @param consume if true, the pattern returned will be consumed, leaving + # everything after it in the Source. + # @return the pattern, if found, or nil if the Source is empty or the + # pattern is not found. + def scan(pattern, cons=false) + return nil if @buffer.nil? + rv = @buffer.scan(pattern) + @buffer = $' if cons and rv.size>0 + rv + end + + def read + end + + def consume( pattern ) + @buffer = $' if pattern.match( @buffer ) + end + + def match_to( char, pattern ) + return pattern.match(@buffer) + end + + def match_to_consume( char, pattern ) + md = pattern.match(@buffer) + @buffer = $' + return md + end + + def match(pattern, cons=false) + md = pattern.match(@buffer) + @buffer = $' if cons and md + return md + end + + # @return true if the Source is exhausted + def empty? + @buffer == "" + end + + def position + @orig.index( @buffer ) + end + + # @return the current line in the source + def current_line + lines = @orig.split + res = lines.grep @buffer[0..30] + res = res[-1] if res.kind_of? Array + lines.index( res ) if res + end + end + + # A Source that wraps an IO. See the Source class for method + # documentation + class IOSource < Source + #attr_reader :block_size + + # block_size has been deprecated + def initialize(arg, block_size=500, encoding=nil) + @er_source = @source = arg + @to_utf = false + + # Determining the encoding is a deceptively difficult issue to resolve. + # First, we check the first two bytes for UTF-16. Then we + # assume that the encoding is at least ASCII enough for the '>', and + # we read until we get one of those. This gives us the XML declaration, + # if there is one. If there isn't one, the file MUST be UTF-8, as per + # the XML spec. If there is one, we can determine the encoding from + # it. + @buffer = "" + str = @source.read( 2 ) + if encoding + self.encoding = encoding + elsif 0xfe == str[0] && 0xff == str[1] + @line_break = "\000>" + elsif 0xff == str[0] && 0xfe == str[1] + @line_break = ">\000" + elsif 0xef == str[0] && 0xbb == str[1] + str += @source.read(1) + str = '' if (0xbf == str[2]) + @line_break = ">" + else + @line_break = ">" + end + super str+@source.readline( @line_break ) + end + + def scan(pattern, cons=false) + rv = super + # You'll notice that this next section is very similar to the same + # section in match(), but just a liiittle different. This is + # because it is a touch faster to do it this way with scan() + # than the way match() does it; enough faster to warrent duplicating + # some code + if rv.size == 0 + until @buffer =~ pattern or @source.nil? + begin + # READLINE OPT + #str = @source.read(@block_size) + str = @source.readline(@line_break) + str = decode(str) if @to_utf and str + @buffer << str + rescue Iconv::IllegalSequence + raise + rescue + @source = nil + end + end + rv = super + end + rv.taint + rv + end + + def read + begin + str = @source.readline(@line_break) + str = decode(str) if @to_utf and str + @buffer << str + rescue Exception, NameError + @source = nil + end + end + + def consume( pattern ) + match( pattern, true ) + end + + def match( pattern, cons=false ) + rv = pattern.match(@buffer) + @buffer = $' if cons and rv + while !rv and @source + begin + str = @source.readline(@line_break) + str = decode(str) if @to_utf and str + @buffer << str + rv = pattern.match(@buffer) + @buffer = $' if cons and rv + rescue + @source = nil + end + end + rv.taint + rv + end + + def empty? + super and ( @source.nil? || @source.eof? ) + end + + def position + @er_source.stat.pipe? ? 0 : @er_source.pos + end + + # @return the current line in the source + def current_line + begin + pos = @er_source.pos # The byte position in the source + lineno = @er_source.lineno # The XML < position in the source + @er_source.rewind + line = 0 # The \r\n position in the source + begin + while @er_source.pos < pos + @er_source.readline + line += 1 + end + rescue + end + rescue IOError + pos = -1 + line = -1 + end + [pos, lineno, line] + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/streamlistener.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/streamlistener.rb new file mode 100644 index 00000000..6f401125 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/streamlistener.rb @@ -0,0 +1,92 @@ +module REXML + # A template for stream parser listeners. + # Note that the declarations (attlistdecl, elementdecl, etc) are trivially + # processed; REXML doesn't yet handle doctype entity declarations, so you + # have to parse them out yourself. + module StreamListener + # Called when a tag is encountered. + # @p name the tag name + # @p attrs an array of arrays of attribute/value pairs, suitable for + # use with assoc or rassoc. IE, + # will result in + # tag_start( "tag", # [["attr1","value1"],["attr2","value2"]]) + def tag_start name, attrs + end + # Called when the end tag is reached. In the case of , tag_end + # will be called immidiately after tag_start + # @p the name of the tag + def tag_end name + end + # Called when text is encountered in the document + # @p text the text content. + def text text + end + # Called when an instruction is encountered. EG: + # @p name the instruction name; in the example, "xsl" + # @p instruction the rest of the instruction. In the example, + # "sheet='foo'" + def instruction name, instruction + end + # Called when a comment is encountered. + # @p comment The content of the comment + def comment comment + end + # Handles a doctype declaration. Any attributes of the doctype which are + # not supplied will be nil. # EG, + # @p name the name of the doctype; EG, "me" + # @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC" + # @p long_name the supplied long name, or nil. EG, "foo" + # @p uri the uri of the doctype, or nil. EG, "bar" + def doctype name, pub_sys, long_name, uri + end + # Called when the doctype is done + def doctype_end + end + # If a doctype includes an ATTLIST declaration, it will cause this + # method to be called. The content is the declaration itself, unparsed. + # EG, will come to this method as "el + # attr CDATA #REQUIRED". This is the same for all of the .*decl + # methods. + def attlistdecl element_name, attributes, raw_content + end + # + def elementdecl content + end + # + # The argument passed to this method is an array of the entity + # declaration. It can be in a number of formats, but in general it + # returns (example, result): + # + # ["%", "YN", "'\"Yes\"'", "\""] + # + # ["%", "YN", "'Yes'", "s"] + # + # ["WhatHeSaid", "\"He said %YN;\"", "YN"] + # + # ["open-hatch", "SYSTEM", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""] + # + # ["open-hatch", "PUBLIC", "\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"", "\"http://www.textuality.com/boilerplate/OpenHatch.xml\""] + # + # ["hatch-pic", "SYSTEM", "\"../grafix/OpenHatch.gif\"", "\n\t\t\t\t\t\t\tNDATA gif", "gif"] + def entitydecl content + end + # + def notationdecl content + end + # Called when %foo; is encountered in a doctype declaration. + # @p content "foo" + def entity content + end + # Called when is encountered in a document. + # @p content "..." + def cdata content + end + # Called when an XML PI is encountered in the document. + # EG: + # @p version the version attribute value. EG, "1.0" + # @p encoding the encoding attribute value, or nil. EG, "utf" + # @p standalone the standalone attribute value, or nil. EG, nil + def xmldecl version, encoding, standalone + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/syncenumerator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/syncenumerator.rb new file mode 100644 index 00000000..955e006c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/syncenumerator.rb @@ -0,0 +1,33 @@ +module REXML + class SyncEnumerator + include Enumerable + + # Creates a new SyncEnumerator which enumerates rows of given + # Enumerable objects. + def initialize(*enums) + @gens = enums + @biggest = @gens[0] + @gens.each {|x| @biggest = x if x.size > @biggest.size } + end + + # Returns the number of enumerated Enumerable objects, i.e. the size + # of each row. + def size + @gens.size + end + + # Returns the number of enumerated Enumerable objects, i.e. the size + # of each row. + def length + @gens.length + end + + # Enumerates rows of the Enumerable objects. + def each + @biggest.zip( *@gens ) {|a| + yield(*a[1..-1]) + } + self + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/text.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/text.rb new file mode 100644 index 00000000..9804aa71 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/text.rb @@ -0,0 +1,344 @@ +require 'rexml/entity' +require 'rexml/doctype' +require 'rexml/child' +require 'rexml/doctype' +require 'rexml/parseexception' + +module REXML + # Represents text nodes in an XML document + class Text < Child + include Comparable + # The order in which the substitutions occur + SPECIALS = [ /&(?!#?[\w-]+;)/u, //u, /"/u, /'/u, /\r/u ] + SUBSTITUTES = ['&', '<', '>', '"', ''', ' '] + # Characters which are substituted in written strings + SLAICEPS = [ '<', '>', '"', "'", '&' ] + SETUTITSBUS = [ /</u, />/u, /"/u, /'/u, /&/u ] + + # If +raw+ is true, then REXML leaves the value alone + attr_accessor :raw + + ILLEGAL = /(<|&(?!(#{Entity::NAME})|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));))/um + NUMERICENTITY = /�*((?:\d+)|(?:x[a-fA-F0-9]+));/ + + # Constructor + # +arg+ if a String, the content is set to the String. If a Text, + # the object is shallowly cloned. + # + # +respect_whitespace+ (boolean, false) if true, whitespace is + # respected + # + # +parent+ (nil) if this is a Parent object, the parent + # will be set to this. + # + # +raw+ (nil) This argument can be given three values. + # If true, then the value of used to construct this object is expected to + # contain no unescaped XML markup, and REXML will not change the text. If + # this value is false, the string may contain any characters, and REXML will + # escape any and all defined entities whose values are contained in the + # text. If this value is nil (the default), then the raw value of the + # parent will be used as the raw value for this node. If there is no raw + # value for the parent, and no value is supplied, the default is false. + # Use this field if you have entities defined for some text, and you don't + # want REXML to escape that text in output. + # Text.new( "<&", false, nil, false ) #-> "<&" + # Text.new( "<&", false, nil, false ) #-> "&lt;&amp;" + # Text.new( "<&", false, nil, true ) #-> Parse exception + # Text.new( "<&", false, nil, true ) #-> "<&" + # # Assume that the entity "s" is defined to be "sean" + # # and that the entity "r" is defined to be "russell" + # Text.new( "sean russell" ) #-> "&s; &r;" + # Text.new( "sean russell", false, nil, true ) #-> "sean russell" + # + # +entity_filter+ (nil) This can be an array of entities to match in the + # supplied text. This argument is only useful if +raw+ is set to false. + # Text.new( "sean russell", false, nil, false, ["s"] ) #-> "&s; russell" + # Text.new( "sean russell", false, nil, true, ["s"] ) #-> "sean russell" + # In the last example, the +entity_filter+ argument is ignored. + # + # +pattern+ INTERNAL USE ONLY + def initialize(arg, respect_whitespace=false, parent=nil, raw=nil, + entity_filter=nil, illegal=ILLEGAL ) + + @raw = false + + if parent + super( parent ) + @raw = parent.raw + else + @parent = nil + end + + @raw = raw unless raw.nil? + @entity_filter = entity_filter + @normalized = @unnormalized = nil + + if arg.kind_of? String + @string = arg.clone + @string.squeeze!(" \n\t") unless respect_whitespace + elsif arg.kind_of? Text + @string = arg.to_s + @raw = arg.raw + elsif + raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})" + end + + @string.gsub!( /\r\n?/, "\n" ) + + # check for illegal characters + if @raw + if @string =~ illegal + raise "Illegal character '#{$1}' in raw string \"#{@string}\"" + end + end + end + + def node_type + :text + end + + def empty? + @string.size==0 + end + + + def clone + return Text.new(self) + end + + + # Appends text to this text node. The text is appended in the +raw+ mode + # of this text node. + def <<( to_append ) + @string << to_append.gsub( /\r\n?/, "\n" ) + end + + + # +other+ a String or a Text + # +returns+ the result of (to_s <=> arg.to_s) + def <=>( other ) + to_s() <=> other.to_s + end + + REFERENCE = /#{Entity::REFERENCE}/ + # Returns the string value of this text node. This string is always + # escaped, meaning that it is a valid XML text node string, and all + # entities that can be escaped, have been inserted. This method respects + # the entity filter set in the constructor. + # + # # Assume that the entity "s" is defined to be "sean", and that the + # # entity "r" is defined to be "russell" + # t = Text.new( "< & sean russell", false, nil, false, ['s'] ) + # t.to_s #-> "< & &s; russell" + # t = Text.new( "< & &s; russell", false, nil, false ) + # t.to_s #-> "< & &s; russell" + # u = Text.new( "sean russell", false, nil, true ) + # u.to_s #-> "sean russell" + def to_s + return @string if @raw + return @normalized if @normalized + + doctype = nil + if @parent + doc = @parent.document + doctype = doc.doctype if doc + end + + @normalized = Text::normalize( @string, doctype, @entity_filter ) + end + + def inspect + @string.inspect + end + + # Returns the string value of this text. This is the text without + # entities, as it might be used programmatically, or printed to the + # console. This ignores the 'raw' attribute setting, and any + # entity_filter. + # + # # Assume that the entity "s" is defined to be "sean", and that the + # # entity "r" is defined to be "russell" + # t = Text.new( "< & sean russell", false, nil, false, ['s'] ) + # t.value #-> "< & sean russell" + # t = Text.new( "< & &s; russell", false, nil, false ) + # t.value #-> "< & sean russell" + # u = Text.new( "sean russell", false, nil, true ) + # u.value #-> "sean russell" + def value + @unnormalized if @unnormalized + doctype = nil + if @parent + doc = @parent.document + doctype = doc.doctype if doc + end + @unnormalized = Text::unnormalize( @string, doctype ) + end + + # Sets the contents of this text node. This expects the text to be + # unnormalized. It returns self. + # + # e = Element.new( "a" ) + # e.add_text( "foo" ) # foo + # e[0].value = "bar" # bar + # e[0].value = "" # <a> + def value=( val ) + @string = val.gsub( /\r\n?/, "\n" ) + @unnormalized = nil + @normalized = nil + @raw = false + end + + def wrap(string, width, addnewline=false) + # Recursivly wrap string at width. + return string if string.length <= width + place = string.rindex(' ', width) # Position in string with last ' ' before cutoff + if addnewline then + return "\n" + string[0,place] + "\n" + wrap(string[place+1..-1], width) + else + return string[0,place] + "\n" + wrap(string[place+1..-1], width) + end + end + + def indent_text(string, level=1, style="\t", indentfirstline=true) + return string if level < 0 + new_string = '' + string.each { |line| + indent_string = style * level + new_line = (indent_string + line).sub(/[\s]+$/,'') + new_string << new_line + } + new_string.strip! unless indentfirstline + return new_string + end + + # == DEPRECATED + # See REXML::Formatters + # + def write( writer, indent=-1, transitive=false, ie_hack=false ) + Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters") + formatter = if indent > -1 + REXML::Formatters::Pretty.new( indent ) + else + REXML::Formatters::Default.new + end + formatter.write( self, writer ) + end + + # FIXME + # This probably won't work properly + def xpath + path = @parent.xpath + path += "/text()" + return path + end + + # Writes out text, substituting special characters beforehand. + # +out+ A String, IO, or any other object supporting <<( String ) + # +input+ the text to substitute and the write out + # + # z=utf8.unpack("U*") + # ascOut="" + # z.each{|r| + # if r < 0x100 + # ascOut.concat(r.chr) + # else + # ascOut.concat(sprintf("&#x%x;", r)) + # end + # } + # puts ascOut + def write_with_substitution out, input + copy = input.clone + # Doing it like this rather than in a loop improves the speed + copy.gsub!( SPECIALS[0], SUBSTITUTES[0] ) + copy.gsub!( SPECIALS[1], SUBSTITUTES[1] ) + copy.gsub!( SPECIALS[2], SUBSTITUTES[2] ) + copy.gsub!( SPECIALS[3], SUBSTITUTES[3] ) + copy.gsub!( SPECIALS[4], SUBSTITUTES[4] ) + copy.gsub!( SPECIALS[5], SUBSTITUTES[5] ) + out << copy + end + + # Reads text, substituting entities + def Text::read_with_substitution( input, illegal=nil ) + copy = input.clone + + if copy =~ illegal + raise ParseException.new( "malformed text: Illegal character #$& in \"#{copy}\"" ) + end if illegal + + copy.gsub!( /\r\n?/, "\n" ) + if copy.include? ?& + copy.gsub!( SETUTITSBUS[0], SLAICEPS[0] ) + copy.gsub!( SETUTITSBUS[1], SLAICEPS[1] ) + copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] ) + copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] ) + copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] ) + copy.gsub!( /�*((?:\d+)|(?:x[a-f0-9]+));/ ) {|m| + m=$1 + #m='0' if m=='' + m = "0#{m}" if m[0] == ?x + [Integer(m)].pack('U*') + } + end + copy + end + + EREFERENCE = /&(?!#{Entity::NAME};)/ + # Escapes all possible entities + def Text::normalize( input, doctype=nil, entity_filter=nil ) + copy = input + # Doing it like this rather than in a loop improves the speed + #copy = copy.gsub( EREFERENCE, '&' ) + copy = copy.gsub( "&", "&" ) + if doctype + # Replace all ampersands that aren't part of an entity + doctype.entities.each_value do |entity| + copy = copy.gsub( entity.value, + "&#{entity.name};" ) if entity.value and + not( entity_filter and entity_filter.include?(entity) ) + end + else + # Replace all ampersands that aren't part of an entity + DocType::DEFAULT_ENTITIES.each_value do |entity| + copy = copy.gsub(entity.value, "&#{entity.name};" ) + end + end + copy + end + + # Unescapes all possible entities + def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil ) + rv = string.clone + rv.gsub!( /\r\n?/, "\n" ) + matches = rv.scan( REFERENCE ) + return rv if matches.size == 0 + rv.gsub!( NUMERICENTITY ) {|m| + m=$1 + m = "0#{m}" if m[0] == ?x + [Integer(m)].pack('U*') + } + matches.collect!{|x|x[0]}.compact! + if matches.size > 0 + if doctype + matches.each do |entity_reference| + unless filter and filter.include?(entity_reference) + entity_value = doctype.entity( entity_reference ) + re = /&#{entity_reference};/ + rv.gsub!( re, entity_value ) if entity_value + end + end + else + matches.each do |entity_reference| + unless filter and filter.include?(entity_reference) + entity_value = DocType::DEFAULT_ENTITIES[ entity_reference ] + re = /&#{entity_reference};/ + rv.gsub!( re, entity_value.value ) if entity_value + end + end + end + rv.gsub!( /&/, '&' ) + end + rv + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/undefinednamespaceexception.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/undefinednamespaceexception.rb new file mode 100644 index 00000000..8ebfdfd0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/undefinednamespaceexception.rb @@ -0,0 +1,8 @@ +require 'rexml/parseexception' +module REXML + class UndefinedNamespaceException < ParseException + def initialize( prefix, source, parser ) + super( "Undefined prefix #{prefix} found" ) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/relaxng.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/relaxng.rb new file mode 100644 index 00000000..969f51bc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/relaxng.rb @@ -0,0 +1,559 @@ +require "rexml/validation/validation" +require "rexml/parsers/baseparser" + +module REXML + module Validation + # Implemented: + # * empty + # * element + # * attribute + # * text + # * optional + # * choice + # * oneOrMore + # * zeroOrMore + # * group + # * value + # * interleave + # * mixed + # * ref + # * grammar + # * start + # * define + # + # Not implemented: + # * data + # * param + # * include + # * externalRef + # * notAllowed + # * anyName + # * nsName + # * except + # * name + class RelaxNG + include Validator + + INFINITY = 1.0 / 0.0 + EMPTY = Event.new( nil ) + TEXT = [:start_element, "text"] + attr_accessor :current + attr_accessor :count + attr_reader :references + + # FIXME: Namespaces + def initialize source + parser = REXML::Parsers::BaseParser.new( source ) + + @count = 0 + @references = {} + @root = @current = Sequence.new(self) + @root.previous = true + states = [ @current ] + begin + event = parser.pull + case event[0] + when :start_element + case event[1] + when "empty" + when "element", "attribute", "text", "value" + states[-1] << event + when "optional" + states << Optional.new( self ) + states[-2] << states[-1] + when "choice" + states << Choice.new( self ) + states[-2] << states[-1] + when "oneOrMore" + states << OneOrMore.new( self ) + states[-2] << states[-1] + when "zeroOrMore" + states << ZeroOrMore.new( self ) + states[-2] << states[-1] + when "group" + states << Sequence.new( self ) + states[-2] << states[-1] + when "interleave" + states << Interleave.new( self ) + states[-2] << states[-1] + when "mixed" + states << Interleave.new( self ) + states[-2] << states[-1] + states[-1] << TEXT + when "define" + states << [ event[2]["name"] ] + when "ref" + states[-1] << Ref.new( event[2]["name"] ) + when "anyName" + states << AnyName.new( self ) + states[-2] << states[-1] + when "nsName" + when "except" + when "name" + when "data" + when "param" + when "include" + when "grammar" + when "start" + when "externalRef" + when "notAllowed" + end + when :end_element + case event[1] + when "element", "attribute" + states[-1] << event + when "zeroOrMore", "oneOrMore", "choice", "optional", + "interleave", "group", "mixed" + states.pop + when "define" + ref = states.pop + @references[ ref.shift ] = ref + #when "empty" + end + when :end_document + states[-1] << event + when :text + states[-1] << event + end + end while event[0] != :end_document + end + + def receive event + validate( event ) + end + end + + class State + def initialize( context ) + @previous = [] + @events = [] + @current = 0 + @count = context.count += 1 + @references = context.references + @value = false + end + + def reset + return if @current == 0 + @current = 0 + @events.each {|s| s.reset if s.kind_of? State } + end + + def previous=( previous ) + @previous << previous + end + + def next( event ) + #print "In next with #{event.inspect}. " + #puts "Next (#@current) is #{@events[@current]}" + #p @previous + return @previous.pop.next( event ) if @events[@current].nil? + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].kind_of? State ) + @current += 1 + @events[@current-1].previous = self + return @events[@current-1].next( event ) + end + #puts "Current isn't a state" + if ( @events[@current].matches?(event) ) + @current += 1 + if @events[@current].nil? + #puts "#{inspect[0,5]} 1RETURNING #{@previous.inspect[0,5]}" + return @previous.pop + elsif @events[@current].kind_of? State + @current += 1 + #puts "#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}" + @events[@current-1].previous = self + return @events[@current-1] + else + #puts "#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}" + return self + end + else + return nil + end + end + + def to_s + # Abbreviated: + self.class.name =~ /(?:::)(\w)\w+$/ + # Full: + #self.class.name =~ /(?:::)(\w+)$/ + "#$1.#@count" + end + + def inspect + "< #{to_s} #{@events.collect{|e| + pre = e == @events[@current] ? '#' : '' + pre + e.inspect unless self == e + }.join(', ')} >" + end + + def expected + return [@events[@current]] + end + + def <<( event ) + add_event_to_arry( @events, event ) + end + + + protected + def expand_ref_in( arry, ind ) + new_events = [] + @references[ arry[ind].to_s ].each{ |evt| + add_event_to_arry(new_events,evt) + } + arry[ind,1] = new_events + end + + def add_event_to_arry( arry, evt ) + evt = generate_event( evt ) + if evt.kind_of? String + arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value + @value = false + else + arry << evt + end + end + + def generate_event( event ) + return event if event.kind_of? State or event.class == Ref + evt = nil + arg = nil + case event[0] + when :start_element + case event[1] + when "element" + evt = :start_element + arg = event[2]["name"] + when "attribute" + evt = :start_attribute + arg = event[2]["name"] + when "text" + evt = :text + when "value" + evt = :text + @value = true + end + when :text + return event[1] + when :end_document + return Event.new( event[0] ) + else # then :end_element + case event[1] + when "element" + evt = :end_element + when "attribute" + evt = :end_attribute + end + end + return Event.new( evt, arg ) + end + end + + + class Sequence < State + def matches?(event) + @events[@current].matches?( event ) + end + end + + + class Optional < State + def next( event ) + if @current == 0 + rv = super + return rv if rv + @prior = @previous.pop + return @prior.next( event ) + end + super + end + + def matches?(event) + @events[@current].matches?(event) || + (@current == 0 and @previous[-1].matches?(event)) + end + + def expected + return [ @prior.expected, @events[0] ].flatten if @current == 0 + return [@events[@current]] + end + end + + + class ZeroOrMore < Optional + def next( event ) + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].matches?(event) ) + @current += 1 + if @events[@current].nil? + @current = 0 + return self + elsif @events[@current].kind_of? State + @current += 1 + @events[@current-1].previous = self + return @events[@current-1] + else + return self + end + else + @prior = @previous.pop + return @prior.next( event ) if @current == 0 + return nil + end + end + + def expected + return [ @prior.expected, @events[0] ].flatten if @current == 0 + return [@events[@current]] + end + end + + + class OneOrMore < State + def initialize context + super + @ord = 0 + end + + def reset + super + @ord = 0 + end + + def next( event ) + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].matches?(event) ) + @current += 1 + @ord += 1 + if @events[@current].nil? + @current = 0 + return self + elsif @events[@current].kind_of? State + @current += 1 + @events[@current-1].previous = self + return @events[@current-1] + else + return self + end + else + return @previous.pop.next( event ) if @current == 0 and @ord > 0 + return nil + end + end + + def matches?( event ) + @events[@current].matches?(event) || + (@current == 0 and @ord > 0 and @previous[-1].matches?(event)) + end + + def expected + if @current == 0 and @ord > 0 + return [@previous[-1].expected, @events[0]].flatten + else + return [@events[@current]] + end + end + end + + + class Choice < State + def initialize context + super + @choices = [] + end + + def reset + super + @events = [] + @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } } + end + + def <<( event ) + add_event_to_arry( @choices, event ) + end + + def next( event ) + # Make the choice if we haven't + if @events.size == 0 + c = 0 ; max = @choices.size + while c < max + if @choices[c][0].class == Ref + expand_ref_in( @choices[c], 0 ) + @choices += @choices[c] + @choices.delete( @choices[c] ) + max -= 1 + else + c += 1 + end + end + @events = @choices.find { |evt| evt[0].matches? event } + # Remove the references + # Find the events + end + #puts "In next with #{event.inspect}." + #puts "events is #{@events.inspect}" + unless @events + @events = [] + return nil + end + #puts "current = #@current" + super + end + + def matches?( event ) + return @events[@current].matches?( event ) if @events.size > 0 + !@choices.find{|evt| evt[0].matches?(event)}.nil? + end + + def expected + #puts "IN CHOICE EXPECTED" + #puts "EVENTS = #{@events.inspect}" + return [@events[@current]] if @events.size > 0 + return @choices.collect do |x| + if x[0].kind_of? State + x[0].expected + else + x[0] + end + end.flatten + end + + def inspect + "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >" + end + + protected + def add_event_to_arry( arry, evt ) + if evt.kind_of? State or evt.class == Ref + arry << [evt] + elsif evt[0] == :text + if arry[-1] and + arry[-1][-1].kind_of?( Event ) and + arry[-1][-1].event_type == :text and @value + + arry[-1][-1].event_arg = evt[1] + @value = false + end + else + arry << [] if evt[0] == :start_element + arry[-1] << generate_event( evt ) + end + end + end + + + class Interleave < Choice + def initialize context + super + @choice = 0 + end + + def reset + @choice = 0 + end + + def next_current( event ) + # Expand references + c = 0 ; max = @choices.size + while c < max + if @choices[c][0].class == Ref + expand_ref_in( @choices[c], 0 ) + @choices += @choices[c] + @choices.delete( @choices[c] ) + max -= 1 + else + c += 1 + end + end + @events = @choices[@choice..-1].find { |evt| evt[0].matches? event } + @current = 0 + if @events + # reorder the choices + old = @choices[@choice] + idx = @choices.index( @events ) + @choices[@choice] = @events + @choices[idx] = old + @choice += 1 + end + + #puts "In next with #{event.inspect}." + #puts "events is #{@events.inspect}" + @events = [] unless @events + end + + + def next( event ) + # Find the next series + next_current(event) unless @events[@current] + return nil unless @events[@current] + + expand_ref_in( @events, @current ) if @events[@current].class == Ref + #puts "In next with #{event.inspect}." + #puts "Next (#@current) is #{@events[@current]}" + if ( @events[@current].kind_of? State ) + @current += 1 + @events[@current-1].previous = self + return @events[@current-1].next( event ) + end + #puts "Current isn't a state" + return @previous.pop.next( event ) if @events[@current].nil? + if ( @events[@current].matches?(event) ) + @current += 1 + if @events[@current].nil? + #puts "#{inspect[0,5]} 1RETURNING self" unless @choices[@choice].nil? + return self unless @choices[@choice].nil? + #puts "#{inspect[0,5]} 1RETURNING #{@previous[-1].inspect[0,5]}" + return @previous.pop + elsif @events[@current].kind_of? State + @current += 1 + #puts "#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}" + @events[@current-1].previous = self + return @events[@current-1] + else + #puts "#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}" + return self + end + else + return nil + end + end + + def matches?( event ) + return @events[@current].matches?( event ) if @events[@current] + !@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil? + end + + def expected + #puts "IN CHOICE EXPECTED" + #puts "EVENTS = #{@events.inspect}" + return [@events[@current]] if @events[@current] + return @choices[@choice..-1].collect do |x| + if x[0].kind_of? State + x[0].expected + else + x[0] + end + end.flatten + end + + def inspect + "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >" + end + end + + class Ref + def initialize value + @value = value + end + def to_s + @value + end + def inspect + "{#{to_s}}" + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/validation.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/validation.rb new file mode 100644 index 00000000..160ea96b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/validation.rb @@ -0,0 +1,155 @@ +require 'rexml/validation/validationexception' + +module REXML + module Validation + module Validator + NILEVENT = [ nil ] + def reset + @current = @root + @root.reset + @root.previous = true + @attr_stack = [] + self + end + def dump + puts @root.inspect + end + def validate( event ) + #puts "Current: #@current" + #puts "Event: #{event.inspect}" + @attr_stack = [] unless defined? @attr_stack + match = @current.next(event) + raise ValidationException.new( "Validation error. Expected: "+ + @current.expected.join( " or " )+" from #{@current.inspect} "+ + " but got #{Event.new( event[0], event[1] ).inspect}" ) unless match + @current = match + + # Check for attributes + case event[0] + when :start_element + #puts "Checking attributes" + @attr_stack << event[2] + begin + sattr = [:start_attribute, nil] + eattr = [:end_attribute] + text = [:text, nil] + k,v = event[2].find { |k,v| + sattr[1] = k + #puts "Looking for #{sattr.inspect}" + m = @current.next( sattr ) + #puts "Got #{m.inspect}" + if m + # If the state has text children... + #puts "Looking for #{eattr.inspect}" + #puts "Expect #{m.expected}" + if m.matches?( eattr ) + #puts "Got end" + @current = m + else + #puts "Didn't get end" + text[1] = v + #puts "Looking for #{text.inspect}" + m = m.next( text ) + #puts "Got #{m.inspect}" + text[1] = nil + return false unless m + @current = m if m + end + m = @current.next( eattr ) + if m + @current = m + true + else + false + end + else + false + end + } + event[2].delete(k) if k + end while k + when :end_element + attrs = @attr_stack.pop + raise ValidationException.new( "Validation error. Illegal "+ + " attributes: #{attrs.inspect}") if attrs.length > 0 + end + end + end + + class Event + def initialize(event_type, event_arg=nil ) + @event_type = event_type + @event_arg = event_arg + end + + attr_reader :event_type + attr_accessor :event_arg + + def done? + @done + end + + def single? + return (@event_type != :start_element and @event_type != :start_attribute) + end + + def matches?( event ) + #puts "#@event_type =? #{event[0]} && #@event_arg =? #{event[1]} " + return false unless event[0] == @event_type + case event[0] + when nil + return true + when :start_element + return true if event[1] == @event_arg + when :end_element + return true + when :start_attribute + return true if event[1] == @event_arg + when :end_attribute + return true + when :end_document + return true + when :text + return (@event_arg.nil? or @event_arg == event[1]) +=begin + when :processing_instruction + false + when :xmldecl + false + when :start_doctype + false + when :end_doctype + false + when :externalentity + false + when :elementdecl + false + when :entity + false + when :attlistdecl + false + when :notationdecl + false + when :end_doctype + false +=end + else + false + end + end + + def ==( other ) + return false unless other.kind_of? Event + @event_type == other.event_type and @event_arg == other.event_arg + end + + def to_s + inspect + end + + def inspect + "#{@event_type.inspect}( #@event_arg )" + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/validationexception.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/validationexception.rb new file mode 100644 index 00000000..4723d9e4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/validation/validationexception.rb @@ -0,0 +1,9 @@ +module REXML + module Validation + class ValidationException < RuntimeError + def initialize msg + super + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xmldecl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xmldecl.rb new file mode 100644 index 00000000..427eb78c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xmldecl.rb @@ -0,0 +1,119 @@ +require 'rexml/encoding' +require 'rexml/source' + +module REXML + # NEEDS DOCUMENTATION + class XMLDecl < Child + include Encoding + + DEFAULT_VERSION = "1.0"; + DEFAULT_ENCODING = "UTF-8"; + DEFAULT_STANDALONE = "no"; + START = '<\?xml'; + STOP = '\?>'; + + attr_accessor :version, :standalone + attr_reader :writeencoding, :writethis + + def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil) + @writethis = true + @writeencoding = !encoding.nil? + if version.kind_of? XMLDecl + super() + @version = version.version + self.encoding = version.encoding + @writeencoding = version.writeencoding + @standalone = version.standalone + else + super() + @version = version + self.encoding = encoding + @standalone = standalone + end + @version = DEFAULT_VERSION if @version.nil? + end + + def clone + XMLDecl.new(self) + end + + # indent:: + # Ignored. There must be no whitespace before an XML declaration + # transitive:: + # Ignored + # ie_hack:: + # Ignored + def write(writer, indent=-1, transitive=false, ie_hack=false) + return nil unless @writethis or writer.kind_of? Output + writer << START.sub(/\\/u, '') + if writer.kind_of? Output + writer << " #{content writer.encoding}" + else + writer << " #{content encoding}" + end + writer << STOP.sub(/\\/u, '') + end + + def ==( other ) + other.kind_of?(XMLDecl) and + other.version == @version and + other.encoding == self.encoding and + other.standalone == @standalone + end + + def xmldecl version, encoding, standalone + @version = version + self.encoding = encoding + @standalone = standalone + end + + def node_type + :xmldecl + end + + alias :stand_alone? :standalone + alias :old_enc= :encoding= + + def encoding=( enc ) + if enc.nil? + self.old_enc = "UTF-8" + @writeencoding = false + else + self.old_enc = enc + @writeencoding = true + end + self.dowrite + end + + # Only use this if you do not want the XML declaration to be written; + # this object is ignored by the XML writer. Otherwise, instantiate your + # own XMLDecl and add it to the document. + # + # Note that XML 1.1 documents *must* include an XML declaration + def XMLDecl.default + rv = XMLDecl.new( "1.0" ) + rv.nowrite + rv + end + + def nowrite + @writethis = false + end + + def dowrite + @writethis = true + end + + def inspect + START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '') + end + + private + def content(enc) + rv = "version='#@version'" + rv << " encoding='#{enc}'" if @writeencoding || enc !~ /utf-8/i + rv << " standalone='#@standalone'" if @standalone + rv + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xmltokens.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xmltokens.rb new file mode 100644 index 00000000..6bbe5b07 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xmltokens.rb @@ -0,0 +1,18 @@ +module REXML + # Defines a number of tokens used for parsing XML. Not for general + # consumption. + module XMLTokens + NCNAME_STR= '[\w:][\-\w\d.]*' + NAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}" + + NAMECHAR = '[\-\w\d\.:]' + NAME = "([\\w:]#{NAMECHAR}*)" + NMTOKEN = "(?:#{NAMECHAR})+" + NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*" + REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)" + + #REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})" + #ENTITYREF = "&#{NAME};" + #CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;" + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xpath.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xpath.rb new file mode 100644 index 00000000..939399e2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xpath.rb @@ -0,0 +1,66 @@ +require 'rexml/functions' +require 'rexml/xpath_parser' + +module REXML + # Wrapper class. Use this class to access the XPath functions. + class XPath + include Functions + EMPTY_HASH = {} + + # Finds and returns the first node that matches the supplied xpath. + # element:: + # The context element + # path:: + # The xpath to search for. If not supplied or nil, returns the first + # node matching '*'. + # namespaces:: + # If supplied, a Hash which defines a namespace mapping. + # + # XPath.first( node ) + # XPath.first( doc, "//b"} ) + # XPath.first( node, "a/x:b", { "x"=>"http://doofus" } ) + def XPath::first element, path=nil, namespaces=nil, variables={} + raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash) + raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash) + parser = XPathParser.new + parser.namespaces = namespaces + parser.variables = variables + path = "*" unless path + element = [element] unless element.kind_of? Array + parser.parse(path, element).flatten[0] + end + + # Itterates over nodes that match the given path, calling the supplied + # block with the match. + # element:: + # The context element + # path:: + # The xpath to search for. If not supplied or nil, defaults to '*' + # namespaces:: + # If supplied, a Hash which defines a namespace mapping + # + # XPath.each( node ) { |el| ... } + # XPath.each( node, '/*[@attr='v']' ) { |el| ... } + # XPath.each( node, 'ancestor::x' ) { |el| ... } + def XPath::each element, path=nil, namespaces=nil, variables={}, &block + raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash) + raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash) + parser = XPathParser.new + parser.namespaces = namespaces + parser.variables = variables + path = "*" unless path + element = [element] unless element.kind_of? Array + parser.parse(path, element).each( &block ) + end + + # Returns an array of nodes matching a given XPath. + def XPath::match element, path=nil, namespaces=nil, variables={} + parser = XPathParser.new + parser.namespaces = namespaces + parser.variables = variables + path = "*" unless path + element = [element] unless element.kind_of? Array + parser.parse(path,element) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xpath_parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xpath_parser.rb new file mode 100644 index 00000000..eb608fdb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rexml/xpath_parser.rb @@ -0,0 +1,792 @@ +require 'rexml/namespace' +require 'rexml/xmltokens' +require 'rexml/attribute' +require 'rexml/syncenumerator' +require 'rexml/parsers/xpathparser' + +class Object + def dclone + clone + end +end +class Symbol + def dclone ; self ; end +end +class Fixnum + def dclone ; self ; end +end +class Float + def dclone ; self ; end +end +class Array + def dclone + klone = self.clone + klone.clear + self.each{|v| klone << v.dclone} + klone + end +end + +module REXML + # You don't want to use this class. Really. Use XPath, which is a wrapper + # for this class. Believe me. You don't want to poke around in here. + # There is strange, dark magic at work in this code. Beware. Go back! Go + # back while you still can! + class XPathParser + include XMLTokens + LITERAL = /^'([^']*)'|^"([^"]*)"/u + + def initialize( ) + @parser = REXML::Parsers::XPathParser.new + @namespaces = nil + @variables = {} + end + + def namespaces=( namespaces={} ) + Functions::namespace_context = namespaces + @namespaces = namespaces + end + + def variables=( vars={} ) + Functions::variables = vars + @variables = vars + end + + def parse path, nodeset + #puts "#"*40 + path_stack = @parser.parse( path ) + #puts "PARSE: #{path} => #{path_stack.inspect}" + #puts "PARSE: nodeset = #{nodeset.inspect}" + match( path_stack, nodeset ) + end + + def get_first path, nodeset + #puts "#"*40 + path_stack = @parser.parse( path ) + #puts "PARSE: #{path} => #{path_stack.inspect}" + #puts "PARSE: nodeset = #{nodeset.inspect}" + first( path_stack, nodeset ) + end + + def predicate path, nodeset + path_stack = @parser.parse( path ) + expr( path_stack, nodeset ) + end + + def []=( variable_name, value ) + @variables[ variable_name ] = value + end + + + # Performs a depth-first (document order) XPath search, and returns the + # first match. This is the fastest, lightest way to return a single result. + # + # FIXME: This method is incomplete! + def first( path_stack, node ) + #puts "#{depth}) Entering match( #{path.inspect}, #{tree.inspect} )" + return nil if path.size == 0 + + case path[0] + when :document + # do nothing + return first( path[1..-1], node ) + when :child + for c in node.children + #puts "#{depth}) CHILD checking #{name(c)}" + r = first( path[1..-1], c ) + #puts "#{depth}) RETURNING #{r.inspect}" if r + return r if r + end + when :qname + name = path[2] + #puts "#{depth}) QNAME #{name(tree)} == #{name} (path => #{path.size})" + if node.name == name + #puts "#{depth}) RETURNING #{tree.inspect}" if path.size == 3 + return node if path.size == 3 + return first( path[3..-1], node ) + else + return nil + end + when :descendant_or_self + r = first( path[1..-1], node ) + return r if r + for c in node.children + r = first( path, c ) + return r if r + end + when :node + return first( path[1..-1], node ) + when :any + return first( path[1..-1], node ) + end + return nil + end + + + def match( path_stack, nodeset ) + #puts "MATCH: path_stack = #{path_stack.inspect}" + #puts "MATCH: nodeset = #{nodeset.inspect}" + r = expr( path_stack, nodeset ) + #puts "MAIN EXPR => #{r.inspect}" + r + end + + private + + + # Returns a String namespace for a node, given a prefix + # The rules are: + # + # 1. Use the supplied namespace mapping first. + # 2. If no mapping was supplied, use the context node to look up the namespace + def get_namespace( node, prefix ) + if @namespaces + return @namespaces[prefix] || '' + else + return node.namespace( prefix ) if node.node_type == :element + return '' + end + end + + + # Expr takes a stack of path elements and a set of nodes (either a Parent + # or an Array and returns an Array of matching nodes + ALL = [ :attribute, :element, :text, :processing_instruction, :comment ] + ELEMENTS = [ :element ] + def expr( path_stack, nodeset, context=nil ) + #puts "#"*15 + #puts "In expr with #{path_stack.inspect}" + #puts "Returning" if path_stack.length == 0 || nodeset.length == 0 + node_types = ELEMENTS + return nodeset if path_stack.length == 0 || nodeset.length == 0 + while path_stack.length > 0 + #puts "#"*5 + #puts "Path stack = #{path_stack.inspect}" + #puts "Nodeset is #{nodeset.inspect}" + if nodeset.length == 0 + path_stack.clear + return [] + end + case (op = path_stack.shift) + when :document + nodeset = [ nodeset[0].root_node ] + #puts ":document, nodeset = #{nodeset.inspect}" + + when :qname + #puts "IN QNAME" + prefix = path_stack.shift + name = path_stack.shift + nodeset.delete_if do |node| + # FIXME: This DOUBLES the time XPath searches take + ns = get_namespace( node, prefix ) + #puts "NS = #{ns.inspect}" + #puts "node.node_type == :element => #{node.node_type == :element}" + if node.node_type == :element + #puts "node.name == #{name} => #{node.name == name}" + if node.name == name + #puts "node.namespace == #{ns.inspect} => #{node.namespace == ns}" + end + end + !(node.node_type == :element and + node.name == name and + node.namespace == ns ) + end + node_types = ELEMENTS + + when :any + #puts "ANY 1: nodeset = #{nodeset.inspect}" + #puts "ANY 1: node_types = #{node_types.inspect}" + nodeset.delete_if { |node| !node_types.include?(node.node_type) } + #puts "ANY 2: nodeset = #{nodeset.inspect}" + + when :self + # This space left intentionally blank + + when :processing_instruction + target = path_stack.shift + nodeset.delete_if do |node| + (node.node_type != :processing_instruction) or + ( target!='' and ( node.target != target ) ) + end + + when :text + nodeset.delete_if { |node| node.node_type != :text } + + when :comment + nodeset.delete_if { |node| node.node_type != :comment } + + when :node + # This space left intentionally blank + node_types = ALL + + when :child + new_nodeset = [] + nt = nil + for node in nodeset + nt = node.node_type + new_nodeset += node.children if nt == :element or nt == :document + end + nodeset = new_nodeset + node_types = ELEMENTS + + when :literal + return path_stack.shift + + when :attribute + new_nodeset = [] + case path_stack.shift + when :qname + prefix = path_stack.shift + name = path_stack.shift + for element in nodeset + if element.node_type == :element + #puts "Element name = #{element.name}" + #puts "get_namespace( #{element.inspect}, #{prefix} ) = #{get_namespace(element, prefix)}" + attrib = element.attribute( name, get_namespace(element, prefix) ) + #puts "attrib = #{attrib.inspect}" + new_nodeset << attrib if attrib + end + end + when :any + #puts "ANY" + for element in nodeset + if element.node_type == :element + new_nodeset += element.attributes.to_a + end + end + end + nodeset = new_nodeset + + when :parent + #puts "PARENT 1: nodeset = #{nodeset}" + nodeset = nodeset.collect{|n| n.parent}.compact + #nodeset = expr(path_stack.dclone, nodeset.collect{|n| n.parent}.compact) + #puts "PARENT 2: nodeset = #{nodeset.inspect}" + node_types = ELEMENTS + + when :ancestor + new_nodeset = [] + for node in nodeset + while node.parent + node = node.parent + new_nodeset << node unless new_nodeset.include? node + end + end + nodeset = new_nodeset + node_types = ELEMENTS + + when :ancestor_or_self + new_nodeset = [] + for node in nodeset + if node.node_type == :element + new_nodeset << node + while ( node.parent ) + node = node.parent + new_nodeset << node unless new_nodeset.include? node + end + end + end + nodeset = new_nodeset + node_types = ELEMENTS + + when :predicate + new_nodeset = [] + subcontext = { :size => nodeset.size } + pred = path_stack.shift + nodeset.each_with_index { |node, index| + subcontext[ :node ] = node + #puts "PREDICATE SETTING CONTEXT INDEX TO #{index+1}" + subcontext[ :index ] = index+1 + pc = pred.dclone + #puts "#{node.hash}) Recursing with #{pred.inspect} and [#{node.inspect}]" + result = expr( pc, [node], subcontext ) + result = result[0] if result.kind_of? Array and result.length == 1 + #puts "#{node.hash}) Result = #{result.inspect} (#{result.class.name})" + if result.kind_of? Numeric + #puts "Adding node #{node.inspect}" if result == (index+1) + new_nodeset << node if result == (index+1) + elsif result.instance_of? Array + if result.size > 0 and result.inject(false) {|k,s| s or k} + #puts "Adding node #{node.inspect}" if result.size > 0 + new_nodeset << node if result.size > 0 + end + else + #puts "Adding node #{node.inspect}" if result + new_nodeset << node if result + end + } + #puts "New nodeset = #{new_nodeset.inspect}" + #puts "Path_stack = #{path_stack.inspect}" + nodeset = new_nodeset +=begin + predicate = path_stack.shift + ns = nodeset.clone + result = expr( predicate, ns ) + #puts "Result = #{result.inspect} (#{result.class.name})" + #puts "nodeset = #{nodeset.inspect}" + if result.kind_of? Array + nodeset = result.zip(ns).collect{|m,n| n if m}.compact + else + nodeset = result ? nodeset : [] + end + #puts "Outgoing NS = #{nodeset.inspect}" +=end + + when :descendant_or_self + rv = descendant_or_self( path_stack, nodeset ) + path_stack.clear + nodeset = rv + node_types = ELEMENTS + + when :descendant + results = [] + nt = nil + for node in nodeset + nt = node.node_type + results += expr( path_stack.dclone.unshift( :descendant_or_self ), + node.children ) if nt == :element or nt == :document + end + nodeset = results + node_types = ELEMENTS + + when :following_sibling + #puts "FOLLOWING_SIBLING 1: nodeset = #{nodeset}" + results = [] + nodeset.each do |node| + next if node.parent.nil? + all_siblings = node.parent.children + current_index = all_siblings.index( node ) + following_siblings = all_siblings[ current_index+1 .. -1 ] + results += expr( path_stack.dclone, following_siblings ) + end + #puts "FOLLOWING_SIBLING 2: nodeset = #{nodeset}" + nodeset = results + + when :preceding_sibling + results = [] + nodeset.each do |node| + next if node.parent.nil? + all_siblings = node.parent.children + current_index = all_siblings.index( node ) + preceding_siblings = all_siblings[ 0, current_index ].reverse + results += preceding_siblings + end + nodeset = results + node_types = ELEMENTS + + when :preceding + new_nodeset = [] + for node in nodeset + new_nodeset += preceding( node ) + end + #puts "NEW NODESET => #{new_nodeset.inspect}" + nodeset = new_nodeset + node_types = ELEMENTS + + when :following + new_nodeset = [] + for node in nodeset + new_nodeset += following( node ) + end + nodeset = new_nodeset + node_types = ELEMENTS + + when :namespace + #puts "In :namespace" + new_nodeset = [] + prefix = path_stack.shift + for node in nodeset + if (node.node_type == :element or node.node_type == :attribute) + if @namespaces + namespaces = @namespaces + elsif (node.node_type == :element) + namespaces = node.namespaces + else + namespaces = node.element.namesapces + end + #puts "Namespaces = #{namespaces.inspect}" + #puts "Prefix = #{prefix.inspect}" + #puts "Node.namespace = #{node.namespace}" + if (node.namespace == namespaces[prefix]) + new_nodeset << node + end + end + end + nodeset = new_nodeset + + when :variable + var_name = path_stack.shift + return @variables[ var_name ] + + # :and, :or, :eq, :neq, :lt, :lteq, :gt, :gteq + # TODO: Special case for :or and :and -- not evaluate the right + # operand if the left alone determines result (i.e. is true for + # :or and false for :and). + when :eq, :neq, :lt, :lteq, :gt, :gteq, :and, :or + left = expr( path_stack.shift, nodeset.dup, context ) + #puts "LEFT => #{left.inspect} (#{left.class.name})" + right = expr( path_stack.shift, nodeset.dup, context ) + #puts "RIGHT => #{right.inspect} (#{right.class.name})" + res = equality_relational_compare( left, op, right ) + #puts "RES => #{res.inspect}" + return res + + when :and + left = expr( path_stack.shift, nodeset.dup, context ) + #puts "LEFT => #{left.inspect} (#{left.class.name})" + if left == false || left.nil? || !left.inject(false) {|a,b| a | b} + return [] + end + right = expr( path_stack.shift, nodeset.dup, context ) + #puts "RIGHT => #{right.inspect} (#{right.class.name})" + res = equality_relational_compare( left, op, right ) + #puts "RES => #{res.inspect}" + return res + + when :div + left = Functions::number(expr(path_stack.shift, nodeset, context)).to_f + right = Functions::number(expr(path_stack.shift, nodeset, context)).to_f + return (left / right) + + when :mod + left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + return (left % right) + + when :mult + left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + return (left * right) + + when :plus + left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + return (left + right) + + when :minus + left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f + return (left - right) + + when :union + left = expr( path_stack.shift, nodeset, context ) + right = expr( path_stack.shift, nodeset, context ) + return (left | right) + + when :neg + res = expr( path_stack, nodeset, context ) + return -(res.to_f) + + when :not + when :function + func_name = path_stack.shift.tr('-','_') + arguments = path_stack.shift + #puts "FUNCTION 0: #{func_name}(#{arguments.collect{|a|a.inspect}.join(', ')})" + subcontext = context ? nil : { :size => nodeset.size } + + res = [] + cont = context + nodeset.each_with_index { |n, i| + if subcontext + subcontext[:node] = n + subcontext[:index] = i + cont = subcontext + end + arg_clone = arguments.dclone + args = arg_clone.collect { |arg| + #puts "FUNCTION 1: Calling expr( #{arg.inspect}, [#{n.inspect}] )" + expr( arg, [n], cont ) + } + #puts "FUNCTION 2: #{func_name}(#{args.collect{|a|a.inspect}.join(', ')})" + Functions.context = cont + res << Functions.send( func_name, *args ) + #puts "FUNCTION 3: #{res[-1].inspect}" + } + return res + + end + end # while + #puts "EXPR returning #{nodeset.inspect}" + return nodeset + end + + + ########################################################## + # FIXME + # The next two methods are BAD MOJO! + # This is my achilles heel. If anybody thinks of a better + # way of doing this, be my guest. This really sucks, but + # it is a wonder it works at all. + # ######################################################## + + def descendant_or_self( path_stack, nodeset ) + rs = [] + #puts "#"*80 + #puts "PATH_STACK = #{path_stack.inspect}" + #puts "NODESET = #{nodeset.collect{|n|n.inspect}.inspect}" + d_o_s( path_stack, nodeset, rs ) + #puts "RS = #{rs.collect{|n|n.inspect}.inspect}" + document_order(rs.flatten.compact) + #rs.flatten.compact + end + + def d_o_s( p, ns, r ) + #puts "IN DOS with #{ns.inspect}; ALREADY HAVE #{r.inspect}" + nt = nil + ns.each_index do |i| + n = ns[i] + #puts "P => #{p.inspect}" + x = expr( p.dclone, [ n ] ) + nt = n.node_type + d_o_s( p, n.children, x ) if nt == :element or nt == :document and n.children.size > 0 + r.concat(x) if x.size > 0 + end + end + + + # Reorders an array of nodes so that they are in document order + # It tries to do this efficiently. + # + # FIXME: I need to get rid of this, but the issue is that most of the XPath + # interpreter functions as a filter, which means that we lose context going + # in and out of function calls. If I knew what the index of the nodes was, + # I wouldn't have to do this. Maybe add a document IDX for each node? + # Problems with mutable documents. Or, rewrite everything. + def document_order( array_of_nodes ) + new_arry = [] + array_of_nodes.each { |node| + node_idx = [] + np = node.node_type == :attribute ? node.element : node + while np.parent and np.parent.node_type == :element + node_idx << np.parent.index( np ) + np = np.parent + end + new_arry << [ node_idx.reverse, node ] + } + #puts "new_arry = #{new_arry.inspect}" + new_arry.sort{ |s1, s2| s1[0] <=> s2[0] }.collect{ |s| s[1] } + end + + + def recurse( nodeset, &block ) + for node in nodeset + yield node + recurse( node, &block ) if node.node_type == :element + end + end + + + + # Builds a nodeset of all of the preceding nodes of the supplied node, + # in reverse document order + # preceding:: includes every element in the document that precedes this node, + # except for ancestors + def preceding( node ) + #puts "IN PRECEDING" + ancestors = [] + p = node.parent + while p + ancestors << p + p = p.parent + end + + acc = [] + p = preceding_node_of( node ) + #puts "P = #{p.inspect}" + while p + if ancestors.include? p + ancestors.delete(p) + else + acc << p + end + p = preceding_node_of( p ) + #puts "P = #{p.inspect}" + end + acc + end + + def preceding_node_of( node ) + #puts "NODE: #{node.inspect}" + #puts "PREVIOUS NODE: #{node.previous_sibling_node.inspect}" + #puts "PARENT NODE: #{node.parent}" + psn = node.previous_sibling_node + if psn.nil? + if node.parent.nil? or node.parent.class == Document + return nil + end + return node.parent + #psn = preceding_node_of( node.parent ) + end + while psn and psn.kind_of? Element and psn.children.size > 0 + psn = psn.children[-1] + end + psn + end + + def following( node ) + #puts "IN PRECEDING" + acc = [] + p = next_sibling_node( node ) + #puts "P = #{p.inspect}" + while p + acc << p + p = following_node_of( p ) + #puts "P = #{p.inspect}" + end + acc + end + + def following_node_of( node ) + #puts "NODE: #{node.inspect}" + #puts "PREVIOUS NODE: #{node.previous_sibling_node.inspect}" + #puts "PARENT NODE: #{node.parent}" + if node.kind_of? Element and node.children.size > 0 + return node.children[0] + end + return next_sibling_node(node) + end + + def next_sibling_node(node) + psn = node.next_sibling_node + while psn.nil? + if node.parent.nil? or node.parent.class == Document + return nil + end + node = node.parent + psn = node.next_sibling_node + #puts "psn = #{psn.inspect}" + end + return psn + end + + def norm b + case b + when true, false + return b + when 'true', 'false' + return Functions::boolean( b ) + when /^\d+(\.\d+)?$/ + return Functions::number( b ) + else + return Functions::string( b ) + end + end + + def equality_relational_compare( set1, op, set2 ) + #puts "EQ_REL_COMP(#{set1.inspect} #{op.inspect} #{set2.inspect})" + if set1.kind_of? Array and set2.kind_of? Array + #puts "#{set1.size} & #{set2.size}" + if set1.size == 1 and set2.size == 1 + set1 = set1[0] + set2 = set2[0] + elsif set1.size == 0 or set2.size == 0 + nd = set1.size==0 ? set2 : set1 + rv = nd.collect { |il| compare( il, op, nil ) } + #puts "RV = #{rv.inspect}" + return rv + else + res = [] + enum = SyncEnumerator.new( set1, set2 ).each { |i1, i2| + #puts "i1 = #{i1.inspect} (#{i1.class.name})" + #puts "i2 = #{i2.inspect} (#{i2.class.name})" + i1 = norm( i1 ) + i2 = norm( i2 ) + res << compare( i1, op, i2 ) + } + return res + end + end + #puts "EQ_REL_COMP: #{set1.inspect} (#{set1.class.name}), #{op}, #{set2.inspect} (#{set2.class.name})" + #puts "COMPARING VALUES" + # If one is nodeset and other is number, compare number to each item + # in nodeset s.t. number op number(string(item)) + # If one is nodeset and other is string, compare string to each item + # in nodeset s.t. string op string(item) + # If one is nodeset and other is boolean, compare boolean to each item + # in nodeset s.t. boolean op boolean(item) + if set1.kind_of? Array or set2.kind_of? Array + #puts "ISA ARRAY" + if set1.kind_of? Array + a = set1 + b = set2 + else + a = set2 + b = set1 + end + + case b + when true, false + return a.collect {|v| compare( Functions::boolean(v), op, b ) } + when Numeric + return a.collect {|v| compare( Functions::number(v), op, b )} + when /^\d+(\.\d+)?$/ + b = Functions::number( b ) + #puts "B = #{b.inspect}" + return a.collect {|v| compare( Functions::number(v), op, b )} + else + #puts "Functions::string( #{b}(#{b.class.name}) ) = #{Functions::string(b)}" + b = Functions::string( b ) + return a.collect { |v| compare( Functions::string(v), op, b ) } + end + else + # If neither is nodeset, + # If op is = or != + # If either boolean, convert to boolean + # If either number, convert to number + # Else, convert to string + # Else + # Convert both to numbers and compare + s1 = set1.to_s + s2 = set2.to_s + #puts "EQ_REL_COMP: #{set1}=>#{s1}, #{set2}=>#{s2}" + if s1 == 'true' or s1 == 'false' or s2 == 'true' or s2 == 'false' + #puts "Functions::boolean(#{set1})=>#{Functions::boolean(set1)}" + #puts "Functions::boolean(#{set2})=>#{Functions::boolean(set2)}" + set1 = Functions::boolean( set1 ) + set2 = Functions::boolean( set2 ) + else + if op == :eq or op == :neq + if s1 =~ /^\d+(\.\d+)?$/ or s2 =~ /^\d+(\.\d+)?$/ + set1 = Functions::number( s1 ) + set2 = Functions::number( s2 ) + else + set1 = Functions::string( set1 ) + set2 = Functions::string( set2 ) + end + else + set1 = Functions::number( set1 ) + set2 = Functions::number( set2 ) + end + end + #puts "EQ_REL_COMP: #{set1} #{op} #{set2}" + #puts ">>> #{compare( set1, op, set2 )}" + return compare( set1, op, set2 ) + end + return false + end + + def compare a, op, b + #puts "COMPARE #{a.inspect}(#{a.class.name}) #{op} #{b.inspect}(#{b.class.name})" + case op + when :eq + a == b + when :neq + a != b + when :lt + a < b + when :lteq + a <= b + when :gt + a > b + when :gteq + a >= b + when :and + a and b + when :or + a or b + else + false + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/rinda.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/rinda.rb new file mode 100644 index 00000000..6c59e686 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/rinda.rb @@ -0,0 +1,283 @@ +require 'drb/drb' +require 'thread' + +## +# A module to implement the Linda distributed computing paradigm in Ruby. +# +# Rinda is part of DRb (dRuby). +# +# == Example(s) +# +# See the sample/drb/ directory in the Ruby distribution, from 1.8.2 onwards. +# +#-- +# TODO +# == Introduction to Linda/rinda? +# +# == Why is this library separate from DRb? + +module Rinda + + ## + # Rinda error base class + + class RindaError < RuntimeError; end + + ## + # Raised when a hash-based tuple has an invalid key. + + class InvalidHashTupleKey < RindaError; end + + ## + # Raised when trying to use a canceled tuple. + + class RequestCanceledError < ThreadError; end + + ## + # Raised when trying to use an expired tuple. + + class RequestExpiredError < ThreadError; end + + ## + # A tuple is the elementary object in Rinda programming. + # Tuples may be matched against templates if the tuple and + # the template are the same size. + + class Tuple + + ## + # Creates a new Tuple from +ary_or_hash+ which must be an Array or Hash. + + def initialize(ary_or_hash) + if hash?(ary_or_hash) + init_with_hash(ary_or_hash) + else + init_with_ary(ary_or_hash) + end + end + + ## + # The number of elements in the tuple. + + def size + @tuple.size + end + + ## + # Accessor method for elements of the tuple. + + def [](k) + @tuple[k] + end + + ## + # Fetches item +k+ from the tuple. + + def fetch(k) + @tuple.fetch(k) + end + + ## + # Iterate through the tuple, yielding the index or key, and the + # value, thus ensuring arrays are iterated similarly to hashes. + + def each # FIXME + if Hash === @tuple + @tuple.each { |k, v| yield(k, v) } + else + @tuple.each_with_index { |v, k| yield(k, v) } + end + end + + ## + # Return the tuple itself + def value + @tuple + end + + private + + def hash?(ary_or_hash) + ary_or_hash.respond_to?(:keys) + end + + ## + # Munges +ary+ into a valid Tuple. + + def init_with_ary(ary) + @tuple = Array.new(ary.size) + @tuple.size.times do |i| + @tuple[i] = ary[i] + end + end + + ## + # Ensures +hash+ is a valid Tuple. + + def init_with_hash(hash) + @tuple = Hash.new + hash.each do |k, v| + raise InvalidHashTupleKey unless String === k + @tuple[k] = v + end + end + + end + + ## + # Templates are used to match tuples in Rinda. + + class Template < Tuple + + ## + # Matches this template against +tuple+. The +tuple+ must be the same + # size as the template. An element with a +nil+ value in a template acts + # as a wildcard, matching any value in the corresponding position in the + # tuple. Elements of the template match the +tuple+ if the are #== or + # #===. + # + # Template.new([:foo, 5]).match Tuple.new([:foo, 5]) # => true + # Template.new([:foo, nil]).match Tuple.new([:foo, 5]) # => true + # Template.new([String]).match Tuple.new(['hello']) # => true + # + # Template.new([:foo]).match Tuple.new([:foo, 5]) # => false + # Template.new([:foo, 6]).match Tuple.new([:foo, 5]) # => false + # Template.new([:foo, nil]).match Tuple.new([:foo]) # => false + # Template.new([:foo, 6]).match Tuple.new([:foo]) # => false + + def match(tuple) + return false unless tuple.respond_to?(:size) + return false unless tuple.respond_to?(:fetch) + return false unless self.size == tuple.size + each do |k, v| + begin + it = tuple.fetch(k) + rescue + return false + end + next if v.nil? + next if v == it + next if v === it + return false + end + return true + end + + ## + # Alias for #match. + + def ===(tuple) + match(tuple) + end + + end + + ## + # Documentation? + + class DRbObjectTemplate + + ## + # Creates a new DRbObjectTemplate that will match against +uri+ and +ref+. + + def initialize(uri=nil, ref=nil) + @drb_uri = uri + @drb_ref = ref + end + + ## + # This DRbObjectTemplate matches +ro+ if the remote object's drburi and + # drbref are the same. +nil+ is used as a wildcard. + + def ===(ro) + return true if super(ro) + unless @drb_uri.nil? + return false unless (@drb_uri === ro.__drburi rescue false) + end + unless @drb_ref.nil? + return false unless (@drb_ref === ro.__drbref rescue false) + end + true + end + + end + + ## + # TupleSpaceProxy allows a remote Tuplespace to appear as local. + + class TupleSpaceProxy + + ## + # Creates a new TupleSpaceProxy to wrap +ts+. + + def initialize(ts) + @ts = ts + end + + ## + # Adds +tuple+ to the proxied TupleSpace. See TupleSpace#write. + + def write(tuple, sec=nil) + @ts.write(tuple, sec) + end + + ## + # Takes +tuple+ from the proxied TupleSpace. See TupleSpace#take. + + def take(tuple, sec=nil, &block) + port = [] + @ts.move(DRbObject.new(port), tuple, sec, &block) + port[0] + end + + ## + # Reads +tuple+ from the proxied TupleSpace. See TupleSpace#read. + + def read(tuple, sec=nil, &block) + @ts.read(tuple, sec, &block) + end + + ## + # Reads all tuples matching +tuple+ from the proxied TupleSpace. See + # TupleSpace#read_all. + + def read_all(tuple) + @ts.read_all(tuple) + end + + ## + # Registers for notifications of event +ev+ on the proxied TupleSpace. + # See TupleSpace#notify + + def notify(ev, tuple, sec=nil) + @ts.notify(ev, tuple, sec) + end + + end + + ## + # An SimpleRenewer allows a TupleSpace to check if a TupleEntry is still + # alive. + + class SimpleRenewer + + include DRbUndumped + + ## + # Creates a new SimpleRenewer that keeps an object alive for another +sec+ + # seconds. + + def initialize(sec=180) + @sec = sec + end + + ## + # Called by the TupleSpace to check if the object is still alive. + + def renew + @sec + end + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/ring.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/ring.rb new file mode 100644 index 00000000..ac8a7162 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/ring.rb @@ -0,0 +1,271 @@ +# +# Note: Rinda::Ring API is unstable. +# +require 'drb/drb' +require 'rinda/rinda' +require 'thread' + +module Rinda + + ## + # The default port Ring discovery will use. + + Ring_PORT = 7647 + + ## + # A RingServer allows a Rinda::TupleSpace to be located via UDP broadcasts. + # Service location uses the following steps: + # + # 1. A RingServer begins listening on the broadcast UDP address. + # 2. A RingFinger sends a UDP packet containing the DRb URI where it will + # listen for a reply. + # 3. The RingServer recieves the UDP packet and connects back to the + # provided DRb URI with the DRb service. + + class RingServer + + include DRbUndumped + + ## + # Advertises +ts+ on the UDP broadcast address at +port+. + + def initialize(ts, port=Ring_PORT) + @ts = ts + @soc = UDPSocket.open + @soc.bind('', port) + @w_service = write_service + @r_service = reply_service + end + + ## + # Creates a thread that picks up UDP packets and passes them to do_write + # for decoding. + + def write_service + Thread.new do + loop do + msg = @soc.recv(1024) + do_write(msg) + end + end + end + + ## + # Extracts the response URI from +msg+ and adds it to TupleSpace where it + # will be picked up by +reply_service+ for notification. + + def do_write(msg) + Thread.new do + begin + tuple, sec = Marshal.load(msg) + @ts.write(tuple, sec) + rescue + end + end + end + + ## + # Creates a thread that notifies waiting clients from the TupleSpace. + + def reply_service + Thread.new do + loop do + do_reply + end + end + end + + ## + # Pulls lookup tuples out of the TupleSpace and sends their DRb object the + # address of the local TupleSpace. + + def do_reply + tuple = @ts.take([:lookup_ring, nil]) + Thread.new { tuple[1].call(@ts) rescue nil} + rescue + end + + end + + ## + # RingFinger is used by RingServer clients to discover the RingServer's + # TupleSpace. Typically, all a client needs to do is call + # RingFinger.primary to retrieve the remote TupleSpace, which it can then + # begin using. + + class RingFinger + + @@broadcast_list = ['', 'localhost'] + + @@finger = nil + + ## + # Creates a singleton RingFinger and looks for a RingServer. Returns the + # created RingFinger. + + def self.finger + unless @@finger + @@finger = self.new + @@finger.lookup_ring_any + end + @@finger + end + + ## + # Returns the first advertised TupleSpace. + + def self.primary + finger.primary + end + + ## + # Contains all discoverd TupleSpaces except for the primary. + + def self.to_a + finger.to_a + end + + ## + # The list of addresses where RingFinger will send query packets. + + attr_accessor :broadcast_list + + ## + # The port that RingFinger will send query packets to. + + attr_accessor :port + + ## + # Contain the first advertised TupleSpace after lookup_ring_any is called. + + attr_accessor :primary + + ## + # Creates a new RingFinger that will look for RingServers at +port+ on + # the addresses in +broadcast_list+. + + def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT) + @broadcast_list = broadcast_list || ['localhost'] + @port = port + @primary = nil + @rings = [] + end + + ## + # Contains all discovered TupleSpaces except for the primary. + + def to_a + @rings + end + + ## + # Iterates over all discovered TupleSpaces starting with the primary. + + def each + lookup_ring_any unless @primary + return unless @primary + yield(@primary) + @rings.each { |x| yield(x) } + end + + ## + # Looks up RingServers waiting +timeout+ seconds. RingServers will be + # given +block+ as a callback, which will be called with the remote + # TupleSpace. + + def lookup_ring(timeout=5, &block) + return lookup_ring_any(timeout) unless block_given? + + msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout]) + @broadcast_list.each do |it| + soc = UDPSocket.open + begin + soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true) + soc.send(msg, 0, it, @port) + rescue + nil + ensure + soc.close + end + end + sleep(timeout) + end + + ## + # Returns the first found remote TupleSpace. Any further recovered + # TupleSpaces can be found by calling +to_a+. + + def lookup_ring_any(timeout=5) + queue = Queue.new + + th = Thread.new do + self.lookup_ring(timeout) do |ts| + queue.push(ts) + end + queue.push(nil) + while it = queue.pop + @rings.push(it) + end + end + + @primary = queue.pop + raise('RingNotFound') if @primary.nil? + @primary + end + + end + + ## + # RingProvider uses a RingServer advertised TupleSpace as a name service. + # TupleSpace clients can register themselves with the remote TupleSpace and + # look up other provided services via the remote TupleSpace. + # + # Services are registered with a tuple of the format [:name, klass, + # DRbObject, description]. + + class RingProvider + + ## + # Creates a RingProvider that will provide a +klass+ service running on + # +front+, with a +description+. +renewer+ is optional. + + def initialize(klass, front, desc, renewer = nil) + @tuple = [:name, klass, front, desc] + @renewer = renewer || Rinda::SimpleRenewer.new + end + + ## + # Advertises this service on the primary remote TupleSpace. + + def provide + ts = Rinda::RingFinger.primary + ts.write(@tuple, @renewer) + end + + end + +end + +if __FILE__ == $0 + DRb.start_service + case ARGV.shift + when 's' + require 'rinda/tuplespace' + ts = Rinda::TupleSpace.new + place = Rinda::RingServer.new(ts) + $stdin.gets + when 'w' + finger = Rinda::RingFinger.new(nil) + finger.lookup_ring do |ts| + p ts + ts.write([:hello, :world]) + end + when 'r' + finger = Rinda::RingFinger.new(nil) + finger.lookup_ring do |ts| + p ts + p ts.take([nil, nil]) + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/tuplespace.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/tuplespace.rb new file mode 100644 index 00000000..6d58a0fd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rinda/tuplespace.rb @@ -0,0 +1,592 @@ +require 'monitor' +require 'thread' +require 'drb/drb' +require 'rinda/rinda' + +module Rinda + + ## + # A TupleEntry is a Tuple (i.e. a possible entry in some Tuplespace) + # together with expiry and cancellation data. + + class TupleEntry + + include DRbUndumped + + attr_accessor :expires + + ## + # Creates a TupleEntry based on +ary+ with an optional renewer or expiry + # time +sec+. + # + # A renewer must implement the +renew+ method which returns a Numeric, + # nil, or true to indicate when the tuple has expired. + + def initialize(ary, sec=nil) + @cancel = false + @expires = nil + @tuple = make_tuple(ary) + @renewer = nil + renew(sec) + end + + ## + # Marks this TupleEntry as canceled. + + def cancel + @cancel = true + end + + ## + # A TupleEntry is dead when it is canceled or expired. + + def alive? + !canceled? && !expired? + end + + ## + # Return the object which makes up the tuple itself: the Array + # or Hash. + + def value; @tuple.value; end + + ## + # Returns the canceled status. + + def canceled?; @cancel; end + + ## + # Has this tuple expired? (true/false). + # + # A tuple has expired when its expiry timer based on the +sec+ argument to + # #initialize runs out. + + def expired? + return true unless @expires + return false if @expires > Time.now + return true if @renewer.nil? + renew(@renewer) + return true unless @expires + return @expires < Time.now + end + + ## + # Reset the expiry time according to +sec_or_renewer+. + # + # +nil+:: it is set to expire in the far future. + # +false+:: it has expired. + # Numeric:: it will expire in that many seconds. + # + # Otherwise the argument refers to some kind of renewer object + # which will reset its expiry time. + + def renew(sec_or_renewer) + sec, @renewer = get_renewer(sec_or_renewer) + @expires = make_expires(sec) + end + + ## + # Returns an expiry Time based on +sec+ which can be one of: + # Numeric:: +sec+ seconds into the future + # +true+:: the expiry time is the start of 1970 (i.e. expired) + # +nil+:: it is Tue Jan 19 03:14:07 GMT Standard Time 2038 (i.e. when + # UNIX clocks will die) + + def make_expires(sec=nil) + case sec + when Numeric + Time.now + sec + when true + Time.at(1) + when nil + Time.at(2**31-1) + end + end + + ## + # Retrieves +key+ from the tuple. + + def [](key) + @tuple[key] + end + + ## + # Fetches +key+ from the tuple. + + def fetch(key) + @tuple.fetch(key) + end + + ## + # The size of the tuple. + + def size + @tuple.size + end + + ## + # Creates a Rinda::Tuple for +ary+. + + def make_tuple(ary) + Rinda::Tuple.new(ary) + end + + private + + ## + # Returns a valid argument to make_expires and the renewer or nil. + # + # Given +true+, +nil+, or Numeric, returns that value and +nil+ (no actual + # renewer). Otherwise it returns an expiry value from calling +it.renew+ + # and the renewer. + + def get_renewer(it) + case it + when Numeric, true, nil + return it, nil + else + begin + return it.renew, it + rescue Exception + return it, nil + end + end + end + + end + + ## + # A TemplateEntry is a Template together with expiry and cancellation data. + + class TemplateEntry < TupleEntry + ## + # Matches this TemplateEntry against +tuple+. See Template#match for + # details on how a Template matches a Tuple. + + def match(tuple) + @tuple.match(tuple) + end + + alias === match + + def make_tuple(ary) # :nodoc: + Rinda::Template.new(ary) + end + + end + + ## + # Documentation? + + class WaitTemplateEntry < TemplateEntry + + attr_reader :found + + def initialize(place, ary, expires=nil) + super(ary, expires) + @place = place + @cond = place.new_cond + @found = nil + end + + def cancel + super + signal + end + + def wait + @cond.wait + end + + def read(tuple) + @found = tuple + signal + end + + def signal + @place.synchronize do + @cond.signal + end + end + + end + + ## + # A NotifyTemplateEntry is returned by TupleSpace#notify and is notified of + # TupleSpace changes. You may receive either your subscribed event or the + # 'close' event when iterating over notifications. + # + # See TupleSpace#notify_event for valid notification types. + # + # == Example + # + # ts = Rinda::TupleSpace.new + # observer = ts.notify 'write', [nil] + # + # Thread.start do + # observer.each { |t| p t } + # end + # + # 3.times { |i| ts.write [i] } + # + # Outputs: + # + # ['write', [0]] + # ['write', [1]] + # ['write', [2]] + + class NotifyTemplateEntry < TemplateEntry + + ## + # Creates a new NotifyTemplateEntry that watches +place+ for +event+s that + # match +tuple+. + + def initialize(place, event, tuple, expires=nil) + ary = [event, Rinda::Template.new(tuple)] + super(ary, expires) + @queue = Queue.new + @done = false + end + + ## + # Called by TupleSpace to notify this NotifyTemplateEntry of a new event. + + def notify(ev) + @queue.push(ev) + end + + ## + # Retrieves a notification. Raises RequestExpiredError when this + # NotifyTemplateEntry expires. + + def pop + raise RequestExpiredError if @done + it = @queue.pop + @done = true if it[0] == 'close' + return it + end + + ## + # Yields event/tuple pairs until this NotifyTemplateEntry expires. + + def each # :yields: event, tuple + while !@done + it = pop + yield(it) + end + rescue + ensure + cancel + end + + end + + ## + # TupleBag is an unordered collection of tuples. It is the basis + # of Tuplespace. + + class TupleBag + + def initialize # :nodoc: + @hash = {} + end + + ## + # +true+ if the TupleBag to see if it has any expired entries. + + def has_expires? + @hash.each do |k, v| + v.each do |tuple| + return true if tuple.expires + end + end + false + end + + ## + # Add +ary+ to the TupleBag. + + def push(ary) + size = ary.size + @hash[size] ||= [] + @hash[size].push(ary) + end + + ## + # Removes +ary+ from the TupleBag. + + def delete(ary) + size = ary.size + @hash.fetch(size, []).delete(ary) + end + + ## + # Finds all live tuples that match +template+. + + def find_all(template) + @hash.fetch(template.size, []).find_all do |tuple| + tuple.alive? && template.match(tuple) + end + end + + ## + # Finds a live tuple that matches +template+. + + def find(template) + @hash.fetch(template.size, []).find do |tuple| + tuple.alive? && template.match(tuple) + end + end + + ## + # Finds all tuples in the TupleBag which when treated as templates, match + # +tuple+ and are alive. + + def find_all_template(tuple) + @hash.fetch(tuple.size, []).find_all do |template| + template.alive? && template.match(tuple) + end + end + + ## + # Delete tuples which dead tuples from the TupleBag, returning the deleted + # tuples. + + def delete_unless_alive + deleted = [] + @hash.keys.each do |size| + ary = [] + @hash[size].each do |tuple| + if tuple.alive? + ary.push(tuple) + else + deleted.push(tuple) + end + end + @hash[size] = ary + end + deleted + end + + end + + ## + # The Tuplespace manages access to the tuples it contains, + # ensuring mutual exclusion requirements are met. + # + # The +sec+ option for the write, take, move, read and notify methods may + # either be a number of seconds or a Renewer object. + + class TupleSpace + + include DRbUndumped + include MonitorMixin + + ## + # Creates a new TupleSpace. +period+ is used to control how often to look + # for dead tuples after modifications to the TupleSpace. + # + # If no dead tuples are found +period+ seconds after the last + # modification, the TupleSpace will stop looking for dead tuples. + + def initialize(period=60) + super() + @bag = TupleBag.new + @read_waiter = TupleBag.new + @take_waiter = TupleBag.new + @notify_waiter = TupleBag.new + @period = period + @keeper = nil + end + + ## + # Adds +tuple+ + + def write(tuple, sec=nil) + entry = TupleEntry.new(tuple, sec) + synchronize do + if entry.expired? + @read_waiter.find_all_template(entry).each do |template| + template.read(tuple) + end + notify_event('write', entry.value) + notify_event('delete', entry.value) + else + @bag.push(entry) + start_keeper if entry.expires + @read_waiter.find_all_template(entry).each do |template| + template.read(tuple) + end + @take_waiter.find_all_template(entry).each do |template| + template.signal + end + notify_event('write', entry.value) + end + end + entry + end + + ## + # Removes +tuple+ + + def take(tuple, sec=nil, &block) + move(nil, tuple, sec, &block) + end + + ## + # Moves +tuple+ to +port+. + + def move(port, tuple, sec=nil) + template = WaitTemplateEntry.new(self, tuple, sec) + yield(template) if block_given? + synchronize do + entry = @bag.find(template) + if entry + port.push(entry.value) if port + @bag.delete(entry) + notify_event('take', entry.value) + return entry.value + end + raise RequestExpiredError if template.expired? + + begin + @take_waiter.push(template) + start_keeper if template.expires + while true + raise RequestCanceledError if template.canceled? + raise RequestExpiredError if template.expired? + entry = @bag.find(template) + if entry + port.push(entry.value) if port + @bag.delete(entry) + notify_event('take', entry.value) + return entry.value + end + template.wait + end + ensure + @take_waiter.delete(template) + end + end + end + + ## + # Reads +tuple+, but does not remove it. + + def read(tuple, sec=nil) + template = WaitTemplateEntry.new(self, tuple, sec) + yield(template) if block_given? + synchronize do + entry = @bag.find(template) + return entry.value if entry + raise RequestExpiredError if template.expired? + + begin + @read_waiter.push(template) + start_keeper if template.expires + template.wait + raise RequestCanceledError if template.canceled? + raise RequestExpiredError if template.expired? + return template.found + ensure + @read_waiter.delete(template) + end + end + end + + ## + # Returns all tuples matching +tuple+. Does not remove the found tuples. + + def read_all(tuple) + template = WaitTemplateEntry.new(self, tuple, nil) + synchronize do + entry = @bag.find_all(template) + entry.collect do |e| + e.value + end + end + end + + ## + # Registers for notifications of +event+. Returns a NotifyTemplateEntry. + # See NotifyTemplateEntry for examples of how to listen for notifications. + # + # +event+ can be: + # 'write':: A tuple was added + # 'take':: A tuple was taken or moved + # 'delete':: A tuple was lost after being overwritten or expiring + # + # The TupleSpace will also notify you of the 'close' event when the + # NotifyTemplateEntry has expired. + + def notify(event, tuple, sec=nil) + template = NotifyTemplateEntry.new(self, event, tuple, sec) + synchronize do + @notify_waiter.push(template) + end + template + end + + private + + ## + # Removes dead tuples. + + def keep_clean + synchronize do + @read_waiter.delete_unless_alive.each do |e| + e.signal + end + @take_waiter.delete_unless_alive.each do |e| + e.signal + end + @notify_waiter.delete_unless_alive.each do |e| + e.notify(['close']) + end + @bag.delete_unless_alive.each do |e| + notify_event('delete', e.value) + end + end + end + + ## + # Notifies all registered listeners for +event+ of a status change of + # +tuple+. + + def notify_event(event, tuple) + ev = [event, tuple] + @notify_waiter.find_all_template(ev).each do |template| + template.notify(ev) + end + end + + ## + # Creates a thread that scans the tuplespace for expired tuples. + + def start_keeper + return if @keeper && @keeper.alive? + @keeper = Thread.new do + while true + synchronize do + break unless need_keeper? + keep_clean + end + sleep(@period) + end + end + end + + ## + # Checks the tuplespace to see if it needs cleaning. + + def need_keeper? + return true if @bag.has_expires? + return true if @read_waiter.has_expires? + return true if @take_waiter.has_expires? + return true if @notify_waiter.has_expires? + end + + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss.rb new file mode 100644 index 00000000..495edb1b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss.rb @@ -0,0 +1,16 @@ +# Copyright (c) 2003-2005 Kouhei Sutou. You can redistribute it and/or +# modify it under the same terms as Ruby. +# +# Author:: Kouhei Sutou +# Tutorial:: http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en + +require 'rss/1.0' +require 'rss/2.0' +require 'rss/content' +require 'rss/dublincore' +require 'rss/image' +require 'rss/syndication' +#require 'rss/taxonomy' +require 'rss/trackback' + +require "rss/maker" diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/0.9.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/0.9.rb new file mode 100644 index 00000000..69e01ddd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/0.9.rb @@ -0,0 +1,422 @@ +require "rss/parser" + +module RSS + + module RSS09 + NSPOOL = {} + ELEMENTS = [] + + def self.append_features(klass) + super + + klass.install_must_call_validator('', "") + end + end + + class Rss < Element + + include RSS09 + include RootElementMixin + + %w(channel).each do |name| + install_have_child_element(name, "", nil) + end + + attr_accessor :rss_version, :version, :encoding, :standalone + + def initialize(rss_version, version=nil, encoding=nil, standalone=nil) + super + end + + def items + if @channel + @channel.items + else + [] + end + end + + def image + if @channel + @channel.image + else + nil + end + end + + def textinput + if @channel + @channel.textInput + else + nil + end + end + + def setup_maker_elements(maker) + super + items.each do |item| + item.setup_maker(maker.items) + end + end + + private + def _attrs + [ + ["version", true, "rss_version"], + ] + end + + class Channel < Element + + include RSS09 + + [ + ["title", nil, :text], + ["link", nil, :text], + ["description", nil, :text], + ["language", nil, :text], + ["copyright", "?", :text], + ["managingEditor", "?", :text], + ["webMaster", "?", :text], + ["rating", "?", :text], + ["pubDate", "?", :date, :rfc822], + ["lastBuildDate", "?", :date, :rfc822], + ["docs", "?", :text], + ["cloud", "?", :have_attribute], + ["skipDays", "?", :have_child], + ["skipHours", "?", :have_child], + ["image", nil, :have_child], + ["item", "*", :have_children], + ["textInput", "?", :have_child], + ].each do |name, occurs, type, *args| + __send__("install_#{type}_element", name, "", occurs, name, *args) + end + alias date pubDate + alias date= pubDate= + + private + def maker_target(maker) + maker.channel + end + + def setup_maker_elements(channel) + super + [ + [skipDays, "day"], + [skipHours, "hour"], + ].each do |skip, key| + if skip + skip.__send__("#{key}s").each do |val| + target_skips = channel.__send__("skip#{key.capitalize}s") + new_target = target_skips.__send__("new_#{key}") + new_target.content = val.content + end + end + end + end + + def not_need_to_call_setup_maker_variables + %w(image textInput) + end + + class SkipDays < Element + include RSS09 + + [ + ["day", "*"] + ].each do |name, occurs| + install_have_children_element(name, "", occurs) + end + + class Day < Element + include RSS09 + + content_setup + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.content = args[0] + end + end + + end + + end + + class SkipHours < Element + include RSS09 + + [ + ["hour", "*"] + ].each do |name, occurs| + install_have_children_element(name, "", occurs) + end + + class Hour < Element + include RSS09 + + content_setup(:integer) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.content = args[0] + end + end + end + + end + + class Image < Element + + include RSS09 + + %w(url title link).each do |name| + install_text_element(name, "", nil) + end + [ + ["width", :integer], + ["height", :integer], + ["description"], + ].each do |name, type| + install_text_element(name, "", "?", name, type) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.url = args[0] + self.title = args[1] + self.link = args[2] + self.width = args[3] + self.height = args[4] + self.description = args[5] + end + end + + private + def maker_target(maker) + maker.image + end + end + + class Cloud < Element + + include RSS09 + + [ + ["domain", "", true], + ["port", "", true, :integer], + ["path", "", true], + ["registerProcedure", "", true], + ["protocol", "", true], + ].each do |name, uri, required, type| + install_get_attribute(name, uri, required, type) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.domain = args[0] + self.port = args[1] + self.path = args[2] + self.registerProcedure = args[3] + self.protocol = args[4] + end + end + end + + class Item < Element + + include RSS09 + + [ + ["title", '?', :text], + ["link", '?', :text], + ["description", '?', :text], + ["category", '*', :have_children, "categories"], + ["source", '?', :have_child], + ["enclosure", '?', :have_child], + ].each do |tag, occurs, type, *args| + __send__("install_#{type}_element", tag, "", occurs, tag, *args) + end + + private + def maker_target(items) + if items.respond_to?("items") + # For backward compatibility + items = items.items + end + items.new_item + end + + def setup_maker_element(item) + super + @enclosure.setup_maker(item) if @enclosure + @source.setup_maker(item) if @source + end + + class Source < Element + + include RSS09 + + [ + ["url", "", true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required) + end + + content_setup + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.url = args[0] + self.content = args[1] + end + end + + private + def maker_target(item) + item.source + end + + def setup_maker_attributes(source) + source.url = url + source.content = content + end + end + + class Enclosure < Element + + include RSS09 + + [ + ["url", "", true], + ["length", "", true, :integer], + ["type", "", true], + ].each do |name, uri, required, type| + install_get_attribute(name, uri, required, type) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.url = args[0] + self.length = args[1] + self.type = args[2] + end + end + + private + def maker_target(item) + item.enclosure + end + + def setup_maker_attributes(enclosure) + enclosure.url = url + enclosure.length = length + enclosure.type = type + end + end + + class Category < Element + + include RSS09 + + [ + ["domain", "", false] + ].each do |name, uri, required| + install_get_attribute(name, uri, required) + end + + content_setup + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.domain = args[0] + self.content = args[1] + end + end + + private + def maker_target(item) + item.new_category + end + + def setup_maker_attributes(category) + category.domain = domain + category.content = content + end + + end + + end + + class TextInput < Element + + include RSS09 + + %w(title description name link).each do |name| + install_text_element(name, "", nil) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.title = args[0] + self.description = args[1] + self.name = args[2] + self.link = args[3] + end + end + + private + def maker_target(maker) + maker.textinput + end + end + + end + + end + + RSS09::ELEMENTS.each do |name| + BaseListener.install_get_text_element("", name, "#{name}=") + end + + module ListenerMixin + private + def start_rss(tag_name, prefix, attrs, ns) + check_ns(tag_name, prefix, ns, "") + + @rss = Rss.new(attrs['version'], @version, @encoding, @standalone) + @rss.do_validate = @do_validate + @rss.xml_stylesheets = @xml_stylesheets + @last_element = @rss + @proc_stack.push Proc.new { |text, tags| + @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate + } + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/1.0.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/1.0.rb new file mode 100644 index 00000000..a945434f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/1.0.rb @@ -0,0 +1,451 @@ +require "rss/parser" + +module RSS + + module RSS10 + NSPOOL = {} + ELEMENTS = [] + + def self.append_features(klass) + super + + klass.install_must_call_validator('', ::RSS::URI) + end + + end + + class RDF < Element + + include RSS10 + include RootElementMixin + + class << self + + def required_uri + URI + end + + end + + @tag_name = 'RDF' + + PREFIX = 'rdf' + URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + + install_ns('', ::RSS::URI) + install_ns(PREFIX, URI) + + [ + ["channel", nil], + ["image", "?"], + ["item", "+", :children], + ["textinput", "?"], + ].each do |tag, occurs, type| + type ||= :child + __send__("install_have_#{type}_element", tag, ::RSS::URI, occurs) + end + + attr_accessor :rss_version, :version, :encoding, :standalone + + def initialize(version=nil, encoding=nil, standalone=nil) + super('1.0', version, encoding, standalone) + end + + def full_name + tag_name_with_prefix(PREFIX) + end + + class Li < Element + + include RSS10 + + class << self + def required_uri + URI + end + end + + [ + ["resource", [URI, ""], true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.resource = args[0] + end + end + + def full_name + tag_name_with_prefix(PREFIX) + end + end + + class Seq < Element + + include RSS10 + + Li = ::RSS::RDF::Li + + class << self + def required_uri + URI + end + end + + @tag_name = 'Seq' + + install_have_children_element("li", URI, "*") + install_must_call_validator('rdf', ::RSS::RDF::URI) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + @li = args[0] if args[0] + end + end + + def full_name + tag_name_with_prefix(PREFIX) + end + + def setup_maker(target) + lis.each do |li| + target << li.resource + end + end + end + + class Bag < Element + + include RSS10 + + Li = ::RSS::RDF::Li + + class << self + def required_uri + URI + end + end + + @tag_name = 'Bag' + + install_have_children_element("li", URI, "*") + install_must_call_validator('rdf', URI) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + @li = args[0] if args[0] + end + end + + def full_name + tag_name_with_prefix(PREFIX) + end + + def setup_maker(target) + lis.each do |li| + target << li.resource + end + end + end + + class Channel < Element + + include RSS10 + + class << self + + def required_uri + ::RSS::URI + end + + end + + [ + ["about", URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{PREFIX}:#{name}") + end + + [ + ['title', nil, :text], + ['link', nil, :text], + ['description', nil, :text], + ['image', '?', :have_child], + ['items', nil, :have_child], + ['textinput', '?', :have_child], + ].each do |tag, occurs, type| + __send__("install_#{type}_element", tag, ::RSS::URI, occurs) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + end + end + + private + def maker_target(maker) + maker.channel + end + + def setup_maker_attributes(channel) + channel.about = about + end + + class Image < Element + + include RSS10 + + class << self + + def required_uri + ::RSS::URI + end + + end + + [ + ["resource", URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{PREFIX}:#{name}") + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.resource = args[0] + end + end + end + + class Textinput < Element + + include RSS10 + + class << self + + def required_uri + ::RSS::URI + end + + end + + [ + ["resource", URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{PREFIX}:#{name}") + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.resource = args[0] + end + end + end + + class Items < Element + + include RSS10 + + Seq = ::RSS::RDF::Seq + + class << self + + def required_uri + ::RSS::URI + end + + end + + install_have_child_element("Seq", URI, nil) + install_must_call_validator('rdf', URI) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.Seq = args[0] + end + self.Seq ||= Seq.new + end + + def resources + if @Seq + @Seq.lis.collect do |li| + li.resource + end + else + [] + end + end + end + end + + class Image < Element + + include RSS10 + + class << self + + def required_uri + ::RSS::URI + end + + end + + [ + ["about", URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{PREFIX}:#{name}") + end + + %w(title url link).each do |name| + install_text_element(name, ::RSS::URI, nil) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + end + end + + private + def maker_target(maker) + maker.image + end + end + + class Item < Element + + include RSS10 + + class << self + + def required_uri + ::RSS::URI + end + + end + + + [ + ["about", URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{PREFIX}:#{name}") + end + + [ + ["title", nil], + ["link", nil], + ["description", "?"], + ].each do |tag, occurs| + install_text_element(tag, ::RSS::URI, occurs) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + end + end + + private + def maker_target(items) + if items.respond_to?("items") + # For backward compatibility + items = items.items + end + items.new_item + end + end + + class Textinput < Element + + include RSS10 + + class << self + + def required_uri + ::RSS::URI + end + + end + + [ + ["about", URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{PREFIX}:#{name}") + end + + %w(title description name link).each do |name| + install_text_element(name, ::RSS::URI, nil) + end + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + end + end + + private + def maker_target(maker) + maker.textinput + end + end + + end + + RSS10::ELEMENTS.each do |name| + BaseListener.install_get_text_element(URI, name, "#{name}=") + end + + module ListenerMixin + private + def start_RDF(tag_name, prefix, attrs, ns) + check_ns(tag_name, prefix, ns, RDF::URI) + + @rss = RDF.new(@version, @encoding, @standalone) + @rss.do_validate = @do_validate + @rss.xml_stylesheets = @xml_stylesheets + @last_element = @rss + @proc_stack.push Proc.new { |text, tags| + @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate + } + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/2.0.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/2.0.rb new file mode 100644 index 00000000..44bdb4f1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/2.0.rb @@ -0,0 +1,111 @@ +require "rss/0.9" + +module RSS + + class Rss + + class Channel + + [ + ["generator"], + ["ttl", :integer], + ].each do |name, type| + install_text_element(name, "", "?", name, type) + end + + [ + %w(category categories), + ].each do |name, plural_name| + install_have_children_element(name, "", "*", name, plural_name) + end + + [ + ["image", "?"], + ["language", "?"], + ].each do |name, occurs| + install_model(name, "", occurs) + end + + Category = Item::Category + + class Item + + [ + ["comments", "?"], + ["author", "?"], + ].each do |name, occurs| + install_text_element(name, "", occurs) + end + + [ + ["pubDate", '?'], + ].each do |name, occurs| + install_date_element(name, "", occurs, name, 'rfc822') + end + alias date pubDate + alias date= pubDate= + + [ + ["guid", '?'], + ].each do |name, occurs| + install_have_child_element(name, "", occurs) + end + + private + alias _setup_maker_element setup_maker_element + def setup_maker_element(item) + _setup_maker_element(item) + @guid.setup_maker(item) if @guid + end + + class Guid < Element + + include RSS09 + + [ + ["isPermaLink", "", false, :boolean] + ].each do |name, uri, required, type| + install_get_attribute(name, uri, required, type) + end + + content_setup + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.isPermaLink = args[0] + self.content = args[1] + end + end + + alias_method :_PermaLink?, :PermaLink? + private :_PermaLink? + def PermaLink? + perma = _PermaLink? + perma or perma.nil? + end + + private + def maker_target(item) + item.guid + end + + def setup_maker_attributes(guid) + guid.isPermaLink = isPermaLink + guid.content = content + end + end + + end + + end + + end + + RSS09::ELEMENTS.each do |name| + BaseListener.install_get_text_element("", name, "#{name}=") + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/content.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/content.rb new file mode 100644 index 00000000..1b13f39f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/content.rb @@ -0,0 +1,38 @@ +require "rss/1.0" + +module RSS + + CONTENT_PREFIX = 'content' + CONTENT_URI = "http://purl.org/rss/1.0/modules/content/" + + RDF.install_ns(CONTENT_PREFIX, CONTENT_URI) + + module ContentModel + + extend BaseModel + + ELEMENTS = [] + + def self.append_features(klass) + super + + klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI) + %w(encoded).each do |name| + klass.install_text_element(name, CONTENT_URI, "?", + "#{CONTENT_PREFIX}_#{name}") + end + end + end + + class RDF + class Item; include ContentModel; end + end + + prefix_size = CONTENT_PREFIX.size + 1 + ContentModel::ELEMENTS.uniq! + ContentModel::ELEMENTS.each do |full_name| + name = full_name[prefix_size..-1] + BaseListener.install_get_text_element(CONTENT_URI, name, "#{full_name}=") + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/converter.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/converter.rb new file mode 100644 index 00000000..d928c482 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/converter.rb @@ -0,0 +1,158 @@ +require "rss/utils" + +module RSS + + class Converter + + include Utils + + def initialize(to_enc, from_enc=nil) + normalized_to_enc = to_enc.downcase.gsub(/-/, '_') + from_enc ||= 'utf-8' + normalized_from_enc = from_enc.downcase.gsub(/-/, '_') + if normalized_to_enc == normalized_from_enc + def_same_enc() + else + def_diff_enc = "def_to_#{normalized_to_enc}_from_#{normalized_from_enc}" + if respond_to?(def_diff_enc) + __send__(def_diff_enc) + else + def_else_enc(to_enc, from_enc) + end + end + end + + def convert(value) + value + end + + def def_convert(depth=0) + instance_eval(<<-EOC, *get_file_and_line_from_caller(depth)) + def convert(value) + if value.kind_of?(String) + #{yield('value')} + else + value + end + end + EOC + end + + def def_iconv_convert(to_enc, from_enc, depth=0) + begin + require "iconv" + @iconv = Iconv.new(to_enc, from_enc) + def_convert(depth+1) do |value| + <<-EOC + begin + @iconv.iconv(#{value}) + rescue Iconv::Failure + raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}") + end + EOC + end + rescue LoadError, ArgumentError, SystemCallError + raise UnknownConversionMethodError.new(to_enc, from_enc) + end + end + + def def_else_enc(to_enc, from_enc) + def_iconv_convert(to_enc, from_enc, 0) + end + + def def_same_enc() + def_convert do |value| + value + end + end + + def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg) + begin + require "uconv" + def_convert(1) do |value| + <<-EOC + begin + Uconv.#{meth}(#{value}) + rescue Uconv::Error + raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}") + end + EOC + end + rescue LoadError + require 'nkf' + def_convert(1) do |value| + "NKF.nkf(#{nkf_arg.dump}, #{value})" + end + end + end + + def def_to_euc_jp_from_utf_8 + def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We') + end + + def def_to_utf_8_from_euc_jp + def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew') + end + + def def_to_shift_jis_from_utf_8 + def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws') + end + + def def_to_utf_8_from_shift_jis + def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw') + end + + def def_to_euc_jp_from_shift_jis + require "nkf" + def_convert do |value| + "NKF.nkf('-Se', #{value})" + end + end + + def def_to_shift_jis_from_euc_jp + require "nkf" + def_convert do |value| + "NKF.nkf('-Es', #{value})" + end + end + + def def_to_euc_jp_from_iso_2022_jp + require "nkf" + def_convert do |value| + "NKF.nkf('-Je', #{value})" + end + end + + def def_to_iso_2022_jp_from_euc_jp + require "nkf" + def_convert do |value| + "NKF.nkf('-Ej', #{value})" + end + end + + def def_to_utf_8_from_iso_8859_1 + def_convert do |value| + "#{value}.unpack('C*').pack('U*')" + end + end + + def def_to_iso_8859_1_from_utf_8 + def_convert do |value| + <<-EOC + array_utf8 = #{value}.unpack('U*') + array_enc = [] + array_utf8.each do |num| + if num <= 0xFF + array_enc << num + else + array_enc.concat "&\#\#{num};".unpack('C*') + end + end + array_enc.pack('C*') + EOC + end + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/dublincore.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/dublincore.rb new file mode 100644 index 00000000..8a4afd4d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/dublincore.rb @@ -0,0 +1,154 @@ +require "rss/1.0" + +module RSS + + DC_PREFIX = 'dc' + DC_URI = "http://purl.org/dc/elements/1.1/" + + RDF.install_ns(DC_PREFIX, DC_URI) + + module BaseDublinCoreModel + def append_features(klass) + super + + return if klass.instance_of?(Module) + DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural = plural_name || "#{name}s" + full_name = "#{DC_PREFIX}_#{name}" + full_plural_name = "#{DC_PREFIX}_#{plural}" + klass_name = "DublinCore#{Utils.to_class_name(name)}" + klass.install_must_call_validator(DC_PREFIX, DC_URI) + klass.install_have_children_element(name, DC_URI, "*", + full_name, full_plural_name) + klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0)) + remove_method :#{full_name} + remove_method :#{full_name}= + remove_method :set_#{full_name} + + def #{full_name} + @#{full_name}.first and @#{full_name}.first.value + end + + def #{full_name}=(new_value) + @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value) + end + alias set_#{full_name} #{full_name}= + EOC + end + klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0)) + alias date #{DC_PREFIX}_date + alias date= #{DC_PREFIX}_date= + EOC + end + end + + module DublinCoreModel + + extend BaseModel + extend BaseDublinCoreModel + + TEXT_ELEMENTS = { + "title" => nil, + "description" => nil, + "creator" => nil, + "subject" => nil, + "publisher" => nil, + "contributor" => nil, + "type" => nil, + "format" => nil, + "identifier" => nil, + "source" => nil, + "language" => nil, + "relation" => nil, + "coverage" => nil, + "rights" => "rightses" # FIXME + } + + DATE_ELEMENTS = { + "date" => "w3cdtf", + } + + ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a + DublinCoreModel::DATE_ELEMENTS.each do |name, | + ELEMENT_NAME_INFOS << [name, nil] + end + + ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys + + ELEMENTS.each do |name, plural_name| + module_eval(<<-EOC, *get_file_and_line_from_caller(0)) + class DublinCore#{Utils.to_class_name(name)} < Element + include RSS10 + + content_setup + + class << self + def required_prefix + DC_PREFIX + end + + def required_uri + DC_URI + end + end + + @tag_name = #{name.dump} + + alias_method(:value, :content) + alias_method(:value=, :content=) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.content = args[0] + end + end + + def full_name + tag_name_with_prefix(DC_PREFIX) + end + + def maker_target(target) + target.new_#{name} + end + + def setup_maker_attributes(#{name}) + #{name}.content = content + end + end + EOC + end + + DATE_ELEMENTS.each do |name, type| + module_eval(<<-EOC, *get_file_and_line_from_caller(0)) + class DublinCore#{Utils.to_class_name(name)} < Element + remove_method(:content=) + remove_method(:value=) + + date_writer("content", #{type.dump}, #{name.dump}) + + alias_method(:value=, :content=) + end + EOC + end + end + + # For backward compatibility + DublincoreModel = DublinCoreModel + + class RDF + class Channel; include DublinCoreModel; end + class Image; include DublinCoreModel; end + class Item; include DublinCoreModel; end + class Textinput; include DublinCoreModel; end + end + + DublinCoreModel::ELEMENTS.each do |name| + class_name = Utils.to_class_name(name) + BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}") + end + + DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"} +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/image.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/image.rb new file mode 100644 index 00000000..a9e9e909 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/image.rb @@ -0,0 +1,193 @@ +require 'rss/1.0' +require 'rss/dublincore' + +module RSS + + IMAGE_PREFIX = 'image' + IMAGE_URI = 'http://web.resource.org/rss/1.0/modules/image/' + + RDF.install_ns(IMAGE_PREFIX, IMAGE_URI) + + IMAGE_ELEMENTS = [] + + %w(item favicon).each do |name| + class_name = Utils.to_class_name(name) + BaseListener.install_class_name(IMAGE_URI, name, "Image#{class_name}") + IMAGE_ELEMENTS << "#{IMAGE_PREFIX}_#{name}" + end + + module ImageModelUtils + def validate_one_tag_name(ignore_unknown_element, name, tags) + if !ignore_unknown_element + invalid = tags.find {|tag| tag != name} + raise UnknownTagError.new(invalid, IMAGE_URI) if invalid + end + raise TooMuchTagError.new(name, tag_name) if tags.size > 1 + end + end + + module ImageItemModel + include ImageModelUtils + extend BaseModel + + def self.append_features(klass) + super + + klass.install_have_child_element("item", IMAGE_URI, "?", + "#{IMAGE_PREFIX}_item") + klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI) + end + + class ImageItem < Element + include RSS10 + include DublinCoreModel + + @tag_name = "item" + + class << self + def required_prefix + IMAGE_PREFIX + end + + def required_uri + IMAGE_URI + end + end + + install_must_call_validator(IMAGE_PREFIX, IMAGE_URI) + + [ + ["about", ::RSS::RDF::URI, true], + ["resource", ::RSS::RDF::URI, false], + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{::RSS::RDF::PREFIX}:#{name}") + end + + %w(width height).each do |tag| + full_name = "#{IMAGE_PREFIX}_#{tag}" + disp_name = "#{IMAGE_PREFIX}:#{tag}" + install_text_element(tag, IMAGE_URI, "?", + full_name, :integer, disp_name) + BaseListener.install_get_text_element(IMAGE_URI, tag, "#{full_name}=") + end + + alias width= image_width= + alias width image_width + alias height= image_height= + alias height image_height + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + self.resource = args[1] + end + end + + def full_name + tag_name_with_prefix(IMAGE_PREFIX) + end + + private + def maker_target(target) + target.image_item + end + + def setup_maker_attributes(item) + item.about = self.about + item.resource = self.resource + end + end + end + + module ImageFaviconModel + include ImageModelUtils + extend BaseModel + + def self.append_features(klass) + super + + unless klass.class == Module + klass.install_have_child_element("favicon", IMAGE_URI, "?", + "#{IMAGE_PREFIX}_favicon") + klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI) + end + end + + class ImageFavicon < Element + include RSS10 + include DublinCoreModel + + @tag_name = "favicon" + + class << self + def required_prefix + IMAGE_PREFIX + end + + def required_uri + IMAGE_URI + end + end + + [ + ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX], + ["size", IMAGE_URI, true, IMAGE_PREFIX], + ].each do |name, uri, required, prefix| + install_get_attribute(name, uri, required, nil, nil, + "#{prefix}:#{name}") + end + + AVAILABLE_SIZES = %w(small medium large) + alias_method :_size=, :size= + private :_size= + def size=(new_value) + if @do_validate and !new_value.nil? + new_value = new_value.strip + unless AVAILABLE_SIZES.include?(new_value) + attr_name = "#{IMAGE_PREFIX}:size" + raise NotAvailableValueError.new(full_name, new_value, attr_name) + end + end + __send__(:_size=, new_value) + end + + alias image_size= size= + alias image_size size + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + self.size = args[1] + end + end + + def full_name + tag_name_with_prefix(IMAGE_PREFIX) + end + + private + def maker_target(target) + target.image_favicon + end + + def setup_maker_attributes(favicon) + favicon.about = self.about + favicon.size = self.size + end + end + + end + + class RDF + class Channel; include ImageFaviconModel; end + class Item; include ImageItemModel; end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker.rb new file mode 100644 index 00000000..9ed799ac --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker.rb @@ -0,0 +1,37 @@ +require "rss/rss" + +module RSS + + module Maker + + MAKERS = {} + + class << self + def make(version, &block) + maker(version).make(&block) + end + + def maker(version) + MAKERS[version] + end + + def add_maker(version, maker) + MAKERS[version] = maker + end + + def filename_to_version(filename) + File.basename(filename, ".*") + end + end + end + +end + +require "rss/maker/1.0" +require "rss/maker/2.0" +require "rss/maker/content" +require "rss/maker/dublincore" +require "rss/maker/syndication" +require "rss/maker/taxonomy" +require "rss/maker/trackback" +require "rss/maker/image" diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/0.9.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/0.9.rb new file mode 100644 index 00000000..b82585fb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/0.9.rb @@ -0,0 +1,224 @@ +require "rss/0.9" + +require "rss/maker/base" + +module RSS + module Maker + + class RSS09 < RSSBase + + def initialize(rss_version="0.91") + super + end + + private + def make_rss + Rss.new(@rss_version, @version, @encoding, @standalone) + end + + def setup_elements(rss) + setup_channel(rss) + end + + class Channel < ChannelBase + + def to_rss(rss) + channel = Rss::Channel.new + set = setup_values(channel) + if set + rss.channel = channel + setup_items(rss) + setup_image(rss) + setup_textinput(rss) + setup_other_elements(rss) + if rss.channel.image + rss + else + nil + end + elsif variable_is_set? + raise NotSetError.new("maker.channel", not_set_required_variables) + end + end + + def have_required_values? + @title and @link and @description and @language + end + + private + def setup_items(rss) + @maker.items.to_rss(rss) + end + + def setup_image(rss) + @maker.image.to_rss(rss) + end + + def setup_textinput(rss) + @maker.textinput.to_rss(rss) + end + + def variables + super + ["pubDate"] + end + + def required_variable_names + %w(title link description language) + end + + class SkipDays < SkipDaysBase + def to_rss(rss, channel) + unless @days.empty? + skipDays = Rss::Channel::SkipDays.new + channel.skipDays = skipDays + @days.each do |day| + day.to_rss(rss, skipDays.days) + end + end + end + + class Day < DayBase + def to_rss(rss, days) + day = Rss::Channel::SkipDays::Day.new + set = setup_values(day) + if set + days << day + setup_other_elements(rss) + end + end + + def have_required_values? + @content + end + end + end + + class SkipHours < SkipHoursBase + def to_rss(rss, channel) + unless @hours.empty? + skipHours = Rss::Channel::SkipHours.new + channel.skipHours = skipHours + @hours.each do |hour| + hour.to_rss(rss, skipHours.hours) + end + end + end + + class Hour < HourBase + def to_rss(rss, hours) + hour = Rss::Channel::SkipHours::Hour.new + set = setup_values(hour) + if set + hours << hour + setup_other_elements(rss) + end + end + + def have_required_values? + @content + end + end + end + + class Cloud < CloudBase + def to_rss(*args) + end + end + + class Categories < CategoriesBase + def to_rss(*args) + end + + class Category < CategoryBase + end + end + end + + class Image < ImageBase + def to_rss(rss) + image = Rss::Channel::Image.new + set = setup_values(image) + if set + image.link = link + rss.channel.image = image + setup_other_elements(rss) + end + end + + def have_required_values? + @url and @title and link + end + end + + class Items < ItemsBase + def to_rss(rss) + if rss.channel + normalize.each do |item| + item.to_rss(rss) + end + setup_other_elements(rss) + end + end + + class Item < ItemBase + def to_rss(rss) + item = Rss::Channel::Item.new + set = setup_values(item) + if set + rss.items << item + setup_other_elements(rss) + end + end + + private + def have_required_values? + @title and @link + end + + class Guid < GuidBase + def to_rss(*args) + end + end + + class Enclosure < EnclosureBase + def to_rss(*args) + end + end + + class Source < SourceBase + def to_rss(*args) + end + end + + class Categories < CategoriesBase + def to_rss(*args) + end + + class Category < CategoryBase + end + end + + end + end + + class Textinput < TextinputBase + def to_rss(rss) + textInput = Rss::Channel::TextInput.new + set = setup_values(textInput) + if set + rss.channel.textInput = textInput + setup_other_elements(rss) + end + end + + private + def have_required_values? + @title and @description and @name and @link + end + end + end + + add_maker(filename_to_version(__FILE__), RSS09) + add_maker(filename_to_version(__FILE__) + "1", RSS09) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/1.0.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/1.0.rb new file mode 100644 index 00000000..3e6542a0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/1.0.rb @@ -0,0 +1,204 @@ +require "rss/1.0" + +require "rss/maker/base" + +module RSS + module Maker + + class RSS10 < RSSBase + + def initialize + super("1.0") + end + + private + def make_rss + RDF.new(@version, @encoding, @standalone) + end + + def setup_elements(rss) + setup_channel(rss) + setup_image(rss) + setup_items(rss) + setup_textinput(rss) + end + + class Channel < ChannelBase + + def to_rss(rss) + set = false + if @about + channel = RDF::Channel.new(@about) + set = setup_values(channel) + if set + channel.dc_dates.clear + rss.channel = channel + setup_items(rss) + setup_image(rss) + setup_textinput(rss) + setup_other_elements(rss) + end + end + + if (!@about or !set) and variable_is_set? + raise NotSetError.new("maker.channel", not_set_required_variables) + end + end + + def have_required_values? + @about and @title and @link and @description + end + + private + def setup_items(rss) + items = RDF::Channel::Items.new + seq = items.Seq + @maker.items.normalize.each do |item| + seq.lis << RDF::Channel::Items::Seq::Li.new(item.link) + end + rss.channel.items = items + end + + def setup_image(rss) + if @maker.image.have_required_values? + rss.channel.image = RDF::Channel::Image.new(@maker.image.url) + end + end + + def setup_textinput(rss) + if @maker.textinput.have_required_values? + textinput = RDF::Channel::Textinput.new(@maker.textinput.link) + rss.channel.textinput = textinput + end + end + + def required_variable_names + %w(about title link description) + end + + class SkipDays < SkipDaysBase + def to_rss(*args) + end + + class Day < DayBase + end + end + + class SkipHours < SkipHoursBase + def to_rss(*args) + end + + class Hour < HourBase + end + end + + class Cloud < CloudBase + def to_rss(*args) + end + end + + class Categories < CategoriesBase + def to_rss(*args) + end + + class Category < CategoryBase + end + end + end + + class Image < ImageBase + def to_rss(rss) + if @url + image = RDF::Image.new(@url) + set = setup_values(image) + if set + rss.image = image + setup_other_elements(rss) + end + end + end + + def have_required_values? + @url and @title and link and @maker.channel.have_required_values? + end + + private + def variables + super + ["link"] + end + end + + class Items < ItemsBase + def to_rss(rss) + if rss.channel + normalize.each do |item| + item.to_rss(rss) + end + setup_other_elements(rss) + end + end + + class Item < ItemBase + def to_rss(rss) + if @link + item = RDF::Item.new(@link) + set = setup_values(item) + if set + item.dc_dates.clear + rss.items << item + setup_other_elements(rss) + end + end + end + + def have_required_values? + @title and @link + end + + class Guid < GuidBase + def to_rss(*args) + end + end + + class Enclosure < EnclosureBase + def to_rss(*args) + end + end + + class Source < SourceBase + def to_rss(*args) + end + end + + class Categories < CategoriesBase + def to_rss(*args) + end + + class Category < CategoryBase + end + end + end + end + + class Textinput < TextinputBase + def to_rss(rss) + if @link + textinput = RDF::Textinput.new(@link) + set = setup_values(textinput) + if set + rss.textinput = textinput + setup_other_elements(rss) + end + end + end + + def have_required_values? + @title and @description and @name and @link and + @maker.channel.have_required_values? + end + end + end + + add_maker(filename_to_version(__FILE__), RSS10) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/2.0.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/2.0.rb new file mode 100644 index 00000000..a9586616 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/2.0.rb @@ -0,0 +1,168 @@ +require "rss/2.0" + +require "rss/maker/0.9" + +module RSS + module Maker + + class RSS20 < RSS09 + + def initialize(rss_version="2.0") + super + end + + class Channel < RSS09::Channel + + def have_required_values? + @title and @link and @description + end + + def required_variable_names + %w(title link description) + end + + class SkipDays < RSS09::Channel::SkipDays + class Day < RSS09::Channel::SkipDays::Day + end + end + + class SkipHours < RSS09::Channel::SkipHours + class Hour < RSS09::Channel::SkipHours::Hour + end + end + + class Cloud < RSS09::Channel::Cloud + def to_rss(rss, channel) + cloud = Rss::Channel::Cloud.new + set = setup_values(cloud) + if set + channel.cloud = cloud + setup_other_elements(rss) + end + end + + def have_required_values? + @domain and @port and @path and + @registerProcedure and @protocol + end + end + + class Categories < RSS09::Channel::Categories + def to_rss(rss, channel) + @categories.each do |category| + category.to_rss(rss, channel) + end + end + + class Category < RSS09::Channel::Categories::Category + def to_rss(rss, channel) + category = Rss::Channel::Category.new + set = setup_values(category) + if set + channel.categories << category + setup_other_elements(rss) + end + end + + def have_required_values? + @content + end + end + end + + end + + class Image < RSS09::Image + end + + class Items < RSS09::Items + + class Item < RSS09::Items::Item + + def have_required_values? + @title or @description + end + + private + def variables + super + ["pubDate"] + end + + class Guid < RSS09::Items::Item::Guid + def to_rss(rss, item) + guid = Rss::Channel::Item::Guid.new + set = setup_values(guid) + if set + item.guid = guid + setup_other_elements(rss) + end + end + + def have_required_values? + @content + end + end + + class Enclosure < RSS09::Items::Item::Enclosure + def to_rss(rss, item) + enclosure = Rss::Channel::Item::Enclosure.new + set = setup_values(enclosure) + if set + item.enclosure = enclosure + setup_other_elements(rss) + end + end + + def have_required_values? + @url and @length and @type + end + end + + class Source < RSS09::Items::Item::Source + def to_rss(rss, item) + source = Rss::Channel::Item::Source.new + set = setup_values(source) + if set + item.source = source + setup_other_elements(rss) + end + end + + def have_required_values? + @url and @content + end + end + + class Categories < RSS09::Items::Item::Categories + def to_rss(rss, item) + @categories.each do |category| + category.to_rss(rss, item) + end + end + + class Category < RSS09::Items::Item::Categories::Category + def to_rss(rss, item) + category = Rss::Channel::Item::Category.new + set = setup_values(category) + if set + item.categories << category + setup_other_elements(rss) + end + end + + def have_required_values? + @content + end + end + end + end + + end + + class Textinput < RSS09::Textinput + end + end + + add_maker(filename_to_version(__FILE__), RSS20) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/base.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/base.rb new file mode 100644 index 00000000..2327dd98 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/base.rb @@ -0,0 +1,546 @@ +require 'forwardable' + +require 'rss/rss' + +module RSS + module Maker + + module Base + + def self.append_features(klass) + super + + klass.module_eval(<<-EOC, __FILE__, __LINE__) + + OTHER_ELEMENTS = [] + NEED_INITIALIZE_VARIABLES = [] + + def self.inherited(subclass) + subclass.const_set("OTHER_ELEMENTS", []) + subclass.const_set("NEED_INITIALIZE_VARIABLES", []) + + subclass.module_eval(<<-EOEOC, __FILE__, __LINE__) + def self.other_elements + OTHER_ELEMENTS + super + end + + def self.need_initialize_variables + NEED_INITIALIZE_VARIABLES + super + end + EOEOC + end + + def self.add_other_element(variable_name) + OTHER_ELEMENTS << variable_name + end + + def self.other_elements + OTHER_ELEMENTS + end + + def self.add_need_initialize_variable(variable_name, init_value="nil") + NEED_INITIALIZE_VARIABLES << [variable_name, init_value] + end + + def self.need_initialize_variables + NEED_INITIALIZE_VARIABLES + end + + def self.def_array_element(name) + include Enumerable + extend Forwardable + + def_delegators("@\#{name}", :<<, :[], :[]=, :first, :last) + def_delegators("@\#{name}", :push, :pop, :shift, :unshift) + def_delegators("@\#{name}", :each, :size) + + add_need_initialize_variable(name, "[]") + end + EOC + end + + def initialize(maker) + @maker = maker + initialize_variables + end + + def have_required_values? + true + end + + private + def initialize_variables + self.class.need_initialize_variables.each do |variable_name, init_value| + instance_eval("@#{variable_name} = #{init_value}", __FILE__, __LINE__) + end + end + + def setup_other_elements(rss) + self.class.other_elements.each do |element| + __send__("setup_#{element}", rss, current_element(rss)) + end + end + + def current_element(rss) + rss + end + + def setup_values(target) + set = false + if have_required_values? + variables.each do |var| + setter = "#{var}=" + if target.respond_to?(setter) + value = __send__(var) + if value + target.__send__(setter, value) + set = true + end + end + end + end + set + end + + def variables + self.class.need_initialize_variables.find_all do |name, init| + "nil" == init + end.collect do |name, init| + name + end + end + + def variable_is_set? + variables.find {|var| !__send__(var).nil?} + end + + def not_set_required_variables + required_variable_names.find_all do |var| + __send__(var).nil? + end + end + + def required_variables_are_set? + required_variable_names.each do |var| + return false if __send__(var).nil? + end + true + end + + end + + class RSSBase + include Base + + class << self + def make(&block) + new.make(&block) + end + end + + %w(xml_stylesheets channel image items textinput).each do |element| + attr_reader element + add_need_initialize_variable(element, "make_#{element}") + module_eval(<<-EOC, __FILE__, __LINE__) + private + def setup_#{element}(rss) + @#{element}.to_rss(rss) + end + + def make_#{element} + self.class::#{Utils.to_class_name(element)}.new(self) + end +EOC + end + + attr_reader :rss_version + attr_accessor :version, :encoding, :standalone + + def initialize(rss_version) + super(self) + @rss_version = rss_version + @version = "1.0" + @encoding = "UTF-8" + @standalone = nil + end + + def make + if block_given? + yield(self) + to_rss + else + nil + end + end + + def to_rss + rss = make_rss + setup_xml_stylesheets(rss) + setup_elements(rss) + setup_other_elements(rss) + if rss.channel + rss + else + nil + end + end + + private + remove_method :make_xml_stylesheets + def make_xml_stylesheets + XMLStyleSheets.new(self) + end + + end + + class XMLStyleSheets + include Base + + def_array_element("xml_stylesheets") + + def to_rss(rss) + @xml_stylesheets.each do |xss| + xss.to_rss(rss) + end + end + + def new_xml_stylesheet + xss = XMLStyleSheet.new(@maker) + @xml_stylesheets << xss + if block_given? + yield xss + else + xss + end + end + + class XMLStyleSheet + include Base + + ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute| + attr_accessor attribute + add_need_initialize_variable(attribute) + end + + def to_rss(rss) + xss = ::RSS::XMLStyleSheet.new + guess_type_if_need(xss) + set = setup_values(xss) + if set + rss.xml_stylesheets << xss + end + end + + def have_required_values? + @href and @type + end + + private + def guess_type_if_need(xss) + if @type.nil? + xss.href = @href + @type = xss.type + end + end + end + end + + class ChannelBase + include Base + + %w(cloud categories skipDays skipHours).each do |element| + attr_reader element + add_other_element(element) + add_need_initialize_variable(element, "make_#{element}") + module_eval(<<-EOC, __FILE__, __LINE__) + private + def setup_#{element}(rss, current) + @#{element}.to_rss(rss, current) + end + + def make_#{element} + self.class::#{Utils.to_class_name(element)}.new(@maker) + end +EOC + end + + %w(about title link description language copyright + managingEditor webMaster rating docs date + lastBuildDate generator ttl).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + alias_method(:pubDate, :date) + alias_method(:pubDate=, :date=) + + def current_element(rss) + rss.channel + end + + class SkipDaysBase + include Base + + def_array_element("days") + + def new_day + day = self.class::Day.new(@maker) + @days << day + if block_given? + yield day + else + day + end + end + + def current_element(rss) + rss.channel.skipDays + end + + class DayBase + include Base + + %w(content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def current_element(rss) + rss.channel.skipDays.last + end + + end + end + + class SkipHoursBase + include Base + + def_array_element("hours") + + def new_hour + hour = self.class::Hour.new(@maker) + @hours << hour + if block_given? + yield hour + else + hour + end + end + + def current_element(rss) + rss.channel.skipHours + end + + class HourBase + include Base + + %w(content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def current_element(rss) + rss.channel.skipHours.last + end + + end + end + + class CloudBase + include Base + + %w(domain port path registerProcedure protocol).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def current_element(rss) + rss.channel.cloud + end + + end + + class CategoriesBase + include Base + + def_array_element("categories") + + def new_category + category = self.class::Category.new(@maker) + @categories << category + if block_given? + yield category + else + category + end + end + + class CategoryBase + include Base + + %w(domain content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + end + end + + class ImageBase + include Base + + %w(title url width height description).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def link + @maker.channel.link + end + + def current_element(rss) + rss.image + end + end + + class ItemsBase + include Base + + def_array_element("items") + + attr_accessor :do_sort, :max_size + + def initialize(maker) + super + @do_sort = false + @max_size = -1 + end + + def normalize + if @max_size >= 0 + sort_if_need[0...@max_size] + else + sort_if_need[0..@max_size] + end + end + + def current_element(rss) + rss.items + end + + def new_item + item = self.class::Item.new(@maker) + @items << item + if block_given? + yield item + else + item + end + end + + private + def sort_if_need + if @do_sort.respond_to?(:call) + @items.sort do |x, y| + @do_sort.call(x, y) + end + elsif @do_sort + @items.sort do |x, y| + y <=> x + end + else + @items + end + end + + class ItemBase + include Base + + %w(guid enclosure source categories).each do |element| + attr_reader element + add_other_element(element) + add_need_initialize_variable(element, "make_#{element}") + module_eval(<<-EOC, __FILE__, __LINE__) + private + def setup_#{element}(rss, current) + @#{element}.to_rss(rss, current) + end + + def make_#{element} + self.class::#{Utils.to_class_name(element)}.new(@maker) + end +EOC + end + + %w(title link description date author comments).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + alias_method(:pubDate, :date) + alias_method(:pubDate=, :date=) + + def <=>(other) + if date and other.date + date <=> other.date + elsif date + 1 + elsif other.date + -1 + else + 0 + end + end + + def current_element(rss) + rss.items.last + end + + class GuidBase + include Base + + %w(isPermaLink content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + class EnclosureBase + include Base + + %w(url length type).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + class SourceBase + include Base + + %w(url content).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + end + + CategoriesBase = ChannelBase::CategoriesBase + + end + end + + class TextinputBase + include Base + + %w(title description name link).each do |element| + attr_accessor element + add_need_initialize_variable(element) + end + + def current_element(rss) + rss.textinput + end + + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/content.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/content.rb new file mode 100644 index 00000000..18590d0c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/content.rb @@ -0,0 +1,29 @@ +require 'rss/content' +require 'rss/maker/1.0' + +module RSS + module Maker + module ContentModel + def self.append_features(klass) + super + + ::RSS::ContentModel::ELEMENTS.each do |element| + klass.add_need_initialize_variable(element) + klass.add_other_element(element) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_accessor :#{element} + def setup_#{element}(rss, current) + if #{element} and current.respond_to?(:#{element}=) + current.#{element} = @#{element} if @#{element} + end + end + EOC + end + end + end + + class ItemsBase + class ItemBase; include ContentModel; end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/dublincore.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/dublincore.rb new file mode 100644 index 00000000..0cf1255e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/dublincore.rb @@ -0,0 +1,169 @@ +require 'rss/dublincore' +require 'rss/maker/1.0' + +module RSS + module Maker + module DublinCoreModel + def self.append_features(klass) + super + + ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural_name ||= "#{name}s" + full_name = "#{RSS::DC_PREFIX}_#{name}" + full_plural_name = "#{RSS::DC_PREFIX}_#{plural_name}" + klass_name = Utils.to_class_name(name) + plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" + full_plural_klass_name = "self.class::#{plural_klass_name}" + full_klass_name = "#{full_plural_klass_name}::#{klass_name}" + klass.add_need_initialize_variable(full_plural_name, + "make_#{full_plural_name}") + klass.add_other_element(full_plural_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_accessor :#{full_plural_name} + def make_#{full_plural_name} + #{full_plural_klass_name}.new(@maker) + end + + def setup_#{full_plural_name}(rss, current) + @#{full_plural_name}.to_rss(rss, current) + end + + def #{full_name} + @#{full_plural_name}[0] and @#{full_plural_name}[0].value + end + + def #{full_name}=(new_value) + @#{full_plural_name}[0] = #{full_klass_name}.new(self) + @#{full_plural_name}[0].value = new_value + end +EOC + end + end + + ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural_name ||= "#{name}s" + klass_name = Utils.to_class_name(name) + plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" + module_eval(<<-EOC, __FILE__, __LINE__) + class #{plural_klass_name}Base + include Base + + def_array_element(#{plural_name.dump}) + + def new_#{name} + #{name} = self.class::#{klass_name}.new(self) + @#{plural_name} << #{name} + if block_given? + yield #{name} + else + #{name} + end + end + + def to_rss(rss, current) + @#{plural_name}.each do |#{name}| + #{name}.to_rss(rss, current) + end + end + + class #{klass_name}Base + include Base + + attr_accessor :value + add_need_initialize_variable("value") + alias_method(:content, :value) + alias_method(:content=, :value=) + + def have_required_values? + @value + end + end + end + EOC + end + + def self.install_dublin_core(klass) + ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name| + plural_name ||= "#{name}s" + klass_name = Utils.to_class_name(name) + plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}" + full_klass_name = "DublinCore#{klass_name}" + klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1)) + class #{plural_klass_name} < #{plural_klass_name}Base + class #{klass_name} < #{klass_name}Base + def to_rss(rss, current) + if value and current.respond_to?(:dc_#{name}) + new_item = current.class::#{full_klass_name}.new(value) + current.dc_#{plural_name} << new_item + end + end + end + end +EOC + end + end + end + + class ChannelBase + include DublinCoreModel + + remove_method(:date) + remove_method(:date=) + alias_method(:date, :dc_date) + alias_method(:date=, :dc_date=) + end + + class ImageBase; include DublinCoreModel; end + class ItemsBase + class ItemBase + include DublinCoreModel + + remove_method(:date) + remove_method(:date=) + alias_method(:date, :dc_date) + alias_method(:date=, :dc_date=) + end + end + class TextinputBase; include DublinCoreModel; end + + class RSS10 + class Channel + DublinCoreModel.install_dublin_core(self) + end + + class Image + DublinCoreModel.install_dublin_core(self) + end + + class Items + class Item + DublinCoreModel.install_dublin_core(self) + end + end + + class Textinput + DublinCoreModel.install_dublin_core(self) + end + end + + class RSS09 + class Channel + DublinCoreModel.install_dublin_core(self) + end + + class Image + DublinCoreModel.install_dublin_core(self) + end + + class Items + class Item + DublinCoreModel.install_dublin_core(self) + end + end + + class Textinput + DublinCoreModel.install_dublin_core(self) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/image.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/image.rb new file mode 100644 index 00000000..ed51c8ec --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/image.rb @@ -0,0 +1,145 @@ +require 'rss/image' +require 'rss/maker/1.0' +require 'rss/maker/dublincore' + +module RSS + module Maker + module ImageItemModel + def self.append_features(klass) + super + + name = "#{RSS::IMAGE_PREFIX}_item" + klass.add_need_initialize_variable(name, "make_#{name}") + klass.add_other_element(name) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_reader :#{name} + def setup_#{name}(rss, current) + if @#{name} + @#{name}.to_rss(rss, current) + end + end + + def make_#{name} + self.class::#{Utils.to_class_name(name)}.new(@maker) + end +EOC + end + + class ImageItemBase + include Base + include Maker::DublinCoreModel + + attr_accessor :about, :resource, :image_width, :image_height + add_need_initialize_variable("about") + add_need_initialize_variable("resource") + add_need_initialize_variable("image_width") + add_need_initialize_variable("image_height") + alias width= image_width= + alias width image_width + alias height= image_height= + alias height image_height + + def have_required_values? + @about + end + end + end + + module ImageFaviconModel + def self.append_features(klass) + super + + name = "#{RSS::IMAGE_PREFIX}_favicon" + klass.add_need_initialize_variable(name, "make_#{name}") + klass.add_other_element(name) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_reader :#{name} + def setup_#{name}(rss, current) + if @#{name} + @#{name}.to_rss(rss, current) + end + end + + def make_#{name} + self.class::#{Utils.to_class_name(name)}.new(@maker) + end +EOC + end + + class ImageFaviconBase + include Base + include Maker::DublinCoreModel + + attr_accessor :about, :image_size + add_need_initialize_variable("about") + add_need_initialize_variable("image_size") + alias size image_size + alias size= image_size= + + def have_required_values? + @about and @image_size + end + end + end + + class ChannelBase; include Maker::ImageFaviconModel; end + + class ItemsBase + class ItemBase; include Maker::ImageItemModel; end + end + + class RSS10 + class Items + class Item + class ImageItem < ImageItemBase + DublinCoreModel.install_dublin_core(self) + def to_rss(rss, current) + if @about + item = ::RSS::ImageItemModel::ImageItem.new(@about, @resource) + setup_values(item) + setup_other_elements(item) + current.image_item = item + end + end + end + end + end + + class Channel + class ImageFavicon < ImageFaviconBase + DublinCoreModel.install_dublin_core(self) + def to_rss(rss, current) + if @about and @image_size + args = [@about, @image_size] + favicon = ::RSS::ImageFaviconModel::ImageFavicon.new(*args) + setup_values(favicon) + setup_other_elements(favicon) + current.image_favicon = favicon + end + end + end + end + end + + class RSS09 + class Items + class Item + class ImageItem < ImageItemBase + DublinCoreModel.install_dublin_core(self) + def to_rss(*args) + end + end + end + end + + class Channel + class ImageFavicon < ImageFaviconBase + DublinCoreModel.install_dublin_core(self) + def to_rss(*args) + end + end + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/syndication.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/syndication.rb new file mode 100644 index 00000000..37170862 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/syndication.rb @@ -0,0 +1,27 @@ +require 'rss/syndication' +require 'rss/maker/1.0' + +module RSS + module Maker + module SyndicationModel + def self.append_features(klass) + super + + ::RSS::SyndicationModel::ELEMENTS.each do |element| + klass.add_need_initialize_variable(element) + klass.add_other_element(element) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_accessor :#{element} + def setup_#{element}(rss, current) + if #{element} and current.respond_to?(:#{element}=) + current.#{element} = @#{element} if @#{element} + end + end + EOC + end + end + end + + class ChannelBase; include SyndicationModel; end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/taxonomy.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/taxonomy.rb new file mode 100644 index 00000000..f2729965 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/taxonomy.rb @@ -0,0 +1,182 @@ +require 'rss/taxonomy' +require 'rss/maker/1.0' +require 'rss/maker/dublincore' + +module RSS + module Maker + module TaxonomyTopicsModel + def self.append_features(klass) + super + + klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics") + klass.add_other_element("taxo_topics") + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + attr_reader :taxo_topics + def make_taxo_topics + self.class::TaxonomyTopics.new(@maker) + end + + def setup_taxo_topics(rss, current) + @taxo_topics.to_rss(rss, current) + end +EOC + end + + def self.install_taxo_topics(klass) + klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1)) + class TaxonomyTopics < TaxonomyTopicsBase + def to_rss(rss, current) + if current.respond_to?(:taxo_topics) + topics = current.class::TaxonomyTopics.new + bag = topics.Bag + @resources.each do |resource| + bag.lis << RDF::Bag::Li.new(resource) + end + current.taxo_topics = topics + end + end + end +EOC + end + + class TaxonomyTopicsBase + include Base + + attr_reader :resources + def_array_element("resources") + end + end + + module TaxonomyTopicModel + def self.append_features(klass) + super + + klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics") + klass.add_other_element("taxo_topics") + klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1) + attr_reader :taxo_topics + def make_taxo_topics + self.class::TaxonomyTopics.new(@maker) + end + + def setup_taxo_topics(rss, current) + @taxo_topics.to_rss(rss, current) + end + + def taxo_topic + @taxo_topics[0] and @taxo_topics[0].value + end + + def taxo_topic=(new_value) + @taxo_topic[0] = self.class::TaxonomyTopic.new(self) + @taxo_topic[0].value = new_value + end +EOC + end + + def self.install_taxo_topic(klass) + klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1)) + class TaxonomyTopics < TaxonomyTopicsBase + class TaxonomyTopic < TaxonomyTopicBase + DublinCoreModel.install_dublin_core(self) + TaxonomyTopicsModel.install_taxo_topics(self) + + def to_rss(rss, current) + if current.respond_to?(:taxo_topics) + topic = current.class::TaxonomyTopic.new(value) + topic.taxo_link = value + taxo_topics.to_rss(rss, topic) if taxo_topics + current.taxo_topics << topic + setup_other_elements(rss) + end + end + + def current_element(rss) + super.taxo_topics.last + end + end + end +EOC + end + + class TaxonomyTopicsBase + include Base + + def_array_element("taxo_topics") + + def new_taxo_topic + taxo_topic = self.class::TaxonomyTopic.new(self) + @taxo_topics << taxo_topic + if block_given? + yield taxo_topic + else + taxo_topic + end + end + + def to_rss(rss, current) + @taxo_topics.each do |taxo_topic| + taxo_topic.to_rss(rss, current) + end + end + + class TaxonomyTopicBase + include Base + include DublinCoreModel + include TaxonomyTopicsModel + + attr_accessor :value + add_need_initialize_variable("value") + alias_method(:taxo_link, :value) + alias_method(:taxo_link=, :value=) + + def have_required_values? + @value + end + end + end + end + + class RSSBase + include TaxonomyTopicModel + end + + class ChannelBase + include TaxonomyTopicsModel + end + + class ItemsBase + class ItemBase + include TaxonomyTopicsModel + end + end + + class RSS10 + TaxonomyTopicModel.install_taxo_topic(self) + + class Channel + TaxonomyTopicsModel.install_taxo_topics(self) + end + + class Items + class Item + TaxonomyTopicsModel.install_taxo_topics(self) + end + end + end + + class RSS09 + TaxonomyTopicModel.install_taxo_topic(self) + + class Channel + TaxonomyTopicsModel.install_taxo_topics(self) + end + + class Items + class Item + TaxonomyTopicsModel.install_taxo_topics(self) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/trackback.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/trackback.rb new file mode 100644 index 00000000..4ae6164f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/maker/trackback.rb @@ -0,0 +1,130 @@ +require 'rss/trackback' +require 'rss/maker/1.0' +require 'rss/maker/2.0' + +module RSS + module Maker + module TrackBackModel + def self.append_features(klass) + super + + name = "#{RSS::TRACKBACK_PREFIX}_ping" + klass.add_need_initialize_variable(name) + klass.add_other_element(name) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_accessor :#{name} + def setup_#{name}(rss, current) + if #{name} and current.respond_to?(:#{name}=) + current.#{name} = #{name} + end + end + EOC + + name = "#{RSS::TRACKBACK_PREFIX}_abouts" + klass.add_need_initialize_variable(name, "make_#{name}") + klass.add_other_element(name) + klass.module_eval(<<-EOC, __FILE__, __LINE__+1) + attr_accessor :#{name} + def make_#{name} + self.class::TrackBackAbouts.new(self) + end + + def setup_#{name}(rss, current) + @#{name}.to_rss(rss, current) + end + EOC + end + + class TrackBackAboutsBase + include Base + + def_array_element("abouts") + + def new_about + about = self.class::TrackBackAbout.new(@maker) + @abouts << about + if block_given? + yield about + else + about + end + end + + def to_rss(rss, current) + @abouts.each do |about| + about.to_rss(rss, current) + end + end + + class TrackBackAboutBase + include Base + + attr_accessor :value + add_need_initialize_variable("value") + + alias_method(:resource, :value) + alias_method(:resource=, :value=) + alias_method(:content, :value) + alias_method(:content=, :value=) + + def have_required_values? + @value + end + + end + end + end + + class ItemsBase + class ItemBase; include TrackBackModel; end + end + + class RSS10 + class Items + class Item + class TrackBackAbouts < TrackBackAboutsBase + class TrackBackAbout < TrackBackAboutBase + def to_rss(rss, current) + if resource + about = ::RSS::TrackBackModel10::TrackBackAbout.new(resource) + current.trackback_abouts << about + end + end + end + end + end + end + end + + class RSS09 + class Items + class Item + class TrackBackAbouts < TrackBackAboutsBase + def to_rss(*args) + end + class TrackBackAbout < TrackBackAboutBase + end + end + end + end + end + + class RSS20 + class Items + class Item + class TrackBackAbouts < TrackBackAboutsBase + class TrackBackAbout < TrackBackAboutBase + def to_rss(rss, current) + if content + about = ::RSS::TrackBackModel20::TrackBackAbout.new(content) + current.trackback_abouts << about + end + end + end + end + end + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/parser.rb new file mode 100644 index 00000000..033bc123 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/parser.rb @@ -0,0 +1,476 @@ +require "forwardable" +require "open-uri" + +require "rss/rss" + +module RSS + + class NotWellFormedError < Error + attr_reader :line, :element + + # Create a new NotWellFormedError for an error at +line+ + # in +element+. If a block is given the return value of + # the block ends up in the error message. + def initialize(line=nil, element=nil) + message = "This is not well formed XML" + if element or line + message << "\nerror occurred" + message << " in #{element}" if element + message << " at about #{line} line" if line + end + message << "\n#{yield}" if block_given? + super(message) + end + end + + class XMLParserNotFound < Error + def initialize + super("available XML parser was not found in " << + "#{AVAILABLE_PARSER_LIBRARIES.inspect}.") + end + end + + class NotValidXMLParser < Error + def initialize(parser) + super("#{parser} is not an available XML parser. " << + "Available XML parser"<< + (AVAILABLE_PARSERS.size > 1 ? "s are ": " is ") << + "#{AVAILABLE_PARSERS.inspect}.") + end + end + + class NSError < InvalidRSSError + attr_reader :tag, :prefix, :uri + def initialize(tag, prefix, require_uri) + @tag, @prefix, @uri = tag, prefix, require_uri + super("prefix <#{prefix}> doesn't associate uri " << + "<#{require_uri}> in tag <#{tag}>") + end + end + + class Parser + + extend Forwardable + + class << self + + @@default_parser = nil + + def default_parser + @@default_parser || AVAILABLE_PARSERS.first + end + + # Set @@default_parser to new_value if it is one of the + # available parsers. Else raise NotValidXMLParser error. + def default_parser=(new_value) + if AVAILABLE_PARSERS.include?(new_value) + @@default_parser = new_value + else + raise NotValidXMLParser.new(new_value) + end + end + + def parse(rss, do_validate=true, ignore_unknown_element=true, + parser_class=default_parser) + parser = new(rss, parser_class) + parser.do_validate = do_validate + parser.ignore_unknown_element = ignore_unknown_element + parser.parse + end + end + + def_delegators(:@parser, :parse, :rss, + :ignore_unknown_element, + :ignore_unknown_element=, :do_validate, + :do_validate=) + + def initialize(rss, parser_class=self.class.default_parser) + @parser = parser_class.new(normalize_rss(rss)) + end + + private + + # Try to get the XML associated with +rss+. + # Return +rss+ if it already looks like XML, or treat it as a URI, + # or a file to get the XML, + def normalize_rss(rss) + return rss if maybe_xml?(rss) + + uri = to_uri(rss) + + if uri.respond_to?(:read) + uri.read + elsif !rss.tainted? and File.readable?(rss) + File.open(rss) {|f| f.read} + else + rss + end + end + + # maybe_xml? tests if source is a string that looks like XML. + def maybe_xml?(source) + source.is_a?(String) and / [2, 5]) < 0 + raise LoadError, "needs REXML 2.5 or later (#{REXML::Version})" +end + +module RSS + + class REXMLParser < BaseParser + + class << self + def listener + REXMLListener + end + end + + private + def _parse + begin + REXML::Document.parse_stream(@rss, @listener) + rescue RuntimeError => e + raise NotWellFormedError.new{e.message} + rescue REXML::ParseException => e + context = e.context + line = context[0] if context + raise NotWellFormedError.new(line){e.message} + end + end + + end + + class REXMLListener < BaseListener + + include REXML::StreamListener + include ListenerMixin + + class << self + def raise_for_undefined_entity? + false + end + end + + def xmldecl(version, encoding, standalone) + super(version, encoding, standalone == "yes") + # Encoding is converted to UTF-8 when REXML parse XML. + @encoding = 'UTF-8' + end + + alias_method(:cdata, :text) + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/rss.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/rss.rb new file mode 100644 index 00000000..a06985af --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/rss.rb @@ -0,0 +1,1015 @@ +require "time" + +class Time + class << self + unless respond_to?(:w3cdtf) + def w3cdtf(date) + if /\A\s* + (-?\d+)-(\d\d)-(\d\d) + (?:T + (\d\d):(\d\d)(?::(\d\d))? + (\.\d+)? + (Z|[+-]\d\d:\d\d)?)? + \s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8)) + datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i] + datetime << $7.to_f * 1000000 if $7 + if $8 + Time.utc(*datetime) - zone_offset($8) + else + Time.local(*datetime) + end + else + raise ArgumentError.new("invalid date: #{date.inspect}") + end + end + end + end + + unless instance_methods.include?("w3cdtf") + alias w3cdtf iso8601 + end +end + +require "English" +require "rss/utils" +require "rss/converter" +require "rss/xml-stylesheet" + +module RSS + + VERSION = "0.1.6" + + URI = "http://purl.org/rss/1.0/" + + DEBUG = false + + class Error < StandardError; end + + class OverlappedPrefixError < Error + attr_reader :prefix + def initialize(prefix) + @prefix = prefix + end + end + + class InvalidRSSError < Error; end + + class MissingTagError < InvalidRSSError + attr_reader :tag, :parent + def initialize(tag, parent) + @tag, @parent = tag, parent + super("tag <#{tag}> is missing in tag <#{parent}>") + end + end + + class TooMuchTagError < InvalidRSSError + attr_reader :tag, :parent + def initialize(tag, parent) + @tag, @parent = tag, parent + super("tag <#{tag}> is too much in tag <#{parent}>") + end + end + + class MissingAttributeError < InvalidRSSError + attr_reader :tag, :attribute + def initialize(tag, attribute) + @tag, @attribute = tag, attribute + super("attribute <#{attribute}> is missing in tag <#{tag}>") + end + end + + class UnknownTagError < InvalidRSSError + attr_reader :tag, :uri + def initialize(tag, uri) + @tag, @uri = tag, uri + super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>") + end + end + + class NotExpectedTagError < InvalidRSSError + attr_reader :tag, :uri, :parent + def initialize(tag, uri, parent) + @tag, @uri, @parent = tag, uri, parent + super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>") + end + end + # For backward compatibility :X + NotExceptedTagError = NotExpectedTagError + + class NotAvailableValueError < InvalidRSSError + attr_reader :tag, :value, :attribute + def initialize(tag, value, attribute=nil) + @tag, @value, @attribute = tag, value, attribute + message = "value <#{value}> of " + message << "attribute <#{attribute}> of " if attribute + message << "tag <#{tag}> is not available." + super(message) + end + end + + class UnknownConversionMethodError < Error + attr_reader :to, :from + def initialize(to, from) + @to = to + @from = from + super("can't convert to #{to} from #{from}.") + end + end + # for backward compatibility + UnknownConvertMethod = UnknownConversionMethodError + + class ConversionError < Error + attr_reader :string, :to, :from + def initialize(string, to, from) + @string = string + @to = to + @from = from + super("can't convert #{@string} to #{to} from #{from}.") + end + end + + class NotSetError < Error + attr_reader :name, :variables + def initialize(name, variables) + @name = name + @variables = variables + super("required variables of #{@name} are not set: #{@variables.join(', ')}") + end + end + + module BaseModel + + include Utils + + def install_have_child_element(tag_name, uri, occurs, name=nil) + name ||= tag_name + add_need_initialize_variable(name) + install_model(tag_name, uri, occurs, name) + + attr_accessor name + install_element(name) do |n, elem_name| + <<-EOC + if @#{n} + "\#{@#{n}.to_s(need_convert, indent)}" + else + '' + end +EOC + end + end + alias_method(:install_have_attribute_element, :install_have_child_element) + + def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil) + name ||= tag_name + plural_name ||= "#{name}s" + add_have_children_element(name, plural_name) + add_plural_form(name, plural_name) + install_model(tag_name, uri, occurs, plural_name) + + def_children_accessor(name, plural_name) + install_element(name, "s") do |n, elem_name| + <<-EOC + rv = [] + @#{n}.each do |x| + value = "\#{x.to_s(need_convert, indent)}" + rv << value if /\\A\\s*\\z/ !~ value + end + rv.join("\n") +EOC + end + end + + def install_text_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil) + name ||= tag_name + disp_name ||= name + self::ELEMENTS << name + add_need_initialize_variable(name) + install_model(tag_name, uri, occurs, name) + + def_corresponded_attr_writer name, type, disp_name + convert_attr_reader name + install_element(name) do |n, elem_name| + <<-EOC + if @#{n} + rv = "\#{indent}<#{elem_name}>" + value = html_escape(@#{n}) + if need_convert + rv << convert(value) + else + rv << value + end + rv << "" + rv + else + '' + end +EOC + end + end + + def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil) + name ||= tag_name + type ||= :w3cdtf + disp_name ||= name + self::ELEMENTS << name + add_need_initialize_variable(name) + install_model(tag_name, uri, occurs, name) + + # accessor + convert_attr_reader name + date_writer(name, type, disp_name) + + install_element(name) do |n, elem_name| + <<-EOC + if @#{n} + rv = "\#{indent}<#{elem_name}>" + value = html_escape(@#{n}.#{type}) + if need_convert + rv << convert(value) + else + rv << value + end + rv << "" + rv + else + '' + end +EOC + end + + end + + private + def install_element(name, postfix="") + elem_name = name.sub('_', ':') + method_name = "#{name}_element#{postfix}" + add_to_element_method(method_name) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{method_name}(need_convert=true, indent='') + #{yield(name, elem_name)} + end + private :#{method_name} +EOC + end + + def convert_attr_reader(*attrs) + attrs.each do |attr| + attr = attr.id2name if attr.kind_of?(Integer) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{attr} + if @converter + @converter.convert(@#{attr}) + else + @#{attr} + end + end +EOC + end + end + + def date_writer(name, type, disp_name=name) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{name}=(new_value) + if new_value.nil? or new_value.kind_of?(Time) + @#{name} = new_value + else + if @do_validate + begin + @#{name} = Time.__send__('#{type}', new_value) + rescue ArgumentError + raise NotAvailableValueError.new('#{disp_name}', new_value) + end + else + @#{name} = nil + if /\\A\\s*\\z/ !~ new_value.to_s + begin + @#{name} = Time.parse(new_value) + rescue ArgumentError + end + end + end + end + + # Is it need? + if @#{name} + class << @#{name} + undef_method(:to_s) + alias_method(:to_s, :#{type}) + end + end + + end +EOC + end + + def integer_writer(name, disp_name=name) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{name}=(new_value) + if new_value.nil? + @#{name} = new_value + else + if @do_validate + begin + @#{name} = Integer(new_value) + rescue ArgumentError + raise NotAvailableValueError.new('#{disp_name}', new_value) + end + else + @#{name} = new_value.to_i + end + end + end +EOC + end + + def positive_integer_writer(name, disp_name=name) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{name}=(new_value) + if new_value.nil? + @#{name} = new_value + else + if @do_validate + begin + tmp = Integer(new_value) + raise ArgumentError if tmp <= 0 + @#{name} = tmp + rescue ArgumentError + raise NotAvailableValueError.new('#{disp_name}', new_value) + end + else + @#{name} = new_value.to_i + end + end + end +EOC + end + + def boolean_writer(name, disp_name=name) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{name}=(new_value) + if new_value.nil? + @#{name} = new_value + else + if @do_validate and + ![true, false, "true", "false"].include?(new_value) + raise NotAvailableValueError.new('#{disp_name}', new_value) + end + if [true, false].include?(new_value) + @#{name} = new_value + else + @#{name} = new_value == "true" + end + end + end +EOC + end + + def def_children_accessor(accessor_name, plural_name) + module_eval(<<-EOC, *get_file_and_line_from_caller(2)) + def #{plural_name} + @#{accessor_name} + end + + def #{accessor_name}(*args) + if args.empty? + @#{accessor_name}.first + else + @#{accessor_name}[*args] + end + end + + def #{accessor_name}=(*args) + warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \ + "Don't use `#{accessor_name} = XXX'/`set_#{accessor_name}(XXX)'. " \ + "Those APIs are not sense of Ruby. " \ + "Use `#{plural_name} << XXX' instead of them.") + if args.size == 1 + @#{accessor_name}.push(args[0]) + else + @#{accessor_name}.__send__("[]=", *args) + end + end + alias_method(:set_#{accessor_name}, :#{accessor_name}=) +EOC + end + end + + class Element + + extend BaseModel + include Utils + + INDENT = " " + + MUST_CALL_VALIDATORS = {} + MODELS = [] + GET_ATTRIBUTES = [] + HAVE_CHILDREN_ELEMENTS = [] + TO_ELEMENT_METHODS = [] + NEED_INITIALIZE_VARIABLES = [] + PLURAL_FORMS = {} + + class << self + + def must_call_validators + MUST_CALL_VALIDATORS + end + def models + MODELS + end + def get_attributes + GET_ATTRIBUTES + end + def have_children_elements + HAVE_CHILDREN_ELEMENTS + end + def to_element_methods + TO_ELEMENT_METHODS + end + def need_initialize_variables + NEED_INITIALIZE_VARIABLES + end + def plural_forms + PLURAL_FORMS + end + + + def inherited(klass) + klass.const_set("MUST_CALL_VALIDATORS", {}) + klass.const_set("MODELS", []) + klass.const_set("GET_ATTRIBUTES", []) + klass.const_set("HAVE_CHILDREN_ELEMENTS", []) + klass.const_set("TO_ELEMENT_METHODS", []) + klass.const_set("NEED_INITIALIZE_VARIABLES", []) + klass.const_set("PLURAL_FORMS", {}) + + klass.module_eval(<<-EOC) + public + + @tag_name = name.split(/::/).last + @tag_name[0,1] = @tag_name[0,1].downcase + @have_content = false + + def self.must_call_validators + super.merge(MUST_CALL_VALIDATORS) + end + def self.models + MODELS + super + end + def self.get_attributes + GET_ATTRIBUTES + super + end + def self.have_children_elements + HAVE_CHILDREN_ELEMENTS + super + end + def self.to_element_methods + TO_ELEMENT_METHODS + super + end + def self.need_initialize_variables + NEED_INITIALIZE_VARIABLES + super + end + def self.plural_forms + super.merge(PLURAL_FORMS) + end + + + def self.install_must_call_validator(prefix, uri) + MUST_CALL_VALIDATORS[uri] = prefix + end + + def self.install_model(tag, uri, occurs=nil, getter=nil) + getter ||= tag + if m = MODELS.find {|t, u, o, g| t == tag and u == uri} + m[2] = occurs + else + MODELS << [tag, uri, occurs, getter] + end + end + + def self.install_get_attribute(name, uri, required=true, + type=nil, disp_name=nil, + element_name=nil) + disp_name ||= name + element_name ||= name + def_corresponded_attr_writer name, type, disp_name + convert_attr_reader name + if type == :boolean and /^is/ =~ name + alias_method "\#{$POSTMATCH}?", name + end + GET_ATTRIBUTES << [name, uri, required, element_name] + add_need_initialize_variable(disp_name) + end + + def self.def_corresponded_attr_writer(name, type=nil, disp_name=name) + case type + when :integer + integer_writer name, disp_name + when :positive_integer + positive_integer_writer name, disp_name + when :boolean + boolean_writer name, disp_name + when :w3cdtf, :rfc822, :rfc2822 + date_writer name, type, disp_name + else + attr_writer name + end + end + + def self.content_setup(type=nil) + def_corresponded_attr_writer "content", type + convert_attr_reader :content + @have_content = true + end + + def self.have_content? + @have_content + end + + def self.add_have_children_element(variable_name, plural_name) + HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name] + end + + def self.add_to_element_method(method_name) + TO_ELEMENT_METHODS << method_name + end + + def self.add_need_initialize_variable(variable_name) + NEED_INITIALIZE_VARIABLES << variable_name + end + + def self.add_plural_form(singular, plural) + PLURAL_FORMS[singular] = plural + end + + EOC + end + + def required_prefix + nil + end + + def required_uri + "" + end + + def install_ns(prefix, uri) + if self::NSPOOL.has_key?(prefix) + raise OverlappedPrefixError.new(prefix) + end + self::NSPOOL[prefix] = uri + end + + def tag_name + @tag_name + end + end + + attr_accessor :do_validate + + def initialize(do_validate=true, attrs={}) + @converter = nil + @do_validate = do_validate + initialize_variables(attrs) + end + + def tag_name + self.class.tag_name + end + + def full_name + tag_name + end + + def converter=(converter) + @converter = converter + targets = children.dup + self.class.have_children_elements.each do |variable_name, plural_name| + targets.concat(__send__(plural_name)) + end + targets.each do |target| + target.converter = converter unless target.nil? + end + end + + def convert(value) + if @converter + @converter.convert(value) + else + value + end + end + + def validate(ignore_unknown_element=true) + validate_attribute + __validate(ignore_unknown_element) + end + + def validate_for_stream(tags, ignore_unknown_element=true) + validate_attribute + __validate(ignore_unknown_element, tags, false) + end + + def setup_maker(maker) + target = maker_target(maker) + unless target.nil? + setup_maker_attributes(target) + setup_maker_element(target) + setup_maker_elements(target) + end + end + + def to_s(need_convert=true, indent='') + if self.class.have_content? + return "" unless @content + rv = tag(indent) do |next_indent| + h(@content) + end + else + rv = tag(indent) do |next_indent| + self.class.to_element_methods.collect do |method_name| + __send__(method_name, false, next_indent) + end + end + end + rv = convert(rv) if need_convert + rv + end + + private + def initialize_variables(attrs) + normalized_attrs = {} + attrs.each do |key, value| + normalized_attrs[key.to_s] = value + end + self.class.need_initialize_variables.each do |variable_name| + value = normalized_attrs[variable_name.to_s] + if value + __send__("#{variable_name}=", value) + else + instance_eval("@#{variable_name} = nil") + end + end + initialize_have_children_elements + @content = "" if self.class.have_content? + end + + def initialize_have_children_elements + self.class.have_children_elements.each do |variable_name, plural_name| + instance_eval("@#{variable_name} = []") + end + end + + def tag(indent, additional_attrs={}, &block) + next_indent = indent + INDENT + + attrs = collect_attrs + return "" if attrs.nil? + + attrs.update(additional_attrs) + start_tag = make_start_tag(indent, next_indent, attrs) + + if block + content = block.call(next_indent) + else + content = [] + end + + if content.is_a?(String) + content = [content] + start_tag << ">" + end_tag = "" + else + content = content.reject{|x| x.empty?} + if content.empty? + end_tag = "/>" + else + start_tag << ">\n" + end_tag = "\n#{indent}" + end + end + + start_tag + content.join("\n") + end_tag + end + + def make_start_tag(indent, next_indent, attrs) + start_tag = ["#{indent}<#{full_name}"] + unless attrs.empty? + start_tag << attrs.collect do |key, value| + %Q[#{h key}="#{h value}"] + end.join("\n#{next_indent}") + end + start_tag.join(" ") + end + + def collect_attrs + attrs = {} + _attrs.each do |name, required, alias_name| + value = __send__(alias_name || name) + return nil if required and value.nil? + next if value.nil? + return nil if attrs.has_key?(name) + attrs[name] = value + end + attrs + end + + def tag_name_with_prefix(prefix) + "#{prefix}:#{tag_name}" + end + + # For backward compatibility + def calc_indent + '' + end + + def maker_target(maker) + nil + end + + def setup_maker_attributes(target) + end + + def setup_maker_element(target) + self.class.need_initialize_variables.each do |var| + value = __send__(var) + if value.respond_to?("setup_maker") and + !not_need_to_call_setup_maker_variables.include?(var) + value.setup_maker(target) + else + setter = "#{var}=" + if target.respond_to?(setter) + target.__send__(setter, value) + end + end + end + end + + def not_need_to_call_setup_maker_variables + [] + end + + def setup_maker_elements(parent) + self.class.have_children_elements.each do |name, plural_name| + if parent.respond_to?(plural_name) + target = parent.__send__(plural_name) + __send__(plural_name).each do |elem| + elem.setup_maker(target) + end + end + end + end + + def set_next_element(tag_name, next_element) + klass = next_element.class + prefix = "" + prefix << "#{klass.required_prefix}_" if klass.required_prefix + key = "#{prefix}#{tag_name}" + if self.class.plural_forms.has_key?(key) + ary = __send__("#{self.class.plural_forms[key]}") + ary << next_element + else + __send__("#{prefix}#{tag_name}=", next_element) + end + end + + def children + rv = [] + self.class.models.each do |name, uri, occurs, getter| + value = __send__(getter) + next if value.nil? + value = [value] unless value.is_a?(Array) + value.each do |v| + rv << v if v.is_a?(Element) + end + end + rv + end + + def _tags + rv = [] + self.class.models.each do |name, uri, occurs, getter| + value = __send__(getter) + next if value.nil? + if value.is_a?(Array) + rv.concat([[uri, name]] * value.size) + else + rv << [uri, name] + end + end + rv + end + + def _attrs + self.class.get_attributes.collect do |name, uri, required, element_name| + [element_name, required, name] + end + end + + def __validate(ignore_unknown_element, tags=_tags, recursive=true) + if recursive + children.compact.each do |child| + child.validate + end + end + must_call_validators = self.class.must_call_validators + tags = tag_filter(tags.dup) + p tags if DEBUG + must_call_validators.each do |uri, prefix| + _validate(ignore_unknown_element, tags[uri], uri) + meth = "#{prefix}_validate" + if respond_to?(meth, true) + __send__(meth, ignore_unknown_element, tags[uri], uri) + end + end + end + + def validate_attribute + _attrs.each do |a_name, required, alias_name| + if required and __send__(alias_name || a_name).nil? + raise MissingAttributeError.new(tag_name, a_name) + end + end + end + + def _validate(ignore_unknown_element, tags, uri, models=self.class.models) + count = 1 + do_redo = false + not_shift = false + tag = nil + models = models.find_all {|model| model[1] == uri} + element_names = models.collect {|model| model[0]} + if tags + tags_size = tags.size + tags = tags.sort_by {|x| element_names.index(x) || tags_size} + end + + models.each_with_index do |model, i| + name, model_uri, occurs, getter = model + + if DEBUG + p "before" + p tags + p model + end + + if not_shift + not_shift = false + elsif tags + tag = tags.shift + end + + if DEBUG + p "mid" + p count + end + + case occurs + when '?' + if count > 2 + raise TooMuchTagError.new(name, tag_name) + else + if name == tag + do_redo = true + else + not_shift = true + end + end + when '*' + if name == tag + do_redo = true + else + not_shift = true + end + when '+' + if name == tag + do_redo = true + else + if count > 1 + not_shift = true + else + raise MissingTagError.new(name, tag_name) + end + end + else + if name == tag + if models[i+1] and models[i+1][0] != name and + tags and tags.first == name + raise TooMuchTagError.new(name, tag_name) + end + else + raise MissingTagError.new(name, tag_name) + end + end + + if DEBUG + p "after" + p not_shift + p do_redo + p tag + end + + if do_redo + do_redo = false + count += 1 + redo + else + count = 1 + end + + end + + if !ignore_unknown_element and !tags.nil? and !tags.empty? + raise NotExpectedTagError.new(tags.first, uri, tag_name) + end + + end + + def tag_filter(tags) + rv = {} + tags.each do |tag| + rv[tag[0]] = [] unless rv.has_key?(tag[0]) + rv[tag[0]].push(tag[1]) + end + rv + end + + end + + module RootElementMixin + + include XMLStyleSheetMixin + + attr_reader :output_encoding + + def initialize(rss_version, version=nil, encoding=nil, standalone=nil) + super() + @rss_version = rss_version + @version = version || '1.0' + @encoding = encoding + @standalone = standalone + @output_encoding = nil + end + + def output_encoding=(enc) + @output_encoding = enc + self.converter = Converter.new(@output_encoding, @encoding) + end + + def setup_maker(maker) + maker.version = version + maker.encoding = encoding + maker.standalone = standalone + + xml_stylesheets.each do |xss| + xss.setup_maker(maker) + end + + setup_maker_elements(maker) + end + + def to_xml(version=nil, &block) + if version.nil? or version == @rss_version + to_s + else + RSS::Maker.make(version) do |maker| + setup_maker(maker) + block.call(maker) if block + end.to_s + end + end + + private + def tag(indent, attrs={}, &block) + rv = xmldecl + xml_stylesheet_pi + rv << super(indent, ns_declarations.merge(attrs), &block) + rv + end + + def xmldecl + rv = %Q[\n" + rv + end + + def ns_declarations + decls = {} + self.class::NSPOOL.collect do |prefix, uri| + prefix = ":#{prefix}" unless prefix.empty? + decls["xmlns#{prefix}"] = uri + end + decls + end + + def setup_maker_elements(maker) + channel.setup_maker(maker) if channel + image.setup_maker(maker) if image + textinput.setup_maker(maker) if textinput + super(maker) + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/syndication.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/syndication.rb new file mode 100644 index 00000000..93d35c89 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/syndication.rb @@ -0,0 +1,64 @@ +require "rss/1.0" + +module RSS + + SY_PREFIX = 'sy' + SY_URI = "http://purl.org/rss/1.0/modules/syndication/" + + RDF.install_ns(SY_PREFIX, SY_URI) + + module SyndicationModel + + extend BaseModel + + ELEMENTS = [] + + def self.append_features(klass) + super + + klass.install_must_call_validator(SY_PREFIX, SY_URI) + klass.module_eval do + [ + ["updatePeriod"], + ["updateFrequency", :positive_integer] + ].each do |name, type| + install_text_element(name, SY_URI, "?", + "#{SY_PREFIX}_#{name}", type, + "#{SY_PREFIX}:#{name}") + end + + %w(updateBase).each do |name| + install_date_element(name, SY_URI, "?", + "#{SY_PREFIX}_#{name}", 'w3cdtf', name) + end + + alias_method(:_sy_updatePeriod=, :sy_updatePeriod=) + def sy_updatePeriod=(new_value) + new_value = new_value.strip + validate_sy_updatePeriod(new_value) if @do_validate + self._sy_updatePeriod = new_value + end + end + end + + private + SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly) + def validate_sy_updatePeriod(value) + unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value) + raise NotAvailableValueError.new("updatePeriod", value) + end + end + end + + class RDF + class Channel; include SyndicationModel; end + end + + prefix_size = SY_PREFIX.size + 1 + SyndicationModel::ELEMENTS.uniq! + SyndicationModel::ELEMENTS.each do |full_name| + name = full_name[prefix_size..-1] + BaseListener.install_get_text_element(SY_URI, name, "#{full_name}=") + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/taxonomy.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/taxonomy.rb new file mode 100644 index 00000000..8caa25e2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/taxonomy.rb @@ -0,0 +1,145 @@ +require "rss/1.0" +require "rss/dublincore" + +module RSS + + TAXO_PREFIX = "taxo" + TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/" + + RDF.install_ns(TAXO_PREFIX, TAXO_URI) + + TAXO_ELEMENTS = [] + + %w(link).each do |name| + full_name = "#{TAXO_PREFIX}_#{name}" + BaseListener.install_get_text_element(TAXO_URI, name, "#{full_name}=") + TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}" + end + + %w(topic topics).each do |name| + class_name = Utils.to_class_name(name) + BaseListener.install_class_name(TAXO_URI, name, "Taxonomy#{class_name}") + TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}" + end + + module TaxonomyTopicsModel + extend BaseModel + + def self.append_features(klass) + super + + klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI) + %w(topics).each do |name| + klass.install_have_child_element(name, TAXO_URI, "?", + "#{TAXO_PREFIX}_#{name}") + end + end + + class TaxonomyTopics < Element + include RSS10 + + Bag = ::RSS::RDF::Bag + + class << self + def required_prefix + TAXO_PREFIX + end + + def required_uri + TAXO_URI + end + end + + @tag_name = "topics" + + install_have_child_element("Bag", RDF::URI, nil) + install_must_call_validator('rdf', RDF::URI) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.Bag = args[0] + end + self.Bag ||= Bag.new + end + + def full_name + tag_name_with_prefix(TAXO_PREFIX) + end + + def maker_target(target) + target.taxo_topics + end + + def resources + if @Bag + @Bag.lis.collect do |li| + li.resource + end + else + [] + end + end + end + end + + module TaxonomyTopicModel + extend BaseModel + + def self.append_features(klass) + super + var_name = "#{TAXO_PREFIX}_topic" + klass.install_have_children_element("topic", TAXO_URI, "*", var_name) + end + + class TaxonomyTopic < Element + include RSS10 + + include DublinCoreModel + include TaxonomyTopicsModel + + class << self + def required_prefix + TAXO_PREFIX + end + + def required_uri + TAXO_URI + end + end + + @tag_name = "topic" + + install_get_attribute("about", ::RSS::RDF::URI, true, nil, nil, + "#{RDF::PREFIX}:about") + install_text_element("link", TAXO_URI, "?", "#{TAXO_PREFIX}_link") + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.about = args[0] + end + end + + def full_name + tag_name_with_prefix(TAXO_PREFIX) + end + + def maker_target(target) + target.new_taxo_topic + end + end + end + + class RDF + include TaxonomyTopicModel + class Channel + include TaxonomyTopicsModel + end + class Item; include TaxonomyTopicsModel; end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/trackback.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/trackback.rb new file mode 100644 index 00000000..ee2491f3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/trackback.rb @@ -0,0 +1,288 @@ +require 'rss/1.0' +require 'rss/2.0' + +module RSS + + TRACKBACK_PREFIX = 'trackback' + TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/' + + RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) + Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) + + module TrackBackUtils + private + def trackback_validate(ignore_unknown_element, tags, uri) + return if tags.nil? + if tags.find {|tag| tag == "about"} and + !tags.find {|tag| tag == "ping"} + raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name) + end + end + end + + module BaseTrackBackModel + + ELEMENTS = %w(ping about) + + def append_features(klass) + super + + unless klass.class == Module + klass.module_eval {include TrackBackUtils} + + klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI) + %w(ping).each do |name| + var_name = "#{TRACKBACK_PREFIX}_#{name}" + klass_name = "TrackBack#{Utils.to_class_name(name)}" + klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__) + remove_method :#{var_name} + def #{var_name} + @#{var_name} and @#{var_name}.value + end + + remove_method :#{var_name}= + def #{var_name}=(value) + @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value) + end + EOC + end + + [%w(about s)].each do |name, postfix| + var_name = "#{TRACKBACK_PREFIX}_#{name}" + klass_name = "TrackBack#{Utils.to_class_name(name)}" + klass.install_have_children_element(name, TRACKBACK_URI, "*", + var_name) + klass.module_eval(<<-EOC, __FILE__, __LINE__) + remove_method :#{var_name} + def #{var_name}(*args) + if args.empty? + @#{var_name}.first and @#{var_name}.first.value + else + ret = @#{var_name}.__send__("[]", *args) + if ret.is_a?(Array) + ret.collect {|x| x.value} + else + ret.value + end + end + end + + remove_method :#{var_name}= + remove_method :set_#{var_name} + def #{var_name}=(*args) + if args.size == 1 + item = Utils.new_with_value_if_need(#{klass_name}, args[0]) + @#{var_name}.push(item) + else + new_val = args.last + if new_val.is_a?(Array) + new_val = new_value.collect do |val| + Utils.new_with_value_if_need(#{klass_name}, val) + end + else + new_val = Utils.new_with_value_if_need(#{klass_name}, new_val) + end + @#{var_name}.__send__("[]=", *(args[0..-2] + [new_val])) + end + end + alias set_#{var_name} #{var_name}= + EOC + end + end + end + end + + module TrackBackModel10 + extend BaseModel + extend BaseTrackBackModel + + class TrackBackPing < Element + include RSS10 + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + @tag_name = "ping" + + [ + ["resource", ::RSS::RDF::URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{::RSS::RDF::PREFIX}:#{name}") + end + + alias_method(:value, :resource) + alias_method(:value=, :resource=) + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.resource = args[0] + end + end + + def full_name + tag_name_with_prefix(TRACKBACK_PREFIX) + end + end + + class TrackBackAbout < Element + include RSS10 + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + @tag_name = "about" + + [ + ["resource", ::RSS::RDF::URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required, nil, nil, + "#{::RSS::RDF::PREFIX}:#{name}") + end + + alias_method(:value, :resource) + alias_method(:value=, :resource=) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.resource = args[0] + end + end + + def full_name + tag_name_with_prefix(TRACKBACK_PREFIX) + end + + private + def maker_target(abouts) + abouts.new_about + end + + def setup_maker_attributes(about) + about.resource = self.resource + end + + end + end + + module TrackBackModel20 + extend BaseModel + extend BaseTrackBackModel + + class TrackBackPing < Element + include RSS09 + + @tag_name = "ping" + + content_setup + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + alias_method(:value, :content) + alias_method(:value=, :content=) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.content = args[0] + end + end + + def full_name + tag_name_with_prefix(TRACKBACK_PREFIX) + end + + end + + class TrackBackAbout < Element + include RSS09 + + @tag_name = "about" + + content_setup + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + alias_method(:value, :content) + alias_method(:value=, :content=) + + def initialize(*args) + if Utils.element_initialize_arguments?(args) + super + else + super() + self.content = args[0] + end + end + + def full_name + tag_name_with_prefix(TRACKBACK_PREFIX) + end + + end + end + + class RDF + class Item; include TrackBackModel10; end + end + + class Rss + class Channel + class Item; include TrackBackModel20; end + end + end + + BaseTrackBackModel::ELEMENTS.each do |name| + class_name = Utils.to_class_name(name) + BaseListener.install_class_name(TRACKBACK_URI, name, + "TrackBack#{class_name}") + end + + BaseTrackBackModel::ELEMENTS.collect! {|name| "#{TRACKBACK_PREFIX}_#{name}"} +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/utils.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/utils.rb new file mode 100644 index 00000000..b242a722 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/utils.rb @@ -0,0 +1,37 @@ +module RSS + module Utils + module_function + + # Convert a name_with_underscores to CamelCase. + def to_class_name(name) + name.split(/_/).collect do |part| + "#{part[0, 1].upcase}#{part[1..-1]}" + end.join("") + end + + def get_file_and_line_from_caller(i=0) + file, line, = caller[i].split(':') + [file, line.to_i] + end + + # escape '&', '"', '<' and '>' for use in HTML. + def html_escape(s) + s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/ "text/xsl", + "css" => "text/css", + } + + attr_accessor(*ATTRIBUTES) + attr_accessor(:do_validate) + def initialize(*attrs) + @do_validate = true + ATTRIBUTES.each do |attr| + __send__("#{attr}=", nil) + end + vars = ATTRIBUTES.dup + vars.unshift(:do_validate) + attrs.each do |name, value| + if vars.include?(name.to_s) + __send__("#{name}=", value) + end + end + end + + def to_s + rv = "" + if @href + rv << %Q[] + end + rv + end + + remove_method(:href=) + def href=(value) + @href = value + if @href and @type.nil? + @type = guess_type(@href) + end + @href + end + + remove_method(:alternate=) + def alternate=(value) + if value.nil? or /\A(?:yes|no)\z/ =~ value + @alternate = value + else + if @do_validate + args = ["?xml-stylesheet?", %Q[alternate="#{value}"]] + raise NotAvailableValueError.new(*args) + end + end + @alternate + end + + def setup_maker(maker) + xss = maker.xml_stylesheets.new_xml_stylesheet + ATTRIBUTES.each do |attr| + xss.__send__("#{attr}=", __send__(attr)) + end + end + + private + def guess_type(filename) + /\.([^.]+)$/ =~ filename + GUESS_TABLE[$1] + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/xmlparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/xmlparser.rb new file mode 100644 index 00000000..3dfe7d46 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/xmlparser.rb @@ -0,0 +1,93 @@ +begin + require "xml/parser" +rescue LoadError + require "xmlparser" +end + +begin + require "xml/encoding-ja" +rescue LoadError + require "xmlencoding-ja" + if defined?(Kconv) + module XMLEncoding_ja + class SJISHandler + include Kconv + end + end + end +end + +module XML + class Parser + unless defined?(Error) + Error = ::XMLParserError + end + end +end + +module RSS + + class REXMLLikeXMLParser < ::XML::Parser + + include ::XML::Encoding_ja + + def listener=(listener) + @listener = listener + end + + def startElement(name, attrs) + @listener.tag_start(name, attrs) + end + + def endElement(name) + @listener.tag_end(name) + end + + def character(data) + @listener.text(data) + end + + def xmlDecl(version, encoding, standalone) + @listener.xmldecl(version, encoding, standalone == 1) + end + + def processingInstruction(target, content) + @listener.instruction(target, content) + end + + end + + class XMLParserParser < BaseParser + + class << self + def listener + XMLParserListener + end + end + + private + def _parse + begin + parser = REXMLLikeXMLParser.new + parser.listener = @listener + parser.parse(@rss) + rescue ::XML::Parser::Error => e + raise NotWellFormedError.new(parser.line){e.message} + end + end + + end + + class XMLParserListener < BaseListener + + include ListenerMixin + + def xmldecl(version, encoding, standalone) + super + # Encoding is converted to UTF-8 when XMLParser parses XML. + @encoding = 'UTF-8' + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/xmlscanner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/xmlscanner.rb new file mode 100644 index 00000000..61b9fa6b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rss/xmlscanner.rb @@ -0,0 +1,121 @@ +require 'xmlscan/scanner' +require 'stringio' + +module RSS + + class XMLScanParser < BaseParser + + class << self + def listener + XMLScanListener + end + end + + private + def _parse + begin + if @rss.is_a?(String) + input = StringIO.new(@rss) + else + input = @rss + end + scanner = XMLScan::XMLScanner.new(@listener) + scanner.parse(input) + rescue XMLScan::Error => e + lineno = e.lineno || scanner.lineno || input.lineno + raise NotWellFormedError.new(lineno){e.message} + end + end + + end + + class XMLScanListener < BaseListener + + include XMLScan::Visitor + include ListenerMixin + + ENTITIES = { + 'lt' => '<', + 'gt' => '>', + 'amp' => '&', + 'quot' => '"', + 'apos' => '\'' + } + + def on_xmldecl_version(str) + @version = str + end + + def on_xmldecl_encoding(str) + @encoding = str + end + + def on_xmldecl_standalone(str) + @standalone = str + end + + def on_xmldecl_end + xmldecl(@version, @encoding, @standalone == "yes") + end + + alias_method(:on_pi, :instruction) + alias_method(:on_chardata, :text) + alias_method(:on_cdata, :text) + + def on_etag(name) + tag_end(name) + end + + def on_entityref(ref) + text(entity(ref)) + end + + def on_charref(code) + text([code].pack('U')) + end + + alias_method(:on_charref_hex, :on_charref) + + def on_stag(name) + @attrs = {} + end + + def on_attribute(name) + @attrs[name] = @current_attr = '' + end + + def on_attr_value(str) + @current_attr << str + end + + def on_attr_entityref(ref) + @current_attr << entity(ref) + end + + def on_attr_charref(code) + @current_attr << [code].pack('U') + end + + alias_method(:on_attr_charref_hex, :on_attr_charref) + + def on_stag_end(name) + tag_start(name, @attrs) + end + + def on_stag_end_empty(name) + tag_start(name, @attrs) + tag_end(name) + end + + private + def entity(ref) + ent = ENTITIES[ref] + if ent + ent + else + wellformed_error("undefined entity: #{ref}") + end + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rubyunit.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rubyunit.rb new file mode 100644 index 00000000..1aca3786 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/rubyunit.rb @@ -0,0 +1,6 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'runit/testcase' +require 'test/unit' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/assert.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/assert.rb new file mode 100644 index 00000000..c752b19a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/assert.rb @@ -0,0 +1,73 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertions' +require 'runit/error' + +module RUNIT + module Assert + include Test::Unit::Assertions + + def setup_assert + end + + def assert_no_exception(*args, &block) + assert_nothing_raised(*args, &block) + end + + # To deal with the fact that RubyUnit does not check that the + # regular expression is, indeed, a regular expression, if it is + # not, we do our own assertion using the same semantics as + # RubyUnit + def assert_match(actual_string, expected_re, message="") + _wrap_assertion { + full_message = build_message(message, "Expected to match ", actual_string, expected_re) + assert_block(full_message) { + expected_re =~ actual_string + } + Regexp.last_match + } + end + + def assert_not_nil(actual, message="") + assert(!actual.nil?, message) + end + + def assert_not_match(actual_string, expected_re, message="") + assert_no_match(expected_re, actual_string, message) + end + + def assert_matches(*args) + assert_match(*args) + end + + def assert_fail(message="") + flunk(message) + end + + def assert_equal_float(expected, actual, delta, message="") + assert_in_delta(expected, actual, delta, message) + end + + def assert_send(object, method, *args) + super([object, method, *args]) + end + + def assert_exception(exception, message="", &block) + assert_raises(exception, message, &block) + end + + def assert_respond_to(method, object, message="") + if (called_internally?) + super + else + super(object, method, message) + end + end + + def called_internally? + /assertions\.rb/.match(caller[1]) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/cui/testrunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/cui/testrunner.rb new file mode 100644 index 00000000..d521ec16 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/cui/testrunner.rb @@ -0,0 +1,51 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/ui/console/testrunner' +require 'runit/testresult' + +module RUNIT + module CUI + class TestRunner < Test::Unit::UI::Console::TestRunner + @@quiet_mode = false + + def self.run(suite) + self.new().run(suite) + end + + def initialize + super nil + end + + def run(suite, quiet_mode=@@quiet_mode) + @suite = suite + def @suite.suite + self + end + @output_level = (quiet_mode ? Test::Unit::UI::PROGRESS_ONLY : Test::Unit::UI::VERBOSE) + start + end + + def create_mediator(suite) + mediator = Test::Unit::UI::TestRunnerMediator.new(suite) + class << mediator + attr_writer :result_delegate + def create_result + return @result_delegate.create_result + end + end + mediator.result_delegate = self + return mediator + end + + def create_result + return RUNIT::TestResult.new + end + + def self.quiet_mode=(boolean) + @@quiet_mode = boolean + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/error.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/error.rb new file mode 100644 index 00000000..4a727fb0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/error.rb @@ -0,0 +1,9 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertionfailederror.rb' + +module RUNIT + AssertionFailedError = Test::Unit::AssertionFailedError +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testcase.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testcase.rb new file mode 100644 index 00000000..4576cb86 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testcase.rb @@ -0,0 +1,45 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'runit/testresult' +require 'runit/testsuite' +require 'runit/assert' +require 'runit/error' +require 'test/unit/testcase' + +module RUNIT + class TestCase < Test::Unit::TestCase + include RUNIT::Assert + + def self.suite + method_names = instance_methods(true) + tests = method_names.delete_if { |method_name| method_name !~ /^test/ } + suite = TestSuite.new(name) + tests.each { + |test| + catch(:invalid_test) { + suite << new(test, name) + } + } + return suite + end + + def initialize(test_name, suite_name=self.class.name) + super(test_name) + end + + def assert_equals(*args) + assert_equal(*args) + end + + def name + super.sub(/^(.*?)\((.*)\)$/, '\2#\1') + end + + def run(result, &progress_block) + progress_block = proc {} unless (block_given?) + super(result, &progress_block) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testresult.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testresult.rb new file mode 100644 index 00000000..7f707781 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testresult.rb @@ -0,0 +1,44 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/testresult' + +module RUNIT + class TestResult < Test::Unit::TestResult + attr_reader(:errors, :failures) + def succeed? + return passed? + end + def failure_size + return failure_count + end + def run_asserts + return assertion_count + end + def error_size + return error_count + end + def run_tests + return run_count + end + def add_failure(failure) + def failure.at + return location + end + def failure.err + return message + end + super(failure) + end + def add_error(error) + def error.at + return location + end + def error.err + return exception + end + super(error) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testsuite.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testsuite.rb new file mode 100644 index 00000000..63baf657 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/testsuite.rb @@ -0,0 +1,26 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/testsuite' + +module RUNIT + class TestSuite < Test::Unit::TestSuite + def add_test(*args) + add(*args) + end + + def add(*args) + self.<<(*args) + end + + def count_test_cases + return size + end + + def run(result, &progress_block) + progress_block = proc {} unless (block_given?) + super(result, &progress_block) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/topublic.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/topublic.rb new file mode 100644 index 00000000..566f0dd3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/runit/topublic.rb @@ -0,0 +1,8 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module RUNIT + module ToPublic + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/scanf.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/scanf.rb new file mode 100644 index 00000000..a49ce694 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/scanf.rb @@ -0,0 +1,702 @@ +# scanf for Ruby +# +# $Revision: 11708 $ +# $Id: scanf.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# $Author: shyouhei $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# +# A product of the Austin Ruby Codefest (Austin, Texas, August 2002) + +=begin + +=scanf for Ruby + +==Description + +scanf for Ruby is an implementation of the C function scanf(3), +modified as necessary for Ruby compatibility. + +The methods provided are String#scanf, IO#scanf, and +Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf. IO#scanf +can be used on any IO stream, including file handles and sockets. +scanf can be called either with or without a block. + +scanf for Ruby scans an input string or stream according to a +format, as described below ("Conversions"), and returns an +array of matches between the format and the input. The format is +defined in a string, and is similar (though not identical) to the +formats used in Kernel#printf and Kernel#sprintf. + +The format may contain conversion specifiers, which tell scanf +what form (type) each particular matched substring should be converted +to (e.g., decimal integer, floating point number, literal string, +etc.) The matches and conversions take place from left to right, and +the conversions themselves are returned as an array. + +The format string may also contain characters other than those in the +conversion specifiers. White space (blanks, tabs, or newlines) in the +format string matches any amount of white space, including none, in +the input. Everything else matches only itself. + +Scanning stops, and scanf returns, when any input character fails to +match the specifications in the format string, or when input is +exhausted, or when everything in the format string has been +matched. All matches found up to the stopping point are returned in +the return array (or yielded to the block, if a block was given). + + +==Basic usage + + require 'scanf.rb' + + # String#scanf and IO#scanf take a single argument (a format string) + array = aString.scanf("%d%s") + array = anIO.scanf("%d%s") + + # Kernel#scanf reads from STDIN + array = scanf("%d%s") + +==Block usage + +When called with a block, scanf keeps scanning the input, cycling back +to the beginning of the format string, and yields a new array of +conversions to the block every time the format string is matched +(including partial matches, but not including complete failures). The +actual return value of scanf when called with a block is an array +containing the results of all the executions of the block. + + str = "123 abc 456 def 789 ghi" + str.scanf("%d%s") { |num,str| [ num * 2, str.upcase ] } + # => [[246, "ABC"], [912, "DEF"], [1578, "GHI"]] + +==Conversions + +The single argument to scanf is a format string, which generally +includes one or more conversion specifiers. Conversion specifiers +begin with the percent character ('%') and include information about +what scanf should next scan for (string, decimal number, single +character, etc.). + +There may be an optional maximum field width, expressed as a decimal +integer, between the % and the conversion. If no width is given, a +default of `infinity' is used (with the exception of the %c specifier; +see below). Otherwise, given a field width of n for a given +conversion, at most n characters are scanned in processing +that conversion. Before conversion begins, most conversions skip +white space in the input string; this white space is not counted +against the field width. + +The following conversions are available. (See the files EXAMPLES +and tests/scanftests.rb for examples.) + +[%] + Matches a literal `%'. That is, `%%' in the format string matches a + single input `%' character. No conversion is done, and the resulting + '%' is not included in the return array. + +[d] + Matches an optionally signed decimal integer. + +[u] + Same as d. + +[i] + Matches an optionally signed integer. The integer is read in base + 16 if it begins with `0x' or `0X', in base 8 if it begins with `0', + and in base 10 other- wise. Only characters that correspond to the + base are recognized. + +[o] + Matches an optionally signed octal integer. + +[x,X] + Matches an optionally signed hexadecimal integer, + +[f,g,e,E] + Matches an optionally signed floating-point number. + +[s] + Matches a sequence of non-white-space character. The input string stops at + white space or at the maximum field width, whichever occurs first. + +[c] + Matches a single character, or a sequence of n characters if a + field width of n is specified. The usual skip of leading white + space is suppressed. To skip white space first, use an explicit space in + the format. + +[[] + Matches a nonempty sequence of characters from the specified set + of accepted characters. The usual skip of leading white space is + suppressed. This bracketed sub-expression is interpreted exactly like a + character class in a Ruby regular expression. (In fact, it is placed as-is + in a regular expression.) The matching against the input string ends with + the appearance of a character not in (or, with a circumflex, in) the set, + or when the field width runs out, whichever comes first. + +===Assignment suppression + +To require that a particular match occur, but without including the result +in the return array, place the assignment suppression flag, which is +the star character ('*'), immediately after the leading '%' of a format +specifier (just before the field width, if any). + +==Examples + +See the files EXAMPLES and tests/scanftests.rb. + +==scanf for Ruby compared with scanf in C + +scanf for Ruby is based on the C function scanf(3), but with modifications, +dictated mainly by the underlying differences between the languages. + +===Unimplemented flags and specifiers + +* The only flag implemented in scanf for Ruby is '*' (ignore + upcoming conversion). Many of the flags available in C versions of scanf(4) + have to do with the type of upcoming pointer arguments, and are literally + meaningless in Ruby. + +* The n specifier (store number of characters consumed so far in + next pointer) is not implemented. + +* The p specifier (match a pointer value) is not implemented. + +===Altered specifiers + +[o,u,x,X] + In scanf for Ruby, all of these specifiers scan for an optionally signed + integer, rather than for an unsigned integer like their C counterparts. + +===Return values + +scanf for Ruby returns an array of successful conversions, whereas +scanf(3) returns the number of conversions successfully +completed. (See below for more details on scanf for Ruby's return +values.) + +==Return values + +Without a block, scanf returns an array containing all the conversions +it has found. If none are found, scanf will return an empty array. An +unsuccesful match is never ignored, but rather always signals the end +of the scanning operation. If the first unsuccessful match takes place +after one or more successful matches have already taken place, the +returned array will contain the results of those successful matches. + +With a block scanf returns a 'map'-like array of transformations from +the block -- that is, an array reflecting what the block did with each +yielded result from the iterative scanf operation. (See "Block +usage", above.) + +==Test suite + +scanf for Ruby includes a suite of unit tests (requiring the +TestUnit package), which can be run with the command ruby +tests/scanftests.rb or the command make test. + +==Current limitations and bugs + +When using IO#scanf under Windows, make sure you open your files in +binary mode: + + File.open("filename", "rb") + +so that scanf can keep track of characters correctly. + +Support for character classes is reasonably complete (since it +essentially piggy-backs on Ruby's regular expression handling of +character classes), but users are advised that character class testing +has not been exhaustive, and that they should exercise some caution +in using any of the more complex and/or arcane character class +idioms. + + +==Technical notes + +===Rationale behind scanf for Ruby + +The impetus for a scanf implementation in Ruby comes chiefly from the fact +that existing pattern matching operations, such as Regexp#match and +String#scan, return all results as strings, which have to be converted to +integers or floats explicitly in cases where what's ultimately wanted are +integer or float values. + +===Design of scanf for Ruby + +scanf for Ruby is essentially a -to- converter. + +When scanf is called, a FormatString object is generated from the +format string ("%d%s...") argument. The FormatString object breaks the +format string down into atoms ("%d", "%5f", "blah", etc.), and from +each atom it creates a FormatSpecifier object, which it +saves. + +Each FormatSpecifier has a regular expression fragment and a "handler" +associated with it. For example, the regular expression fragment +associated with the format "%d" is "([-+]?\d+)", and the handler +associated with it is a wrapper around String#to_i. scanf itself calls +FormatString#match, passing in the input string. FormatString#match +iterates through its FormatSpecifiers; for each one, it matches the +corresponding regular expression fragment against the string. If +there's a match, it sends the matched string to the handler associated +with the FormatSpecifier. + +Thus, to follow up the "%d" example: if "123" occurs in the input +string when a FormatSpecifier consisting of "%d" is reached, the "123" +will be matched against "([-+]?\d+)", and the matched string will be +rendered into an integer by a call to to_i. + +The rendered match is then saved to an accumulator array, and the +input string is reduced to the post-match substring. Thus the string +is "eaten" from the left as the FormatSpecifiers are applied in +sequence. (This is done to a duplicate string; the original string is +not altered.) + +As soon as a regular expression fragment fails to match the string, or +when the FormatString object runs out of FormatSpecifiers, scanning +stops and results accumulated so far are returned in an array. + +==License and copyright + +Copyright:: (c) 2002-2003 David Alan Black +License:: Distributed on the same licensing terms as Ruby itself + +==Warranty disclaimer + +This software is provided "as is" and without any express or implied +warranties, including, without limitation, the implied warranties of +merchantibility and fitness for a particular purpose. + +==Credits and acknowledgements + +scanf for Ruby was developed as the major activity of the Austin +Ruby Codefest (Austin, Texas, August 2002). + +Principal author:: David Alan Black (mailto:dblack@superlink.net) +Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com) +Project contributors:: Nolan Darilek, Jason Johnston + +Thanks to Hal Fulton for hosting the Codefest. + +Thanks to Matz for suggestions about the class design. + +Thanks to Gavin Sinclair for some feedback on the documentation. + +The text for parts of this document, especially the Description and +Conversions sections, above, were adapted from the Linux Programmer's +Manual manpage for scanf(3), dated 1995-11-01. + +==Bugs and bug reports + +scanf for Ruby is based on something of an amalgam of C scanf +implementations and documentation, rather than on a single canonical +description. Suggestions for features and behaviors which appear in +other scanfs, and would be meaningful in Ruby, are welcome, as are +reports of suspicious behaviors and/or bugs. (Please see "Credits and +acknowledgements", above, for email addresses.) + +=end + +module Scanf + + class FormatSpecifier + + attr_reader :re_string, :matched_string, :conversion, :matched + + private + + def skip; /^\s*%\*/.match(@spec_string); end + + def extract_float(s); s.to_f if s &&! skip; end + def extract_decimal(s); s.to_i if s &&! skip; end + def extract_hex(s); s.hex if s &&! skip; end + def extract_octal(s); s.oct if s &&! skip; end + def extract_integer(s); Integer(s) if s &&! skip; end + def extract_plain(s); s unless skip; end + + def nil_proc(s); nil; end + + public + + def to_s + @spec_string + end + + def count_space? + /(?:\A|\S)%\*?\d*c|\[/.match(@spec_string) + end + + def initialize(str) + @spec_string = str + h = '[A-Fa-f0-9]' + + @re_string, @handler = + case @spec_string + + # %[[:...:]] + when /%\*?(\[\[:[a-z]+:\]\])/ + [ "(#{$1}+)", :extract_plain ] + + # %5[[:...:]] + when /%\*?(\d+)(\[\[:[a-z]+:\]\])/ + [ "(#{$2}{1,#{$1}})", :extract_plain ] + + # %[...] + when /%\*?\[([^\]]*)\]/ + yes = $1 + if /^\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end + [ "([#{yes}]+)(?=[#{no}]|\\z)", :extract_plain ] + + # %5[...] + when /%\*?(\d+)\[([^\]]*)\]/ + yes = $2 + w = $1 + [ "([#{yes}]{1,#{w}})", :extract_plain ] + + # %i + when /%\*?i/ + [ "([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\d+)))", :extract_integer ] + + # %5i + when /%\*?(\d+)i/ + n = $1.to_i + s = "(" + if n > 1 then s += "[1-9]\\d{1,#{n-1}}|" end + if n > 1 then s += "0[0-7]{1,#{n-1}}|" end + if n > 2 then s += "[-+]0[0-7]{1,#{n-2}}|" end + if n > 2 then s += "[-+][1-9]\\d{1,#{n-2}}|" end + if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end + if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end + s += "\\d" + s += ")" + [ s, :extract_integer ] + + # %d, %u + when /%\*?[du]/ + [ '([-+]?\d+)', :extract_decimal ] + + # %5d, %5u + when /%\*?(\d+)[du]/ + n = $1.to_i + s = "(" + if n > 1 then s += "[-+]\\d{1,#{n-1}}|" end + s += "\\d{1,#{$1}})" + [ s, :extract_decimal ] + + # %x + when /%\*?[Xx]/ + [ "([-+]?(?:0[Xx])?#{h}+)", :extract_hex ] + + # %5x + when /%\*?(\d+)[Xx]/ + n = $1.to_i + s = "(" + if n > 3 then s += "[-+]0[Xx]#{h}{1,#{n-3}}|" end + if n > 2 then s += "0[Xx]#{h}{1,#{n-2}}|" end + if n > 1 then s += "[-+]#{h}{1,#{n-1}}|" end + s += "#{h}{1,#{n}}" + s += ")" + [ s, :extract_hex ] + + # %o + when /%\*?o/ + [ '([-+]?[0-7]+)', :extract_octal ] + + # %5o + when /%\*?(\d+)o/ + [ "([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})", :extract_octal ] + + # %f + when /%\*?f/ + [ '([-+]?((\d+(?>(?=[^\d.]|$)))|(\d*(\.(\d*([eE][-+]?\d+)?)))))', :extract_float ] + + # %5f + when /%\*?(\d+)f/ + [ "(\\S{1,#{$1}})", :extract_float ] + + # %5s + when /%\*?(\d+)s/ + [ "(\\S{1,#{$1}})", :extract_plain ] + + # %s + when /%\*?s/ + [ '(\S+)', :extract_plain ] + + # %c + when /\s%\*?c/ + [ "\\s*(.)", :extract_plain ] + + # %c + when /%\*?c/ + [ "(.)", :extract_plain ] + + # %5c (whitespace issues are handled by the count_*_space? methods) + when /%\*?(\d+)c/ + [ "(.{1,#{$1}})", :extract_plain ] + + # %% + when /%%/ + [ '(\s*%)', :nil_proc ] + + # literal characters + else + [ "(#{Regexp.escape(@spec_string)})", :nil_proc ] + end + + @re_string = '\A' + @re_string + end + + def to_re + Regexp.new(@re_string,Regexp::MULTILINE) + end + + def match(str) + @matched = false + s = str.dup + s.sub!(/\A\s+/,'') unless count_space? + res = to_re.match(s) + if res + @conversion = send(@handler, res[1]) + @matched_string = @conversion.to_s + @matched = true + end + res + end + + def letter + /%\*?\d*([a-z\[])/.match(@spec_string).to_a[1] + end + + def width + w = /%\*?(\d+)/.match(@spec_string).to_a[1] + w && w.to_i + end + + def mid_match? + return false unless @matched + cc_no_width = letter == '[' &&! width + c_or_cc_width = (letter == 'c' || letter == '[') && width + width_left = c_or_cc_width && (matched_string.size < width) + + return width_left || cc_no_width + end + + end + + class FormatString + + attr_reader :string_left, :last_spec_tried, + :last_match_tried, :matched_count, :space + + SPECIFIERS = 'diuXxofeEgsc' + REGEX = / + # possible space, followed by... + (?:\s* + # percent sign, followed by... + % + # another percent sign, or... + (?:%| + # optional assignment suppression flag + \*? + # optional maximum field width + \d* + # named character class, ... + (?:\[\[:\w+:\]\]| + # traditional character class, or... + \[[^\]]*\]| + # specifier letter. + [#{SPECIFIERS}])))| + # or miscellaneous characters + [^%\s]+/ix + + def initialize(str) + @specs = [] + @i = 1 + s = str.to_s + return unless /\S/.match(s) + @space = true if /\s\z/.match(s) + @specs.replace s.scan(REGEX).map {|spec| FormatSpecifier.new(spec) } + end + + def to_s + @specs.join('') + end + + def prune(n=matched_count) + n.times { @specs.shift } + end + + def spec_count + @specs.size + end + + def last_spec + @i == spec_count - 1 + end + + def match(str) + accum = [] + @string_left = str + @matched_count = 0 + + @specs.each_with_index do |spec,@i| + @last_spec_tried = spec + @last_match_tried = spec.match(@string_left) + break unless @last_match_tried + @matched_count += 1 + + accum << spec.conversion + + @string_left = @last_match_tried.post_match + break if @string_left.empty? + end + return accum.compact + end + end +end + +class IO + +# The trick here is doing a match where you grab one *line* +# of input at a time. The linebreak may or may not occur +# at the boundary where the string matches a format specifier. +# And if it does, some rule about whitespace may or may not +# be in effect... +# +# That's why this is much more elaborate than the string +# version. +# +# For each line: +# Match succeeds (non-emptily) +# and the last attempted spec/string sub-match succeeded: +# +# could the last spec keep matching? +# yes: save interim results and continue (next line) +# +# The last attempted spec/string did not match: +# +# are we on the next-to-last spec in the string? +# yes: +# is fmt_string.string_left all spaces? +# yes: does current spec care about input space? +# yes: fatal failure +# no: save interim results and continue +# no: continue [this state could be analyzed further] +# +# + + def scanf(str,&b) + return block_scanf(str,&b) if b + return [] unless str.size > 0 + + start_position = pos rescue 0 + matched_so_far = 0 + source_buffer = "" + result_buffer = [] + final_result = [] + + fstr = Scanf::FormatString.new(str) + + loop do + if eof || (tty? &&! fstr.match(source_buffer)) + final_result.concat(result_buffer) + break + end + + source_buffer << gets + + current_match = fstr.match(source_buffer) + + spec = fstr.last_spec_tried + + if spec.matched + if spec.mid_match? + result_buffer.replace(current_match) + next + end + + elsif (fstr.matched_count == fstr.spec_count - 1) + if /\A\s*\z/.match(fstr.string_left) + break if spec.count_space? + result_buffer.replace(current_match) + next + end + end + + final_result.concat(current_match) + + matched_so_far += source_buffer.size + source_buffer.replace(fstr.string_left) + matched_so_far -= source_buffer.size + break if fstr.last_spec + fstr.prune + end + seek(start_position + matched_so_far, IO::SEEK_SET) rescue Errno::ESPIPE + soak_up_spaces if fstr.last_spec && fstr.space + + return final_result + end + + private + + def soak_up_spaces + c = getc + ungetc(c) if c + until eof ||! c || /\S/.match(c.chr) + c = getc + end + ungetc(c) if (c && /\S/.match(c.chr)) + end + + def block_scanf(str) + final = [] +# Sub-ideal, since another FS gets created in scanf. +# But used here to determine the number of specifiers. + fstr = Scanf::FormatString.new(str) + last_spec = fstr.last_spec + begin + current = scanf(str) + break if current.empty? + final.push(yield(current)) + end until eof || fstr.last_spec_tried == last_spec + return final + end +end + +class String + + def scanf(fstr,&b) + if b + block_scanf(fstr,&b) + else + fs = + if fstr.is_a? Scanf::FormatString + fstr + else + Scanf::FormatString.new(fstr) + end + fs.match(self) + end + end + + def block_scanf(fstr,&b) + fs = Scanf::FormatString.new(fstr) + str = self.dup + final = [] + begin + current = str.scanf(fs) + final.push(yield(current)) unless current.empty? + str = fs.string_left + end until current.empty? || str.empty? + return final + end +end + +module Kernel + private + def scanf(fs,&b) + STDIN.scanf(fs,&b) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/set.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/set.rb new file mode 100644 index 00000000..ac8950ab --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/set.rb @@ -0,0 +1,1250 @@ +#!/usr/bin/env ruby +#-- +# set.rb - defines the Set class +#++ +# Copyright (c) 2002 Akinori MUSHA +# +# Documentation by Akinori MUSHA and Gavin Sinclair. +# +# All rights reserved. You can redistribute and/or modify it under the same +# terms as Ruby. +# +# $Id: set.rb 17648 2008-06-29 08:06:28Z shyouhei $ +# +# == Overview +# +# This library provides the Set class, which deals with a collection +# of unordered values with no duplicates. It is a hybrid of Array's +# intuitive inter-operation facilities and Hash's fast lookup. If you +# need to keep values ordered, use the SortedSet class. +# +# The method +to_set+ is added to Enumerable for convenience. +# +# See the Set class for an example of usage. + + +# +# Set implements a collection of unordered values with no duplicates. +# This is a hybrid of Array's intuitive inter-operation facilities and +# Hash's fast lookup. +# +# Several methods accept any Enumerable object (implementing +each+) +# for greater flexibility: new, replace, merge, subtract, |, &, -, ^. +# +# The equality of each couple of elements is determined according to +# Object#eql? and Object#hash, since Set uses Hash as storage. +# +# Finally, if you are using class Set, you can also use Enumerable#to_set +# for convenience. +# +# == Example +# +# require 'set' +# s1 = Set.new [1, 2] # -> # +# s2 = [1, 2].to_set # -> # +# s1 == s2 # -> true +# s1.add("foo") # -> # +# s1.merge([2, 6]) # -> # +# s1.subset? s2 # -> false +# s2.subset? s1 # -> true +# +class Set + include Enumerable + + # Creates a new set containing the given objects. + def self.[](*ary) + new(ary) + end + + # Creates a new set containing the elements of the given enumerable + # object. + # + # If a block is given, the elements of enum are preprocessed by the + # given block. + def initialize(enum = nil, &block) # :yields: o + @hash ||= Hash.new + + enum.nil? and return + + if block + enum.each { |o| add(block[o]) } + else + merge(enum) + end + end + + # Copy internal hash. + def initialize_copy(orig) + @hash = orig.instance_eval{@hash}.dup + end + + # Returns the number of elements. + def size + @hash.size + end + alias length size + + # Returns true if the set contains no elements. + def empty? + @hash.empty? + end + + # Removes all elements and returns self. + def clear + @hash.clear + self + end + + # Replaces the contents of the set with the contents of the given + # enumerable object and returns self. + def replace(enum) + if enum.class == self.class + @hash.replace(enum.instance_eval { @hash }) + else + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + clear + enum.each { |o| add(o) } + end + + self + end + + # Converts the set to an array. The order of elements is uncertain. + def to_a + @hash.keys + end + + def flatten_merge(set, seen = Set.new) + set.each { |e| + if e.is_a?(Set) + if seen.include?(e_id = e.object_id) + raise ArgumentError, "tried to flatten recursive Set" + end + + seen.add(e_id) + flatten_merge(e, seen) + seen.delete(e_id) + else + add(e) + end + } + + self + end + protected :flatten_merge + + # Returns a new set that is a copy of the set, flattening each + # containing set recursively. + def flatten + self.class.new.flatten_merge(self) + end + + # Equivalent to Set#flatten, but replaces the receiver with the + # result in place. Returns nil if no modifications were made. + def flatten! + if detect { |e| e.is_a?(Set) } + replace(flatten()) + else + nil + end + end + + # Returns true if the set contains the given object. + def include?(o) + @hash.include?(o) + end + alias member? include? + + # Returns true if the set is a superset of the given set. + def superset?(set) + set.is_a?(Set) or raise ArgumentError, "value must be a set" + return false if size < set.size + set.all? { |o| include?(o) } + end + + # Returns true if the set is a proper superset of the given set. + def proper_superset?(set) + set.is_a?(Set) or raise ArgumentError, "value must be a set" + return false if size <= set.size + set.all? { |o| include?(o) } + end + + # Returns true if the set is a subset of the given set. + def subset?(set) + set.is_a?(Set) or raise ArgumentError, "value must be a set" + return false if set.size < size + all? { |o| set.include?(o) } + end + + # Returns true if the set is a proper subset of the given set. + def proper_subset?(set) + set.is_a?(Set) or raise ArgumentError, "value must be a set" + return false if set.size <= size + all? { |o| set.include?(o) } + end + + # Calls the given block once for each element in the set, passing + # the element as parameter. + def each + @hash.each_key { |o| yield(o) } + self + end + + # Adds the given object to the set and returns self. Use +merge+ to + # add several elements at once. + def add(o) + @hash[o] = true + self + end + alias << add + + # Adds the given object to the set and returns self. If the + # object is already in the set, returns nil. + def add?(o) + if include?(o) + nil + else + add(o) + end + end + + # Deletes the given object from the set and returns self. Use +subtract+ to + # delete several items at once. + def delete(o) + @hash.delete(o) + self + end + + # Deletes the given object from the set and returns self. If the + # object is not in the set, returns nil. + def delete?(o) + if include?(o) + delete(o) + else + nil + end + end + + # Deletes every element of the set for which block evaluates to + # true, and returns self. + def delete_if + to_a.each { |o| @hash.delete(o) if yield(o) } + self + end + + # Do collect() destructively. + def collect! + set = self.class.new + each { |o| set << yield(o) } + replace(set) + end + alias map! collect! + + # Equivalent to Set#delete_if, but returns nil if no changes were + # made. + def reject! + n = size + delete_if { |o| yield(o) } + size == n ? nil : self + end + + # Merges the elements of the given enumerable object to the set and + # returns self. + def merge(enum) + if enum.is_a?(Set) + @hash.update(enum.instance_eval { @hash }) + else + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + enum.each { |o| add(o) } + end + + self + end + + # Deletes every element that appears in the given enumerable object + # and returns self. + def subtract(enum) + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + enum.each { |o| delete(o) } + self + end + + # Returns a new set built by merging the set and the elements of the + # given enumerable object. + def |(enum) + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + dup.merge(enum) + end + alias + | ## + alias union | ## + + # Returns a new set built by duplicating the set, removing every + # element that appears in the given enumerable object. + def -(enum) + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + dup.subtract(enum) + end + alias difference - ## + + # Returns a new set containing elements common to the set and the + # given enumerable object. + def &(enum) + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + n = self.class.new + enum.each { |o| n.add(o) if include?(o) } + n + end + alias intersection & ## + + # Returns a new set containing elements exclusive between the set + # and the given enumerable object. (set ^ enum) is equivalent to + # ((set | enum) - (set & enum)). + def ^(enum) + enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" + n = Set.new(enum) + each { |o| if n.include?(o) then n.delete(o) else n.add(o) end } + n + end + + # Returns true if two sets are equal. The equality of each couple + # of elements is defined according to Object#eql?. + def ==(set) + equal?(set) and return true + + set.is_a?(Set) && size == set.size or return false + + hash = @hash.dup + set.all? { |o| hash.include?(o) } + end + + def hash # :nodoc: + @hash.hash + end + + def eql?(o) # :nodoc: + return false unless o.is_a?(Set) + @hash.eql?(o.instance_eval{@hash}) + end + + # Classifies the set by the return value of the given block and + # returns a hash of {value => set of elements} pairs. The block is + # called once for each element of the set, passing the element as + # parameter. + # + # e.g.: + # + # require 'set' + # files = Set.new(Dir.glob("*.rb")) + # hash = files.classify { |f| File.mtime(f).year } + # p hash # => {2000=>#, + # # 2001=>#, + # # 2002=>#} + def classify # :yields: o + h = {} + + each { |i| + x = yield(i) + (h[x] ||= self.class.new).add(i) + } + + h + end + + # Divides the set into a set of subsets according to the commonality + # defined by the given block. + # + # If the arity of the block is 2, elements o1 and o2 are in common + # if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are + # in common if block.call(o1) == block.call(o2). + # + # e.g.: + # + # require 'set' + # numbers = Set[1, 3, 4, 6, 9, 10, 11] + # set = numbers.divide { |i,j| (i - j).abs == 1 } + # p set # => #, + # # #, + # # #, + # # #}> + def divide(&func) + if func.arity == 2 + require 'tsort' + + class << dig = {} # :nodoc: + include TSort + + alias tsort_each_node each_key + def tsort_each_child(node, &block) + fetch(node).each(&block) + end + end + + each { |u| + dig[u] = a = [] + each{ |v| func.call(u, v) and a << v } + } + + set = Set.new() + dig.each_strongly_connected_component { |css| + set.add(self.class.new(css)) + } + set + else + Set.new(classify(&func).values) + end + end + + InspectKey = :__inspect_key__ # :nodoc: + + # Returns a string containing a human-readable representation of the + # set. ("#") + def inspect + ids = (Thread.current[InspectKey] ||= []) + + if ids.include?(object_id) + return sprintf('#<%s: {...}>', self.class.name) + end + + begin + ids << object_id + return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2]) + ensure + ids.pop + end + end + + def pretty_print(pp) # :nodoc: + pp.text sprintf('#<%s: {', self.class.name) + pp.nest(1) { + pp.seplist(self) { |o| + pp.pp o + } + } + pp.text "}>" + end + + def pretty_print_cycle(pp) # :nodoc: + pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...') + end +end + +# SortedSet implements a set which elements are sorted in order. See Set. +class SortedSet < Set + @@setup = false + + class << self + def [](*ary) # :nodoc: + new(ary) + end + + def setup # :nodoc: + @@setup and return + + module_eval { + # a hack to shut up warning + alias old_init initialize + remove_method :old_init + } + begin + require 'rbtree' + + module_eval %{ + def initialize(*args, &block) + @hash = RBTree.new + super + end + } + rescue LoadError + module_eval %{ + def initialize(*args, &block) + @keys = nil + super + end + + def clear + @keys = nil + super + end + + def replace(enum) + @keys = nil + super + end + + def add(o) + @keys = nil + @hash[o] = true + self + end + alias << add + + def delete(o) + @keys = nil + @hash.delete(o) + self + end + + def delete_if + n = @hash.size + super + @keys = nil if @hash.size != n + self + end + + def merge(enum) + @keys = nil + super + end + + def each + to_a.each { |o| yield(o) } + self + end + + def to_a + (@keys = @hash.keys).sort! unless @keys + @keys + end + } + end + + @@setup = true + end + end + + def initialize(*args, &block) # :nodoc: + SortedSet.setup + initialize(*args, &block) + end +end + +module Enumerable + # Makes a set from the enumerable object with given arguments. + # Needs to +require "set"+ to use this method. + def to_set(klass = Set, *args, &block) + klass.new(self, *args, &block) + end +end + +# =begin +# == RestricedSet class +# RestricedSet implements a set with restrictions defined by a given +# block. +# +# === Super class +# Set +# +# === Class Methods +# --- RestricedSet::new(enum = nil) { |o| ... } +# --- RestricedSet::new(enum = nil) { |rset, o| ... } +# Creates a new restricted set containing the elements of the given +# enumerable object. Restrictions are defined by the given block. +# +# If the block's arity is 2, it is called with the RestrictedSet +# itself and an object to see if the object is allowed to be put in +# the set. +# +# Otherwise, the block is called with an object to see if the object +# is allowed to be put in the set. +# +# === Instance Methods +# --- restriction_proc +# Returns the restriction procedure of the set. +# +# =end +# +# class RestricedSet < Set +# def initialize(*args, &block) +# @proc = block or raise ArgumentError, "missing a block" +# +# if @proc.arity == 2 +# instance_eval %{ +# def add(o) +# @hash[o] = true if @proc.call(self, o) +# self +# end +# alias << add +# +# def add?(o) +# if include?(o) || !@proc.call(self, o) +# nil +# else +# @hash[o] = true +# self +# end +# end +# +# def replace(enum) +# enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" +# clear +# enum.each { |o| add(o) } +# +# self +# end +# +# def merge(enum) +# enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" +# enum.each { |o| add(o) } +# +# self +# end +# } +# else +# instance_eval %{ +# def add(o) +# if @proc.call(o) +# @hash[o] = true +# end +# self +# end +# alias << add +# +# def add?(o) +# if include?(o) || !@proc.call(o) +# nil +# else +# @hash[o] = true +# self +# end +# end +# } +# end +# +# super(*args) +# end +# +# def restriction_proc +# @proc +# end +# end + +if $0 == __FILE__ + eval DATA.read, nil, $0, __LINE__+4 +end + +__END__ + +require 'test/unit' + +class TC_Set < Test::Unit::TestCase + def test_aref + assert_nothing_raised { + Set[] + Set[nil] + Set[1,2,3] + } + + assert_equal(0, Set[].size) + assert_equal(1, Set[nil].size) + assert_equal(1, Set[[]].size) + assert_equal(1, Set[[nil]].size) + + set = Set[2,4,6,4] + assert_equal(Set.new([2,4,6]), set) + end + + def test_s_new + assert_nothing_raised { + Set.new() + Set.new(nil) + Set.new([]) + Set.new([1,2]) + Set.new('a'..'c') + Set.new('XYZ') + } + assert_raises(ArgumentError) { + Set.new(false) + } + assert_raises(ArgumentError) { + Set.new(1) + } + assert_raises(ArgumentError) { + Set.new(1,2) + } + + assert_equal(0, Set.new().size) + assert_equal(0, Set.new(nil).size) + assert_equal(0, Set.new([]).size) + assert_equal(1, Set.new([nil]).size) + + ary = [2,4,6,4] + set = Set.new(ary) + ary.clear + assert_equal(false, set.empty?) + assert_equal(3, set.size) + + ary = [1,2,3] + + s = Set.new(ary) { |o| o * 2 } + assert_equal([2,4,6], s.sort) + end + + def test_clone + set1 = Set.new + set2 = set1.clone + set1 << 'abc' + assert_equal(Set.new, set2) + end + + def test_dup + set1 = Set[1,2] + set2 = set1.dup + + assert_not_same(set1, set2) + + assert_equal(set1, set2) + + set1.add(3) + + assert_not_equal(set1, set2) + end + + def test_size + assert_equal(0, Set[].size) + assert_equal(2, Set[1,2].size) + assert_equal(2, Set[1,2,1].size) + end + + def test_empty? + assert_equal(true, Set[].empty?) + assert_equal(false, Set[1, 2].empty?) + end + + def test_clear + set = Set[1,2] + ret = set.clear + + assert_same(set, ret) + assert_equal(true, set.empty?) + end + + def test_replace + set = Set[1,2] + ret = set.replace('a'..'c') + + assert_same(set, ret) + assert_equal(Set['a','b','c'], set) + end + + def test_to_a + set = Set[1,2,3,2] + ary = set.to_a + + assert_equal([1,2,3], ary.sort) + end + + def test_flatten + # test1 + set1 = Set[ + 1, + Set[ + 5, + Set[7, + Set[0] + ], + Set[6,2], + 1 + ], + 3, + Set[3,4] + ] + + set2 = set1.flatten + set3 = Set.new(0..7) + + assert_not_same(set2, set1) + assert_equal(set3, set2) + + # test2; destructive + orig_set1 = set1 + set1.flatten! + + assert_same(orig_set1, set1) + assert_equal(set3, set1) + + # test3; multiple occurrences of a set in an set + set1 = Set[1, 2] + set2 = Set[set1, Set[set1, 4], 3] + + assert_nothing_raised { + set2.flatten! + } + + assert_equal(Set.new(1..4), set2) + + # test4; recursion + set2 = Set[] + set1 = Set[1, set2] + set2.add(set1) + + assert_raises(ArgumentError) { + set1.flatten! + } + + # test5; miscellaneous + empty = Set[] + set = Set[Set[empty, "a"],Set[empty, "b"]] + + assert_nothing_raised { + set.flatten + } + + set1 = empty.merge(Set["no_more", set]) + + assert_nil(Set.new(0..31).flatten!) + + x = Set[Set[],Set[1,2]].flatten! + y = Set[1,2] + + assert_equal(x, y) + end + + def test_include? + set = Set[1,2,3] + + assert_equal(true, set.include?(1)) + assert_equal(true, set.include?(2)) + assert_equal(true, set.include?(3)) + assert_equal(false, set.include?(0)) + assert_equal(false, set.include?(nil)) + + set = Set["1",nil,"2",nil,"0","1",false] + assert_equal(true, set.include?(nil)) + assert_equal(true, set.include?(false)) + assert_equal(true, set.include?("1")) + assert_equal(false, set.include?(0)) + assert_equal(false, set.include?(true)) + end + + def test_superset? + set = Set[1,2,3] + + assert_raises(ArgumentError) { + set.superset?() + } + + assert_raises(ArgumentError) { + set.superset?(2) + } + + assert_raises(ArgumentError) { + set.superset?([2]) + } + + assert_equal(true, set.superset?(Set[])) + assert_equal(true, set.superset?(Set[1,2])) + assert_equal(true, set.superset?(Set[1,2,3])) + assert_equal(false, set.superset?(Set[1,2,3,4])) + assert_equal(false, set.superset?(Set[1,4])) + + assert_equal(true, Set[].superset?(Set[])) + end + + def test_proper_superset? + set = Set[1,2,3] + + assert_raises(ArgumentError) { + set.proper_superset?() + } + + assert_raises(ArgumentError) { + set.proper_superset?(2) + } + + assert_raises(ArgumentError) { + set.proper_superset?([2]) + } + + assert_equal(true, set.proper_superset?(Set[])) + assert_equal(true, set.proper_superset?(Set[1,2])) + assert_equal(false, set.proper_superset?(Set[1,2,3])) + assert_equal(false, set.proper_superset?(Set[1,2,3,4])) + assert_equal(false, set.proper_superset?(Set[1,4])) + + assert_equal(false, Set[].proper_superset?(Set[])) + end + + def test_subset? + set = Set[1,2,3] + + assert_raises(ArgumentError) { + set.subset?() + } + + assert_raises(ArgumentError) { + set.subset?(2) + } + + assert_raises(ArgumentError) { + set.subset?([2]) + } + + assert_equal(true, set.subset?(Set[1,2,3,4])) + assert_equal(true, set.subset?(Set[1,2,3])) + assert_equal(false, set.subset?(Set[1,2])) + assert_equal(false, set.subset?(Set[])) + + assert_equal(true, Set[].subset?(Set[1])) + assert_equal(true, Set[].subset?(Set[])) + end + + def test_proper_subset? + set = Set[1,2,3] + + assert_raises(ArgumentError) { + set.proper_subset?() + } + + assert_raises(ArgumentError) { + set.proper_subset?(2) + } + + assert_raises(ArgumentError) { + set.proper_subset?([2]) + } + + assert_equal(true, set.proper_subset?(Set[1,2,3,4])) + assert_equal(false, set.proper_subset?(Set[1,2,3])) + assert_equal(false, set.proper_subset?(Set[1,2])) + assert_equal(false, set.proper_subset?(Set[])) + + assert_equal(false, Set[].proper_subset?(Set[])) + end + + def test_each + ary = [1,3,5,7,10,20] + set = Set.new(ary) + + assert_raises(LocalJumpError) { + set.each + } + + assert_nothing_raised { + set.each { |o| + ary.delete(o) or raise "unexpected element: #{o}" + } + + ary.empty? or raise "forgotten elements: #{ary.join(', ')}" + } + end + + def test_add + set = Set[1,2,3] + + ret = set.add(2) + assert_same(set, ret) + assert_equal(Set[1,2,3], set) + + ret = set.add?(2) + assert_nil(ret) + assert_equal(Set[1,2,3], set) + + ret = set.add(4) + assert_same(set, ret) + assert_equal(Set[1,2,3,4], set) + + ret = set.add?(5) + assert_same(set, ret) + assert_equal(Set[1,2,3,4,5], set) + end + + def test_delete + set = Set[1,2,3] + + ret = set.delete(4) + assert_same(set, ret) + assert_equal(Set[1,2,3], set) + + ret = set.delete?(4) + assert_nil(ret) + assert_equal(Set[1,2,3], set) + + ret = set.delete(2) + assert_equal(set, ret) + assert_equal(Set[1,3], set) + + ret = set.delete?(1) + assert_equal(set, ret) + assert_equal(Set[3], set) + end + + def test_delete_if + set = Set.new(1..10) + ret = set.delete_if { |i| i > 10 } + assert_same(set, ret) + assert_equal(Set.new(1..10), set) + + set = Set.new(1..10) + ret = set.delete_if { |i| i % 3 == 0 } + assert_same(set, ret) + assert_equal(Set[1,2,4,5,7,8,10], set) + end + + def test_collect! + set = Set[1,2,3,'a','b','c',-1..1,2..4] + + ret = set.collect! { |i| + case i + when Numeric + i * 2 + when String + i.upcase + else + nil + end + } + + assert_same(set, ret) + assert_equal(Set[2,4,6,'A','B','C',nil], set) + end + + def test_reject! + set = Set.new(1..10) + + ret = set.reject! { |i| i > 10 } + assert_nil(ret) + assert_equal(Set.new(1..10), set) + + ret = set.reject! { |i| i % 3 == 0 } + assert_same(set, ret) + assert_equal(Set[1,2,4,5,7,8,10], set) + end + + def test_merge + set = Set[1,2,3] + + ret = set.merge([2,4,6]) + assert_same(set, ret) + assert_equal(Set[1,2,3,4,6], set) + end + + def test_subtract + set = Set[1,2,3] + + ret = set.subtract([2,4,6]) + assert_same(set, ret) + assert_equal(Set[1,3], set) + end + + def test_plus + set = Set[1,2,3] + + ret = set + [2,4,6] + assert_not_same(set, ret) + assert_equal(Set[1,2,3,4,6], ret) + end + + def test_minus + set = Set[1,2,3] + + ret = set - [2,4,6] + assert_not_same(set, ret) + assert_equal(Set[1,3], ret) + end + + def test_and + set = Set[1,2,3,4] + + ret = set & [2,4,6] + assert_not_same(set, ret) + assert_equal(Set[2,4], ret) + end + + def test_xor + set = Set[1,2,3,4] + ret = set ^ [2,4,5,5] + assert_not_same(set, ret) + assert_equal(Set[1,3,5], ret) + end + + def test_eq + set1 = Set[2,3,1] + set2 = Set[1,2,3] + + assert_equal(set1, set1) + assert_equal(set1, set2) + assert_not_equal(Set[1], [1]) + + set1 = Class.new(Set)["a", "b"] + set2 = Set["a", "b", set1] + set1 = set1.add(set1.clone) + +# assert_equal(set1, set2) +# assert_equal(set2, set1) + assert_equal(set2, set2.clone) + assert_equal(set1.clone, set1) + + assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]") + end + + # def test_hash + # end + + # def test_eql? + # end + + def test_classify + set = Set.new(1..10) + ret = set.classify { |i| i % 3 } + + assert_equal(3, ret.size) + assert_instance_of(Hash, ret) + ret.each_value { |value| assert_instance_of(Set, value) } + assert_equal(Set[3,6,9], ret[0]) + assert_equal(Set[1,4,7,10], ret[1]) + assert_equal(Set[2,5,8], ret[2]) + end + + def test_divide + set = Set.new(1..10) + ret = set.divide { |i| i % 3 } + + assert_equal(3, ret.size) + n = 0 + ret.each { |s| n += s.size } + assert_equal(set.size, n) + assert_equal(set, ret.flatten) + + set = Set[7,10,5,11,1,3,4,9,0] + ret = set.divide { |a,b| (a - b).abs == 1 } + + assert_equal(4, ret.size) + n = 0 + ret.each { |s| n += s.size } + assert_equal(set.size, n) + assert_equal(set, ret.flatten) + ret.each { |s| + if s.include?(0) + assert_equal(Set[0,1], s) + elsif s.include?(3) + assert_equal(Set[3,4,5], s) + elsif s.include?(7) + assert_equal(Set[7], s) + elsif s.include?(9) + assert_equal(Set[9,10,11], s) + else + raise "unexpected group: #{s.inspect}" + end + } + end + + def test_inspect + set1 = Set[1] + + assert_equal('#', set1.inspect) + + set2 = Set[Set[0], 1, 2, set1] + assert_equal(false, set2.inspect.include?('#')) + + set1.add(set2) + assert_equal(true, set1.inspect.include?('#')) + end + + # def test_pretty_print + # end + + # def test_pretty_print_cycle + # end +end + +class TC_SortedSet < Test::Unit::TestCase + def test_sortedset + s = SortedSet[4,5,3,1,2] + + assert_equal([1,2,3,4,5], s.to_a) + + prev = nil + s.each { |o| assert(prev < o) if prev; prev = o } + assert_not_nil(prev) + + s.map! { |o| -2 * o } + + assert_equal([-10,-8,-6,-4,-2], s.to_a) + + prev = nil + ret = s.each { |o| assert(prev < o) if prev; prev = o } + assert_not_nil(prev) + assert_same(s, ret) + + s = SortedSet.new([2,1,3]) { |o| o * -2 } + assert_equal([-6,-4,-2], s.to_a) + + s = SortedSet.new(['one', 'two', 'three', 'four']) + a = [] + ret = s.delete_if { |o| a << o; o[0] == ?t } + assert_same(s, ret) + assert_equal(['four', 'one'], s.to_a) + assert_equal(['four', 'one', 'three', 'two'], a) + + s = SortedSet.new(['one', 'two', 'three', 'four']) + a = [] + ret = s.reject! { |o| a << o; o[0] == ?t } + assert_same(s, ret) + assert_equal(['four', 'one'], s.to_a) + assert_equal(['four', 'one', 'three', 'two'], a) + + s = SortedSet.new(['one', 'two', 'three', 'four']) + a = [] + ret = s.reject! { |o| a << o; false } + assert_same(nil, ret) + assert_equal(['four', 'one', 'three', 'two'], s.to_a) + assert_equal(['four', 'one', 'three', 'two'], a) + end +end + +class TC_Enumerable < Test::Unit::TestCase + def test_to_set + ary = [2,5,4,3,2,1,3] + + set = ary.to_set + assert_instance_of(Set, set) + assert_equal([1,2,3,4,5], set.sort) + + set = ary.to_set { |o| o * -2 } + assert_instance_of(Set, set) + assert_equal([-10,-8,-6,-4,-2], set.sort) + + set = ary.to_set(SortedSet) + assert_instance_of(SortedSet, set) + assert_equal([1,2,3,4,5], set.to_a) + + set = ary.to_set(SortedSet) { |o| o * -2 } + assert_instance_of(SortedSet, set) + assert_equal([-10,-8,-6,-4,-2], set.sort) + end +end + +# class TC_RestricedSet < Test::Unit::TestCase +# def test_s_new +# assert_raises(ArgumentError) { RestricedSet.new } +# +# s = RestricedSet.new([-1,2,3]) { |o| o > 0 } +# assert_equal([2,3], s.sort) +# end +# +# def test_restriction_proc +# s = RestricedSet.new([-1,2,3]) { |o| o > 0 } +# +# f = s.restriction_proc +# assert_instance_of(Proc, f) +# assert(f[1]) +# assert(!f[0]) +# end +# +# def test_replace +# s = RestricedSet.new(-3..3) { |o| o > 0 } +# assert_equal([1,2,3], s.sort) +# +# s.replace([-2,0,3,4,5]) +# assert_equal([3,4,5], s.sort) +# end +# +# def test_merge +# s = RestricedSet.new { |o| o > 0 } +# s.merge(-5..5) +# assert_equal([1,2,3,4,5], s.sort) +# +# s.merge([10,-10,-8,8]) +# assert_equal([1,2,3,4,5,8,10], s.sort) +# end +# end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/sha1.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/sha1.rb new file mode 100644 index 00000000..af04158a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/sha1.rb @@ -0,0 +1,23 @@ +# just for compatibility; requiring "sha1" is obsoleted +# +# $RoughId: sha1.rb,v 1.4 2001/07/13 15:38:27 knu Exp $ +# $Id: sha1.rb 12008 2007-03-06 10:12:12Z knu $ + +require 'digest/sha1' + +class SHA1 < Digest::SHA1 + class << self + alias orig_new new + def new(str = nil) + if str + orig_new.update(str) + else + orig_new + end + end + + def sha1(*args) + new(*args) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell.rb new file mode 100644 index 00000000..039f849e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell.rb @@ -0,0 +1,269 @@ +# +# shell.rb - +# $Release Version: 0.6.0 $ +# $Revision: 1.8 $ +# $Date: 2001/03/19 09:01:11 $ +# by Keiju ISHITSUKA(Nippon Rational Inc.) +# +# -- +# +# +# + +require "e2mmap" +require "thread" + +require "shell/error" +require "shell/command-processor" +require "shell/process-controller" + +class Shell + @RCS_ID='-$Id: shell.rb,v 1.8 2001/03/19 09:01:11 keiju Exp keiju $-' + + include Error + extend Exception2MessageMapper + +# @cascade = true + # debug: true -> normal debug + # debug: 1 -> eval definition debug + # debug: 2 -> detail inspect debug + @debug = false + @verbose = true + + class << Shell + attr :cascade, true + attr :debug, true + attr :verbose, true + +# alias cascade? cascade + alias debug? debug + alias verbose? verbose + @verbose = true + + def debug=(val) + @debug = val + @verbose = val if val + end + + def cd(path) + sh = new + sh.cd path + sh + end + + def default_system_path + if @default_system_path + @default_system_path + else + ENV["PATH"].split(":") + end + end + + def default_system_path=(path) + @default_system_path = path + end + + def default_record_separator + if @default_record_separator + @default_record_separator + else + $/ + end + end + + def default_record_separator=(rs) + @default_record_separator = rs + end + end + + def initialize + @cwd = Dir.pwd + @dir_stack = [] + @umask = nil + + @system_path = Shell.default_system_path + @record_separator = Shell.default_record_separator + + @command_processor = CommandProcessor.new(self) + @process_controller = ProcessController.new(self) + + @verbose = Shell.verbose + @debug = Shell.debug + end + + attr_reader :system_path + + def system_path=(path) + @system_path = path + rehash + end + + attr :umask, true + attr :record_separator, true + + attr :verbose, true + attr :debug, true + + def debug=(val) + @debug = val + @verbose = val if val + end + + alias verbose? verbose + alias debug? debug + + attr_reader :command_processor + attr_reader :process_controller + + def expand_path(path) + File.expand_path(path, @cwd) + end + + # Most Shell commands are defined via CommandProcessor + + # + # Dir related methods + # + # Shell#cwd/dir/getwd/pwd + # Shell#chdir/cd + # Shell#pushdir/pushd + # Shell#popdir/popd + # Shell#mkdir + # Shell#rmdir + + attr :cwd + alias dir cwd + alias getwd cwd + alias pwd cwd + + attr :dir_stack + alias dirs dir_stack + + # If called as iterator, it restores the current directory when the + # block ends. + def chdir(path = nil) + if iterator? + cwd_old = @cwd + begin + chdir(path) + yield + ensure + chdir(cwd_old) + end + else + path = "~" unless path + @cwd = expand_path(path) + notify "current dir: #{@cwd}" + rehash + self + end + end + alias cd chdir + + def pushdir(path = nil) + if iterator? + pushdir(path) + begin + yield + ensure + popdir + end + elsif path + @dir_stack.push @cwd + chdir path + notify "dir stack: [#{@dir_stack.join ', '}]" + self + else + if pop = @dir_stack.pop + @dir_stack.push @cwd + chdir pop + notify "dir stack: [#{@dir_stack.join ', '}]" + self + else + Shell.Fail DirStackEmpty + end + end + end + alias pushd pushdir + + def popdir + if pop = @dir_stack.pop + chdir pop + notify "dir stack: [#{@dir_stack.join ', '}]" + self + else + Shell.Fail DirStackEmpty + end + end + alias popd popdir + + + # + # process management + # + def jobs + @process_controller.jobs + end + + def kill(sig, command) + @process_controller.kill_job(sig, command) + end + + # + # command definitions + # + def Shell.def_system_command(command, path = command) + CommandProcessor.def_system_command(command, path) + end + + def Shell.undef_system_command(command) + CommandProcessor.undef_system_command(command) + end + + def Shell.alias_command(ali, command, *opts, &block) + CommandProcessor.alias_command(ali, command, *opts, &block) + end + + def Shell.unalias_command(ali) + CommandProcessor.unalias_command(ali) + end + + def Shell.install_system_commands(pre = "sys_") + CommandProcessor.install_system_commands(pre) + end + + # + def inspect + if debug.kind_of?(Integer) && debug > 2 + super + else + to_s + end + end + + def self.notify(*opts, &block) + Thread.exclusive do + if opts[-1].kind_of?(String) + yorn = verbose? + else + yorn = opts.pop + end + return unless yorn + + _head = true + print opts.collect{|mes| + mes = mes.dup + yield mes if iterator? + if _head + _head = false + "shell: " + mes + else + " " + mes + end + }.join("\n")+"\n" + end + end + + CommandProcessor.initialize + CommandProcessor.run_config +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/builtin-command.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/builtin-command.rb new file mode 100644 index 00000000..2e1b361c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/builtin-command.rb @@ -0,0 +1,154 @@ +# +# shell/builtin-command.rb - +# $Release Version: 0.6.0 $ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) +# +# -- +# +# +# + +require "shell/filter" + +class Shell + class BuiltInCommand + # + def expand_path(path) + @shell.expand_path(path) + end + + # + # File related commands + # Shell#foreach + # Shell#open + # Shell#unlink + # Shell#test + # + # - + # + # CommandProcessor#foreach(path, rs) + # path: String + # rs: String - record separator + # iterator + # Same as: + # File#foreach (when path is file) + # Dir#foreach (when path is directory) + # path is relative to pwd + # + def foreach(path = nil, *rs) + path = "." unless path + path = expand_path(path) + + if File.directory?(path) + Dir.foreach(path){|fn| yield fn} + else + IO.foreach(path, *rs){|l| yield l} + end + end + + # + # CommandProcessor#open(path, mode) + # path: String + # mode: String + # return: File or Dir + # Same as: + # File#open (when path is file) + # Dir#open (when path is directory) + # mode has an effect only when path is a file + # + def open(path, mode) + path = expand_path(path) + if File.directory?(path) + Dir.open(path) + else + effect_umask do + File.open(path, mode) + end + end + end + # public :open + + # + # CommandProcessor#unlink(path) + # same as: + # Dir#unlink (when path is directory) + # File#unlink (when path is file) + # + def unlink(path) + path = expand_path(path) + if File.directory?(path) + Dir.unlink(path) + else + IO.unlink(path) + end + end + + # + # CommandProcessor#test(command, file1, file2) + # CommandProcessor#[command, file1, file2] + # command: char or String or Symbol + # file1: String + # file2: String(optional) + # return: Boolean + # same as: + # test() (when command is char or length 1 string or symbol) + # FileTest.command (others) + # example: + # sh[?e, "foo"] + # sh[:e, "foo"] + # sh["e", "foo"] + # sh[:exists?, "foo"] + # sh["exists?", "foo"] + # + def test(command, file1, file2=nil) + file1 = expand_path(file1) + file2 = expand_path(file2) if file2 + command = command.id2name if command.kind_of?(Symbol) + + case command + when Integer + top_level_test(command, file1, file2) + when String + if command.size == 1 + if file2 + top_level_test(command, file1, file2) + else + top_level_test(command, file1) + end + else + if file2 + FileTest.send(command, file1, file2) + else + FileTest.send(command, file1) + end + end + end + end + alias [] test + + # + # Dir related methods + # + # Shell#mkdir + # Shell#rmdir + # + #-- + # + # CommandProcessor#mkdir(*path) + # path: String + # same as Dir.mkdir() + # + def mkdir(*path) + for dir in path + Dir.mkdir(expand_path(dir)) + end + end + + # + # CommandProcessor#rmdir(*path) + # path: String + # same as Dir.rmdir() + # + def rmdir(*path) + for dir in path + Dir.rmdir(expand_path(dir)) + end + end + + # + # CommandProcessor#system(command, *opts) + # command: String + # opts: String + # return: SystemCommand + # Same as system() function + # example: + # print sh.system("ls", "-l") + # sh.system("ls", "-l") | sh.head > STDOUT + # + def system(command, *opts) + if opts.empty? + if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/ + return SystemCommand.new(@shell, find_system_command("sh"), "-c", command) + else + command, *opts = command.split(/\s+/) + end + end + SystemCommand.new(@shell, find_system_command(command), *opts) + end + + # + # ProcessCommand#rehash + # clear command hash table. + # + def rehash + @system_commands = {} + end + + # + # ProcessCommand#transact + # + def check_point + @shell.process_controller.wait_all_jobs_execution + end + alias finish_all_jobs check_point + + def transact(&block) + begin + @shell.instance_eval(&block) + ensure + check_point + end + end + + # + # internal commands + # + def out(dev = STDOUT, &block) + dev.print transact(&block) + end + + def echo(*strings) + Echo.new(@shell, *strings) + end + + def cat(*filenames) + Cat.new(@shell, *filenames) + end + + # def sort(*filenames) + # Sort.new(self, *filenames) + # end + + def glob(pattern) + Glob.new(@shell, pattern) + end + + def append(to, filter) + case to + when String + AppendFile.new(@shell, to, filter) + when IO + AppendIO.new(@shell, to, filter) + else + Shell.Fail Error::CantApplyMethod, "append", to.class + end + end + + def tee(file) + Tee.new(@shell, file) + end + + def concat(*jobs) + Concat.new(@shell, *jobs) + end + + # %pwd, %cwd -> @pwd + def notify(*opts, &block) + Thread.exclusive do + Shell.notify(*opts) {|mes| + yield mes if iterator? + + mes.gsub!("%pwd", "#{@cwd}") + mes.gsub!("%cwd", "#{@cwd}") + } + end + end + + # + # private functions + # + def effect_umask + if @shell.umask + Thread.critical = true + save = File.umask + begin + yield + ensure + File.umask save + Thread.critical = false + end + else + yield + end + end + private :effect_umask + + def find_system_command(command) + return command if /^\// =~ command + case path = @system_commands[command] + when String + if exists?(path) + return path + else + Shell.Fail Error::CommandNotFound, command + end + when false + Shell.Fail Error::CommandNotFound, command + end + + for p in @shell.system_path + path = join(p, command) + if FileTest.exists?(path) + @system_commands[command] = path + return path + end + end + @system_commands[command] = false + Shell.Fail Error::CommandNotFound, command + end + + # + # CommandProcessor.def_system_command(command, path) + # command: String + # path: String + # define 'command()' method as method. + # + def self.def_system_command(command, path = command) + begin + eval((d = %Q[def #{command}(*opts) + SystemCommand.new(@shell, '#{path}', *opts) + end]), nil, __FILE__, __LINE__ - 1) + rescue SyntaxError + Shell.notify "warn: Can't define #{command} path: #{path}." + end + Shell.notify "Define #{command} path: #{path}.", Shell.debug? + Shell.notify("Definition of #{command}: ", d, + Shell.debug.kind_of?(Integer) && Shell.debug > 1) + end + + def self.undef_system_command(command) + command = command.id2name if command.kind_of?(Symbol) + remove_method(command) + Shell.module_eval{remove_method(command)} + Filter.module_eval{remove_method(command)} + self + end + + # define command alias + # ex) + # def_alias_command("ls_c", "ls", "-C", "-F") + # def_alias_command("ls_c", "ls"){|*opts| ["-C", "-F", *opts]} + # + @alias_map = {} + def self.alias_map + @alias_map + end + def self.alias_command(ali, command, *opts, &block) + ali = ali.id2name if ali.kind_of?(Symbol) + command = command.id2name if command.kind_of?(Symbol) + begin + if iterator? + @alias_map[ali.intern] = proc + + eval((d = %Q[def #{ali}(*opts) + @shell.__send__(:#{command}, + *(CommandProcessor.alias_map[:#{ali}].call *opts)) + end]), nil, __FILE__, __LINE__ - 1) + + else + args = opts.collect{|opt| '"' + opt + '"'}.join(",") + eval((d = %Q[def #{ali}(*opts) + @shell.__send__(:#{command}, #{args}, *opts) + end]), nil, __FILE__, __LINE__ - 1) + end + rescue SyntaxError + Shell.notify "warn: Can't alias #{ali} command: #{command}." + Shell.notify("Definition of #{ali}: ", d) + raise + end + Shell.notify "Define #{ali} command: #{command}.", Shell.debug? + Shell.notify("Definition of #{ali}: ", d, + Shell.debug.kind_of?(Integer) && Shell.debug > 1) + self + end + + def self.unalias_command(ali) + ali = ali.id2name if ali.kind_of?(Symbol) + @alias_map.delete ali.intern + undef_system_command(ali) + end + + # + # CommandProcessor.def_builtin_commands(delegation_class, command_specs) + # delegation_class: Class or Module + # command_specs: [[command_name, [argument,...]],...] + # command_name: String + # arguments: String + # FILENAME?? -> expand_path(filename??) + # *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ") + # define command_name(argument,...) as + # delegation_class.command_name(argument,...) + # + def self.def_builtin_commands(delegation_class, command_specs) + for meth, args in command_specs + arg_str = args.collect{|arg| arg.downcase}.join(", ") + call_arg_str = args.collect{ + |arg| + case arg + when /^(FILENAME.*)$/ + format("expand_path(%s)", $1.downcase) + when /^(\*FILENAME.*)$/ + # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ") + $1.downcase + '.collect{|fn| expand_path(fn)}' + else + arg + end + }.join(", ") + d = %Q[def #{meth}(#{arg_str}) + #{delegation_class}.#{meth}(#{call_arg_str}) + end] + Shell.notify "Define #{meth}(#{arg_str})", Shell.debug? + Shell.notify("Definition of #{meth}: ", d, + Shell.debug.kind_of?(Integer) && Shell.debug > 1) + eval d + end + end + + # + # CommandProcessor.install_system_commands(pre) + # pre: String - command name prefix + # defines every command which belongs in default_system_path via + # CommandProcessor.command(). It doesn't define already defined + # methods twice. By default, "pre_" is prefixes to each method + # name. Characters that may not be used in a method name are + # all converted to '_'. Definition errors are just ignored. + # + def self.install_system_commands(pre = "sys_") + defined_meth = {} + for m in Shell.methods + defined_meth[m] = true + end + sh = Shell.new + for path in Shell.default_system_path + next unless sh.directory? path + sh.cd path + sh.foreach do + |cn| + if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn) + command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1') + begin + def_system_command(command, sh.expand_path(cn)) + rescue + Shell.notify "warn: Can't define #{command} path: #{cn}" + end + defined_meth[command] = command + end + end + end + end + + #---------------------------------------------------------------------- + # + # class initializing methods - + # + #---------------------------------------------------------------------- + def self.add_delegate_command_to_shell(id) + id = id.intern if id.kind_of?(String) + name = id.id2name + if Shell.method_defined?(id) + Shell.notify "warn: override definnition of Shell##{name}." + Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n" + Shell.module_eval "alias #{name}_org #{name}" + end + Shell.notify "method added: Shell##{name}.", Shell.debug? + Shell.module_eval(%Q[def #{name}(*args, &block) + begin + @command_processor.__send__(:#{name}, *args, &block) + rescue Exception + $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` + $@.delete_if{|s| /^\\(eval\\):/ =~ s} + raise + end + end], __FILE__, __LINE__) + + if Shell::Filter.method_defined?(id) + Shell.notify "warn: override definnition of Shell::Filter##{name}." + Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org." + Filter.module_eval "alias #{name}_org #{name}" + end + Shell.notify "method added: Shell::Filter##{name}.", Shell.debug? + Filter.module_eval(%Q[def #{name}(*args, &block) + begin + self | @shell.__send__(:#{name}, *args, &block) + rescue Exception + $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` + $@.delete_if{|s| /^\\(eval\\):/ =~ s} + raise + end + end], __FILE__, __LINE__) + end + + # + # define default builtin commands + # + def self.install_builtin_commands + # method related File. + # (exclude open/foreach/unlink) + normal_delegation_file_methods = [ + ["atime", ["FILENAME"]], + ["basename", ["fn", "*opts"]], + ["chmod", ["mode", "*FILENAMES"]], + ["chown", ["owner", "group", "*FILENAME"]], + ["ctime", ["FILENAMES"]], + ["delete", ["*FILENAMES"]], + ["dirname", ["FILENAME"]], + ["ftype", ["FILENAME"]], + ["join", ["*items"]], + ["link", ["FILENAME_O", "FILENAME_N"]], + ["lstat", ["FILENAME"]], + ["mtime", ["FILENAME"]], + ["readlink", ["FILENAME"]], + ["rename", ["FILENAME_FROM", "FILENAME_TO"]], + # ["size", ["FILENAME"]], + ["split", ["pathname"]], + ["stat", ["FILENAME"]], + ["symlink", ["FILENAME_O", "FILENAME_N"]], + ["truncate", ["FILENAME", "length"]], + ["utime", ["atime", "mtime", "*FILENAMES"]]] + + def_builtin_commands(File, normal_delegation_file_methods) + alias_method :rm, :delete + + # method related FileTest + def_builtin_commands(FileTest, + FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]}) + + # method related ftools + normal_delegation_ftools_methods = [ + ["syscopy", ["FILENAME_FROM", "FILENAME_TO"]], + ["copy", ["FILENAME_FROM", "FILENAME_TO"]], + ["move", ["FILENAME_FROM", "FILENAME_TO"]], + ["compare", ["FILENAME_FROM", "FILENAME_TO"]], + ["safe_unlink", ["*FILENAMES"]], + ["makedirs", ["*FILENAMES"]], + # ["chmod", ["mode", "*FILENAMES"]], + ["install", ["FILENAME_FROM", "FILENAME_TO", "mode"]], + ] + def_builtin_commands(File, + normal_delegation_ftools_methods) + alias_method :cmp, :compare + alias_method :mv, :move + alias_method :cp, :copy + alias_method :rm_f, :safe_unlink + alias_method :mkpath, :makedirs + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/error.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/error.rb new file mode 100644 index 00000000..959f9264 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/error.rb @@ -0,0 +1,26 @@ +# +# shell/error.rb - +# $Release Version: 0.6.0 $ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) +# +# -- +# +# +# + +require "e2mmap" + +class Shell + module Error + extend Exception2MessageMapper + def_e2message TypeError, "wrong argument type %s (expected %s)" + + def_exception :DirStackEmpty, "Directory stack empty." + def_exception :CantDefine, "Can't define method(%s, %s)." + def_exception :CantApplyMethod, "This method(%s) does not apply to this type(%s)." + def_exception :CommandNotFound, "Command not found(%s)." + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/filter.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/filter.rb new file mode 100644 index 00000000..1d2c0b9e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/filter.rb @@ -0,0 +1,110 @@ +# +# shell/filter.rb - +# $Release Version: 0.6.0 $ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) +# +# -- +# +# +# + +class Shell + # + # Filter + # A method to require + # each() + # + class Filter + include Enumerable + + def initialize(sh) + @shell = sh # parent shell + @input = nil # input filter + end + + attr_reader :input + + def input=(filter) + @input = filter + end + + def each(rs = nil) + rs = @shell.record_separator unless rs + if @input + @input.each(rs){|l| yield l} + end + end + + def < (src) + case src + when String + cat = Cat.new(@shell, src) + cat | self + when IO + self.input = src + self + else + Shell.Fail Error::CantApplyMethod, "<", to.class + end + end + + def > (to) + case to + when String + dst = @shell.open(to, "w") + begin + each(){|l| dst << l} + ensure + dst.close + end + when IO + each(){|l| to << l} + else + Shell.Fail Error::CantApplyMethod, ">", to.class + end + self + end + + def >> (to) + begin + Shell.cd(@shell.pwd).append(to, self) + rescue CantApplyMethod + Shell.Fail Error::CantApplyMethod, ">>", to.class + end + end + + def | (filter) + filter.input = self + if active? + @shell.process_controller.start_job filter + end + filter + end + + def + (filter) + Join.new(@shell, self, filter) + end + + def to_a + ary = [] + each(){|l| ary.push l} + ary + end + + def to_s + str = "" + each(){|l| str.concat l} + str + end + + def inspect + if @shell.debug.kind_of?(Integer) && @shell.debug > 2 + super + else + to_s + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/process-controller.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/process-controller.rb new file mode 100644 index 00000000..0ae975c8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/shell/process-controller.rb @@ -0,0 +1,260 @@ +# +# shell/process-controller.rb - +# $Release Version: 0.6.0 $ +# $Revision: 12008 $ +# $Date: 2007-03-06 19:12:12 +0900 (Tue, 06 Mar 2007) $ +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) +# +# -- +# +# +# + +require "mutex_m" +require "monitor" +require "sync" + +class Shell + class ProcessController + + @ProcessControllers = {} + @ProcessControllers.extend Mutex_m + + class< true +# a.new # NoMethodError - new is private ... +# +# * ``The instance'' is created at instantiation time, in other +# words the first call of Klass.instance(), thus +# +# class OtherKlass +# include Singleton +# # ... +# end +# ObjectSpace.each_object(OtherKlass){} # => 0. +# +# * This behavior is preserved under inheritance and cloning. +# +# +# +# This is achieved by marking +# * Klass.new and Klass.allocate - as private +# +# Providing (or modifying) the class methods +# * Klass.inherited(sub_klass) and Klass.clone() - +# to ensure that the Singleton pattern is properly +# inherited and cloned. +# +# * Klass.instance() - returning ``the instance''. After a +# successful self modifying (normally the first) call the +# method body is a simple: +# +# def Klass.instance() +# return @__instance__ +# end +# +# * Klass._load(str) - calling Klass.instance() +# +# * Klass._instantiate?() - returning ``the instance'' or +# nil. This hook method puts a second (or nth) thread calling +# Klass.instance() on a waiting loop. The return value +# signifies the successful completion or premature termination +# of the first, or more generally, current "instantiation thread". +# +# +# The instance method of Singleton are +# * clone and dup - raising TypeErrors to prevent cloning or duping +# +# * _dump(depth) - returning the empty string. Marshalling strips +# by default all state information, e.g. instance variables and +# taint state, from ``the instance''. Providing custom _load(str) +# and _dump(depth) hooks allows the (partially) resurrections of +# a previous state of ``the instance''. + + + +module Singleton + # disable build-in copying methods + def clone + raise TypeError, "can't clone instance of singleton #{self.class}" + end + def dup + raise TypeError, "can't dup instance of singleton #{self.class}" + end + + # default marshalling strategy + def _dump(depth=-1) + '' + end +end + + +class << Singleton + # Method body of first instance call. + FirstInstanceCall = proc do + # @__instance__ takes on one of the following values + # * nil - before and after a failed creation + # * false - during creation + # * sub_class instance - after a successful creation + # the form makes up for the lack of returns in progs + Thread.critical = true + if @__instance__.nil? + @__instance__ = false + Thread.critical = false + begin + @__instance__ = new + ensure + if @__instance__ + class < mes + puts mes +end + + + +puts "\nThreaded example with exception and customized #_instantiate?() hook"; p +Thread.abort_on_exception = false + +class Ups < SomeSingletonClass + def initialize + self.class.__sleep + puts "initialize called by thread ##{Thread.current[:i]}" + end +end + +class << Ups + def _instantiate? + @enter.push Thread.current[:i] + while false.equal?(@__instance__) + Thread.critical = false + sleep 0.08 + Thread.critical = true + end + @leave.push Thread.current[:i] + @__instance__ + end + + def __sleep + sleep(rand(0.08)) + end + + def new + begin + __sleep + raise "boom - thread ##{Thread.current[:i]} failed to create instance" + ensure + # simple flip-flop + class << self + remove_method :new + end + end + end + + def instantiate_all + @enter = [] + @leave = [] + 1.upto(9) {|i| + Thread.new { + begin + Thread.current[:i] = i + __sleep + instance + rescue RuntimeError => mes + puts mes + end + } + } + puts "Before there were #{num_of_instances(self)}" + sleep 3 + puts "Now there is #{num_of_instances(self)}" + puts "#{@enter.join '; '} was the order of threads entering the waiting loop" + puts "#{@leave.join '; '} was the order of threads leaving the waiting loop" + end +end + + +Ups.instantiate_all +# results in message like +# Before there were 0 Ups instance(s) +# boom - thread #6 failed to create instance +# initialize called by thread #3 +# Now there is 1 Ups instance(s) +# 3; 2; 1; 8; 4; 7; 5 was the order of threads entering the waiting loop +# 3; 2; 1; 7; 4; 8; 5 was the order of threads leaving the waiting loop + + +puts "\nLets see if class level cloning really works" +Yup = Ups.clone +def Yup.new + begin + __sleep + raise "boom - thread ##{Thread.current[:i]} failed to create instance" + ensure + # simple flip-flop + class << self + remove_method :new + end + end +end +Yup.instantiate_all + + +puts "\n\n","Customized marshalling" +class A + include Singleton + attr_accessor :persist, :die + def _dump(depth) + # this strips the @die information from the instance + Marshal.dump(@persist,depth) + end +end + +def A._load(str) + instance.persist = Marshal.load(str) + instance +end + +a = A.instance +a.persist = ["persist"] +a.die = "die" +a.taint + +stored_state = Marshal.dump(a) +# change state +a.persist = nil +a.die = nil +b = Marshal.load(stored_state) +p a == b # => true +p a.persist # => ["persist"] +p a.die # => nil + + +puts "\n\nSingleton with overridden default #inherited() hook" +class Up +end +def Up.inherited(sub_klass) + puts "#{sub_klass} subclasses #{self}" +end + + +class Middle < Up + include Singleton +end + +class Down < Middle; end + +puts "and basic \"Down test\" is #{Down.instance == Down.instance}\n +Various exceptions" + +begin + module AModule + include Singleton + end +rescue TypeError => mes + puts mes #=> Inclusion of the OO-Singleton module in module AModule +end + +begin + 'aString'.extend Singleton +rescue NoMethodError => mes + puts mes #=> undefined method `extend_object' for Singleton:Module +end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/attachment.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/attachment.rb new file mode 100644 index 00000000..1a59b140 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/attachment.rb @@ -0,0 +1,107 @@ +# soap/attachment.rb: SOAP4R - SwA implementation. +# Copyright (C) 2002, 2003 Jamie Herre and NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/baseData' +require 'soap/mapping' + + +module SOAP + + +class SOAPAttachment < SOAPExternalReference + attr_reader :data + + def initialize(value) + super() + @data = value + end + +private + + def external_contentid + @data.contentid + end +end + + +class Attachment + attr_reader :io + attr_accessor :contenttype + + def initialize(string_or_readable = nil) + @string_or_readable = string_or_readable + @contenttype = "application/octet-stream" + @contentid = nil + end + + def contentid + @contentid ||= Attachment.contentid(self) + end + + def contentid=(contentid) + @contentid = contentid + end + + def mime_contentid + '<' + contentid + '>' + end + + def content + if @content == nil and @string_or_readable != nil + @content = @string_or_readable.respond_to?(:read) ? + @string_or_readable.read : @string_or_readable + end + @content + end + + def to_s + content + end + + def write(out) + out.write(content) + end + + def save(filename) + File.open(filename, "wb") do |f| + write(f) + end + end + + def self.contentid(obj) + # this needs to be fixed + [obj.__id__.to_s, Process.pid.to_s].join('.') + end + + def self.mime_contentid(obj) + '<' + contentid(obj) + '>' + end +end + + +module Mapping + class AttachmentFactory < SOAP::Mapping::Factory + def obj2soap(soap_class, obj, info, map) + soap_obj = soap_class.new(obj) + mark_marshalled_obj(obj, soap_obj) + soap_obj + end + + def soap2obj(obj_class, node, info, map) + obj = node.data + mark_unmarshalled_obj(node, obj) + return true, obj + end + end + + DefaultRegistry.add(::SOAP::Attachment, ::SOAP::SOAPAttachment, + AttachmentFactory.new, nil) +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/baseData.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/baseData.rb new file mode 100644 index 00000000..0e8b00d4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/baseData.rb @@ -0,0 +1,942 @@ +# soap/baseData.rb: SOAP4R - Base type library +# Copyright (C) 2000, 2001, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/datatypes' +require 'soap/soap' + + +module SOAP + + +### +## Mix-in module for SOAP base type classes. +# +module SOAPModuleUtils + include SOAP + +public + + def decode(elename) + d = self.new + d.elename = elename + d + end +end + + +### +## for SOAP type(base and compound) +# +module SOAPType + attr_accessor :encodingstyle + attr_accessor :elename + attr_accessor :id + attr_reader :precedents + attr_accessor :root + attr_accessor :parent + attr_accessor :position + attr_reader :extraattr + attr_accessor :definedtype + + def initialize(*arg) + super + @encodingstyle = nil + @elename = XSD::QName::EMPTY + @id = nil + @precedents = [] + @root = false + @parent = nil + @position = nil + @definedtype = nil + @extraattr = {} + end + + def inspect + if self.is_a?(XSD::NSDBase) + sprintf("#<%s:0x%x %s %s>", self.class.name, __id__, self.elename, self.type) + else + sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.elename) + end + end + + def rootnode + node = self + while node = node.parent + break if SOAPEnvelope === node + end + node + end +end + + +### +## for SOAP base type +# +module SOAPBasetype + include SOAPType + include SOAP + + def initialize(*arg) + super + end +end + + +### +## for SOAP compound type +# +module SOAPCompoundtype + include SOAPType + include SOAP + + def initialize(*arg) + super + end +end + + +### +## Convenience datatypes. +# +class SOAPReference < XSD::NSDBase + include SOAPBasetype + extend SOAPModuleUtils + +public + + attr_accessor :refid + + # Override the definition in SOAPBasetype. + def initialize(obj = nil) + super() + @type = XSD::QName::EMPTY + @refid = nil + @obj = nil + __setobj__(obj) if obj + end + + def __getobj__ + @obj + end + + def __setobj__(obj) + @obj = obj + @refid = @obj.id || SOAPReference.create_refid(@obj) + @obj.id = @refid unless @obj.id + @obj.precedents << self + # Copies NSDBase information + @obj.type = @type unless @obj.type + end + + # Why don't I use delegate.rb? + # -> delegate requires target object type at initialize time. + # Why don't I use forwardable.rb? + # -> forwardable requires a list of forwarding methods. + # + # ToDo: Maybe I should use forwardable.rb and give it a methods list like + # delegate.rb... + # + def method_missing(msg_id, *params) + if @obj + @obj.send(msg_id, *params) + else + nil + end + end + + def refidstr + '#' + @refid + end + + def self.create_refid(obj) + 'id' + obj.__id__.to_s + end + + def self.decode(elename, refidstr) + if /\A#(.*)\z/ =~ refidstr + refid = $1 + elsif /\Acid:(.*)\z/ =~ refidstr + refid = $1 + else + raise ArgumentError.new("illegal refid #{refidstr}") + end + d = super(elename) + d.refid = refid + d + end +end + + +class SOAPExternalReference < XSD::NSDBase + include SOAPBasetype + extend SOAPModuleUtils + + def initialize + super() + @type = XSD::QName::EMPTY + end + + def referred + rootnode.external_content[external_contentid] = self + end + + def refidstr + 'cid:' + external_contentid + end + +private + + def external_contentid + raise NotImplementedError.new + end +end + + +class SOAPNil < XSD::XSDNil + include SOAPBasetype + extend SOAPModuleUtils +end + +# SOAPRawString is for sending raw string. In contrast to SOAPString, +# SOAP4R does not do XML encoding and does not convert its CES. The string it +# holds is embedded to XML instance directly as a 'xsd:string'. +class SOAPRawString < XSD::XSDString + include SOAPBasetype + extend SOAPModuleUtils +end + + +### +## Basic datatypes. +# +class SOAPAnySimpleType < XSD::XSDAnySimpleType + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPString < XSD::XSDString + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPBoolean < XSD::XSDBoolean + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPDecimal < XSD::XSDDecimal + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPFloat < XSD::XSDFloat + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPDouble < XSD::XSDDouble + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPDuration < XSD::XSDDuration + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPDateTime < XSD::XSDDateTime + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPTime < XSD::XSDTime + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPDate < XSD::XSDDate + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPGYearMonth < XSD::XSDGYearMonth + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPGYear < XSD::XSDGYear + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPGMonthDay < XSD::XSDGMonthDay + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPGDay < XSD::XSDGDay + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPGMonth < XSD::XSDGMonth + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPHexBinary < XSD::XSDHexBinary + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPBase64 < XSD::XSDBase64Binary + include SOAPBasetype + extend SOAPModuleUtils + Type = QName.new(EncodingNamespace, Base64Literal) + +public + # Override the definition in SOAPBasetype. + def initialize(value = nil) + super(value) + @type = Type + end + + def as_xsd + @type = XSD::XSDBase64Binary::Type + end +end + +class SOAPAnyURI < XSD::XSDAnyURI + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPQName < XSD::XSDQName + include SOAPBasetype + extend SOAPModuleUtils +end + + +class SOAPInteger < XSD::XSDInteger + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPNonPositiveInteger < XSD::XSDNonPositiveInteger + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPNegativeInteger < XSD::XSDNegativeInteger + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPLong < XSD::XSDLong + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPInt < XSD::XSDInt + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPShort < XSD::XSDShort + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPByte < XSD::XSDByte + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPNonNegativeInteger < XSD::XSDNonNegativeInteger + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPUnsignedLong < XSD::XSDUnsignedLong + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPUnsignedInt < XSD::XSDUnsignedInt + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPUnsignedShort < XSD::XSDUnsignedShort + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPUnsignedByte < XSD::XSDUnsignedByte + include SOAPBasetype + extend SOAPModuleUtils +end + +class SOAPPositiveInteger < XSD::XSDPositiveInteger + include SOAPBasetype + extend SOAPModuleUtils +end + + +### +## Compound datatypes. +# +class SOAPStruct < XSD::NSDBase + include SOAPCompoundtype + include Enumerable + +public + + def initialize(type = nil) + super() + @type = type || XSD::QName::EMPTY + @array = [] + @data = [] + end + + def to_s() + str = '' + self.each do |key, data| + str << "#{key}: #{data}\n" + end + str + end + + def add(name, value) + add_member(name, value) + end + + def [](idx) + if idx.is_a?(Range) + @data[idx] + elsif idx.is_a?(Integer) + if (idx > @array.size) + raise ArrayIndexOutOfBoundsError.new('In ' << @type.name) + end + @data[idx] + else + if @array.include?(idx) + @data[@array.index(idx)] + else + nil + end + end + end + + def []=(idx, data) + if @array.include?(idx) + data.parent = self if data.respond_to?(:parent=) + @data[@array.index(idx)] = data + else + add(idx, data) + end + end + + def key?(name) + @array.include?(name) + end + + def members + @array + end + + def to_obj + hash = {} + proptype = {} + each do |k, v| + value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s + case proptype[k] + when :single + hash[k] = [hash[k], value] + proptype[k] = :multi + when :multi + hash[k] << value + else + hash[k] = value + proptype[k] = :single + end + end + hash + end + + def each + idx = 0 + while idx < @array.length + yield(@array[idx], @data[idx]) + idx += 1 + end + end + + def replace + members.each do |member| + self[member] = yield(self[member]) + end + end + + def self.decode(elename, type) + s = SOAPStruct.new(type) + s.elename = elename + s + end + +private + + def add_member(name, value = nil) + value = SOAPNil.new() if value.nil? + @array.push(name) + value.elename = value.elename.dup_name(name) + @data.push(value) + value.parent = self if value.respond_to?(:parent=) + value + end +end + + +# SOAPElement is not typed so it is not derived from NSDBase. +class SOAPElement + include Enumerable + + attr_accessor :encodingstyle + + attr_accessor :elename + attr_accessor :id + attr_reader :precedents + attr_accessor :root + attr_accessor :parent + attr_accessor :position + attr_accessor :extraattr + + attr_accessor :qualified + + def initialize(elename, text = nil) + if !elename.is_a?(XSD::QName) + elename = XSD::QName.new(nil, elename) + end + @encodingstyle = LiteralNamespace + @elename = elename + @id = nil + @precedents = [] + @root = false + @parent = nil + @position = nil + @extraattr = {} + + @qualified = nil + + @array = [] + @data = [] + @text = text + end + + def inspect + sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.elename) + end + + # Text interface. + attr_accessor :text + alias data text + + # Element interfaces. + def add(value) + add_member(value.elename.name, value) + end + + def [](idx) + if @array.include?(idx) + @data[@array.index(idx)] + else + nil + end + end + + def []=(idx, data) + if @array.include?(idx) + data.parent = self if data.respond_to?(:parent=) + @data[@array.index(idx)] = data + else + add(data) + end + end + + def key?(name) + @array.include?(name) + end + + def members + @array + end + + def to_obj + if members.empty? + @text + else + hash = {} + proptype = {} + each do |k, v| + value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s + case proptype[k] + when :single + hash[k] = [hash[k], value] + proptype[k] = :multi + when :multi + hash[k] << value + else + hash[k] = value + proptype[k] = :single + end + end + hash + end + end + + def each + idx = 0 + while idx < @array.length + yield(@array[idx], @data[idx]) + idx += 1 + end + end + + def self.decode(elename) + o = SOAPElement.new(elename) + o + end + + def self.from_obj(obj, namespace = nil) + o = SOAPElement.new(nil) + case obj + when nil + o.text = nil + when Hash + obj.each do |elename, value| + if value.is_a?(Array) + value.each do |subvalue| + child = from_obj(subvalue, namespace) + child.elename = to_elename(elename, namespace) + o.add(child) + end + else + child = from_obj(value, namespace) + child.elename = to_elename(elename, namespace) + o.add(child) + end + end + else + o.text = obj.to_s + end + o + end + + def self.to_elename(obj, namespace = nil) + if obj.is_a?(XSD::QName) + obj + elsif /\A(.+):([^:]+)\z/ =~ obj.to_s + XSD::QName.new($1, $2) + else + XSD::QName.new(namespace, obj.to_s) + end + end + +private + + def add_member(name, value) + add_accessor(name) + @array.push(name) + @data.push(value) + value.parent = self if value.respond_to?(:parent=) + value + end + + if RUBY_VERSION > "1.7.0" + def add_accessor(name) + methodname = name + if self.respond_to?(methodname) + methodname = safe_accessor_name(methodname) + end + Mapping.define_singleton_method(self, methodname) do + @data[@array.index(name)] + end + Mapping.define_singleton_method(self, methodname + '=') do |value| + @data[@array.index(name)] = value + end + end + else + def add_accessor(name) + methodname = safe_accessor_name(name) + instance_eval <<-EOS + def #{methodname} + @data[@array.index(#{name.dump})] + end + + def #{methodname}=(value) + @data[@array.index(#{name.dump})] = value + end + EOS + end + end + + def safe_accessor_name(name) + "var_" << name.gsub(/[^a-zA-Z0-9_]/, '') + end +end + + +class SOAPArray < XSD::NSDBase + include SOAPCompoundtype + include Enumerable + +public + + attr_accessor :sparse + + attr_reader :offset, :rank + attr_accessor :size, :size_fixed + attr_reader :arytype + + def initialize(type = nil, rank = 1, arytype = nil) + super() + @type = type || ValueArrayName + @rank = rank + @data = Array.new + @sparse = false + @offset = Array.new(rank, 0) + @size = Array.new(rank, 0) + @size_fixed = false + @position = nil + @arytype = arytype + end + + def offset=(var) + @offset = var + @sparse = true + end + + def add(value) + self[*(@offset)] = value + end + + def [](*idxary) + if idxary.size != @rank + raise ArgumentError.new("given #{idxary.size} params does not match rank: #{@rank}") + end + + retrieve(idxary) + end + + def []=(*idxary) + value = idxary.slice!(-1) + + if idxary.size != @rank + raise ArgumentError.new("given #{idxary.size} params(#{idxary})" + + " does not match rank: #{@rank}") + end + + idx = 0 + while idx < idxary.size + if idxary[idx] + 1 > @size[idx] + @size[idx] = idxary[idx] + 1 + end + idx += 1 + end + + data = retrieve(idxary[0, idxary.size - 1]) + data[idxary.last] = value + + if value.is_a?(SOAPType) + value.elename = ITEM_NAME + # Sync type + unless @type.name + @type = XSD::QName.new(value.type.namespace, + SOAPArray.create_arytype(value.type.name, @rank)) + end + value.type ||= @type + end + + @offset = idxary + value.parent = self if value.respond_to?(:parent=) + offsetnext + end + + def each + @data.each do |data| + yield(data) + end + end + + def to_a + @data.dup + end + + def replace + @data = deep_map(@data) do |ele| + yield(ele) + end + end + + def deep_map(ary, &block) + ary.collect do |ele| + if ele.is_a?(Array) + deep_map(ele, &block) + else + new_obj = block.call(ele) + new_obj.elename = ITEM_NAME + new_obj + end + end + end + + def include?(var) + traverse_data(@data) do |v, *rank| + if v.is_a?(SOAPBasetype) && v.data == var + return true + end + end + false + end + + def traverse + traverse_data(@data) do |v, *rank| + unless @sparse + yield(v) + else + yield(v, *rank) if v && !v.is_a?(SOAPNil) + end + end + end + + def soap2array(ary) + traverse_data(@data) do |v, *position| + iteary = ary + rank = 1 + while rank < position.size + idx = position[rank - 1] + if iteary[idx].nil? + iteary = iteary[idx] = Array.new + else + iteary = iteary[idx] + end + rank += 1 + end + if block_given? + iteary[position.last] = yield(v) + else + iteary[position.last] = v + end + end + end + + def position + @position + end + +private + + ITEM_NAME = XSD::QName.new(nil, 'item') + + def retrieve(idxary) + data = @data + rank = 1 + while rank <= idxary.size + idx = idxary[rank - 1] + if data[idx].nil? + data = data[idx] = Array.new + else + data = data[idx] + end + rank += 1 + end + data + end + + def traverse_data(data, rank = 1) + idx = 0 + while idx < ranksize(rank) + if rank < @rank + traverse_data(data[idx], rank + 1) do |*v| + v[1, 0] = idx + yield(*v) + end + else + yield(data[idx], idx) + end + idx += 1 + end + end + + def ranksize(rank) + @size[rank - 1] + end + + def offsetnext + move = false + idx = @offset.size - 1 + while !move && idx >= 0 + @offset[idx] += 1 + if @size_fixed + if @offset[idx] < @size[idx] + move = true + else + @offset[idx] = 0 + idx -= 1 + end + else + move = true + end + end + end + + # Module function + +public + + def self.decode(elename, type, arytype) + typestr, nofary = parse_type(arytype.name) + rank = nofary.count(',') + 1 + plain_arytype = XSD::QName.new(arytype.namespace, typestr) + o = SOAPArray.new(type, rank, plain_arytype) + size = [] + nofary.split(',').each do |s| + if s.empty? + size.clear + break + else + size << s.to_i + end + end + unless size.empty? + o.size = size + o.size_fixed = true + end + o.elename = elename + o + end + +private + + def self.create_arytype(typename, rank) + "#{typename}[" << ',' * (rank - 1) << ']' + end + + TypeParseRegexp = Regexp.new('^(.+)\[([\d,]*)\]$') + + def self.parse_type(string) + TypeParseRegexp =~ string + return $1, $2 + end +end + + +require 'soap/mapping/typeMap' + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/element.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/element.rb new file mode 100644 index 00000000..cc58b5d3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/element.rb @@ -0,0 +1,258 @@ +# SOAP4R - SOAP elements library +# Copyright (C) 2000, 2001, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'soap/baseData' + + +module SOAP + + +### +## SOAP elements +# +module SOAPEnvelopeElement; end + +class SOAPFault < SOAPStruct + include SOAPEnvelopeElement + include SOAPCompoundtype + +public + + def faultcode + self['faultcode'] + end + + def faultstring + self['faultstring'] + end + + def faultactor + self['faultactor'] + end + + def detail + self['detail'] + end + + def faultcode=(rhs) + self['faultcode'] = rhs + end + + def faultstring=(rhs) + self['faultstring'] = rhs + end + + def faultactor=(rhs) + self['faultactor'] = rhs + end + + def detail=(rhs) + self['detail'] = rhs + end + + def initialize(faultcode = nil, faultstring = nil, faultactor = nil, detail = nil) + super(EleFaultName) + @elename = EleFaultName + @encodingstyle = EncodingNamespace + + if faultcode + self.faultcode = faultcode + self.faultstring = faultstring + self.faultactor = faultactor + self.detail = detail + self.faultcode.elename = EleFaultCodeName if self.faultcode + self.faultstring.elename = EleFaultStringName if self.faultstring + self.faultactor.elename = EleFaultActorName if self.faultactor + self.detail.elename = EleFaultDetailName if self.detail + end + faultcode.parent = self if faultcode + faultstring.parent = self if faultstring + faultactor.parent = self if faultactor + detail.parent = self if detail + end + + def encode(generator, ns, attrs = {}) + SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace) + SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace) + attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace + name = ns.name(@elename) + generator.encode_tag(name, attrs) + yield(self.faultcode) + yield(self.faultstring) + yield(self.faultactor) + yield(self.detail) if self.detail + generator.encode_tag_end(name, true) + end +end + + +class SOAPBody < SOAPStruct + include SOAPEnvelopeElement + + def initialize(data = nil, is_fault = false) + super(nil) + @elename = EleBodyName + @encodingstyle = nil + if data + if data.respond_to?(:elename) + add(data.elename.name, data) + else + data.to_a.each do |datum| + add(datum.elename.name, datum) + end + end + end + @is_fault = is_fault + end + + def encode(generator, ns, attrs = {}) + name = ns.name(@elename) + generator.encode_tag(name, attrs) + if @is_fault + yield(@data) + else + @data.each do |data| + yield(data) + end + end + generator.encode_tag_end(name, true) + end + + def root_node + @data.each do |node| + if node.root == 1 + return node + end + end + # No specified root... + @data.each do |node| + if node.root != 0 + return node + end + end + + raise Parser::FormatDecodeError.new('no root element') + end +end + + +class SOAPHeaderItem < XSD::NSDBase + include SOAPEnvelopeElement + include SOAPCompoundtype + +public + + attr_accessor :element + attr_accessor :mustunderstand + attr_accessor :encodingstyle + + def initialize(element, mustunderstand = true, encodingstyle = nil) + super() + @type = nil + @element = element + @mustunderstand = mustunderstand + @encodingstyle = encodingstyle + element.parent = self if element + end + + def encode(generator, ns, attrs = {}) + attrs.each do |key, value| + @element.extraattr[key] = value + end + @element.extraattr[ns.name(AttrMustUnderstandName)] = + (@mustunderstand ? '1' : '0') + if @encodingstyle + @element.extraattr[ns.name(AttrEncodingStyleName)] = @encodingstyle + end + @element.encodingstyle = @encodingstyle if !@element.encodingstyle + yield(@element) + end +end + + +class SOAPHeader < SOAPStruct + include SOAPEnvelopeElement + + def initialize + super(nil) + @elename = EleHeaderName + @encodingstyle = nil + end + + def encode(generator, ns, attrs = {}) + name = ns.name(@elename) + generator.encode_tag(name, attrs) + @data.each do |data| + yield(data) + end + generator.encode_tag_end(name, true) + end + + def add(name, value) + mu = (value.extraattr[AttrMustUnderstandName] == '1') + encstyle = value.extraattr[AttrEncodingStyleName] + item = SOAPHeaderItem.new(value, mu, encstyle) + super(name, item) + end + + def length + @data.length + end + alias size length +end + + +class SOAPEnvelope < XSD::NSDBase + include SOAPEnvelopeElement + include SOAPCompoundtype + + attr_reader :header + attr_reader :body + attr_reader :external_content + + def initialize(header = nil, body = nil) + super() + @type = nil + @elename = EleEnvelopeName + @encodingstyle = nil + @header = header + @body = body + @external_content = {} + header.parent = self if header + body.parent = self if body + end + + def header=(header) + header.parent = self + @header = header + end + + def body=(body) + body.parent = self + @body = body + end + + def encode(generator, ns, attrs = {}) + SOAPGenerator.assign_ns(attrs, ns, elename.namespace, SOAPNamespaceTag) + name = ns.name(@elename) + generator.encode_tag(name, attrs) + + yield(@header) if @header and @header.length > 0 + yield(@body) + + generator.encode_tag_end(name, true) + end + + def to_ary + [header, body] + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/aspDotNetHandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/aspDotNetHandler.rb new file mode 100644 index 00000000..fd7e0fa2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/aspDotNetHandler.rb @@ -0,0 +1,213 @@ +# SOAP4R - ASP.NET EncodingStyle handler library +# Copyright (C) 2001, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/encodingstyle/handler' + + +module SOAP +module EncodingStyle + + +class ASPDotNetHandler < Handler + Namespace = 'http://tempuri.org/ASP.NET' + add_handler + + def initialize(charset = nil) + super(charset) + @textbuf = '' + @decode_typemap = nil + end + + + ### + ## encode interface. + # + def encode_data(generator, ns, data, parent) + attrs = {} + # ASPDotNetHandler is intended to be used for accessing an ASP.NET doc/lit + # service as an rpc/encoded service. in the situation, local elements + # should be qualified. propagate parent's namespace to children. + if data.elename.namespace.nil? + data.elename.namespace = parent.elename.namespace + end + name = generator.encode_name(ns, data, attrs) + case data + when SOAPRawString + generator.encode_tag(name, attrs) + generator.encode_rawstring(data.to_s) + when XSD::XSDString + generator.encode_tag(name, attrs) + generator.encode_string(@charset ? + XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s) + when XSD::XSDAnySimpleType + generator.encode_tag(name, attrs) + generator.encode_string(data.to_s) + when SOAPStruct + generator.encode_tag(name, attrs) + data.each do |key, value| + generator.encode_child(ns, value, data) + end + when SOAPArray + generator.encode_tag(name, attrs) + data.traverse do |child, *rank| + data.position = nil + generator.encode_child(ns, child, data) + end + else + raise EncodingStyleError.new( + "unknown object:#{data} in this encodingStyle") + end + end + + def encode_data_end(generator, ns, data, parent) + name = generator.encode_name_end(ns, data) + cr = data.is_a?(SOAPCompoundtype) + generator.encode_tag_end(name, cr) + end + + + ### + ## decode interface. + # + class SOAPTemporalObject + attr_accessor :parent + + def initialize + @parent = nil + end + end + + class SOAPUnknown < SOAPTemporalObject + def initialize(handler, elename) + super() + @handler = handler + @elename = elename + end + + def as_struct + o = SOAPStruct.decode(@elename, XSD::AnyTypeName) + o.parent = @parent + o.type.name = @name + @handler.decode_parent(@parent, o) + o + end + + def as_string + o = SOAPString.decode(@elename) + o.parent = @parent + @handler.decode_parent(@parent, o) + o + end + + def as_nil + o = SOAPNil.decode(@elename) + o.parent = @parent + @handler.decode_parent(@parent, o) + o + end + end + + def decode_tag(ns, elename, attrs, parent) + @textbuf = '' + o = SOAPUnknown.new(self, elename) + o.parent = parent + o + end + + def decode_tag_end(ns, node) + o = node.node + if o.is_a?(SOAPUnknown) + newnode = o.as_string +# if /\A\s*\z/ =~ @textbuf +# o.as_struct +# else +# o.as_string +# end + node.replace_node(newnode) + o = node.node + end + + decode_textbuf(o) + @textbuf = '' + end + + def decode_text(ns, text) + # @textbuf is set at decode_tag_end. + @textbuf << text + end + + def decode_prologue + end + + def decode_epilogue + end + + def decode_parent(parent, node) + case parent.node + when SOAPUnknown + newparent = parent.node.as_struct + node.parent = newparent + parent.replace_node(newparent) + decode_parent(parent, node) + + when SOAPStruct + data = parent.node[node.elename.name] + case data + when nil + parent.node.add(node.elename.name, node) + when SOAPArray + name, type_ns = node.elename.name, node.type.namespace + data.add(node) + node.elename, node.type.namespace = name, type_ns + else + parent.node[node.elename.name] = SOAPArray.new + name, type_ns = data.elename.name, data.type.namespace + parent.node[node.elename.name].add(data) + data.elename.name, data.type.namespace = name, type_ns + name, type_ns = node.elename.name, node.type.namespace + parent.node[node.elename.name].add(node) + node.elename.name, node.type.namespace = name, type_ns + end + + when SOAPArray + if node.position + parent.node[*(decode_arypos(node.position))] = node + parent.node.sparse = true + else + parent.node.add(node) + end + + when SOAPBasetype + raise EncodingStyleError.new("SOAP base type must not have a child") + + else + # SOAPUnknown does not have parent. + # raise EncodingStyleError.new("illegal parent: #{parent}") + end + end + +private + + def decode_textbuf(node) + if node.is_a?(XSD::XSDString) + if @charset + node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset)) + else + node.set(@textbuf) + end + else + # Nothing to do... + end + end +end + +ASPDotNetHandler.new + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/handler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/handler.rb new file mode 100644 index 00000000..c0154174 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/handler.rb @@ -0,0 +1,100 @@ +# SOAP4R - EncodingStyle handler library +# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/soap' +require 'soap/baseData' +require 'soap/element' + + +module SOAP +module EncodingStyle + + +class Handler + @@handlers = {} + + class EncodingStyleError < Error; end + + class << self + def uri + self::Namespace + end + + def handler(uri) + @@handlers[uri] + end + + def each + @@handlers.each do |key, value| + yield(value) + end + end + + private + + def add_handler + @@handlers[self.uri] = self + end + end + + attr_reader :charset + attr_accessor :generate_explicit_type + def decode_typemap=(definedtypes) + @decode_typemap = definedtypes + end + + def initialize(charset) + @charset = charset + @generate_explicit_type = true + @decode_typemap = nil + end + + ### + ## encode interface. + # + # Returns a XML instance as a string. + def encode_data(generator, ns, data, parent) + raise NotImplementError + end + + def encode_data_end(generator, ns, data, parent) + raise NotImplementError + end + + def encode_prologue + end + + def encode_epilogue + end + + ### + ## decode interface. + # + # Returns SOAP/OM data. + def decode_tag(ns, name, attrs, parent) + raise NotImplementError.new('Method decode_tag must be defined in derived class.') + end + + def decode_tag_end(ns, name) + raise NotImplementError.new('Method decode_tag_end must be defined in derived class.') + end + + def decode_text(ns, text) + raise NotImplementError.new('Method decode_text must be defined in derived class.') + end + + def decode_prologue + end + + def decode_epilogue + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/literalHandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/literalHandler.rb new file mode 100644 index 00000000..59c72053 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/literalHandler.rb @@ -0,0 +1,226 @@ +# SOAP4R - XML Literal EncodingStyle handler library +# Copyright (C) 2001, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/encodingstyle/handler' + + +module SOAP +module EncodingStyle + + +class LiteralHandler < Handler + Namespace = SOAP::LiteralNamespace + add_handler + + def initialize(charset = nil) + super(charset) + @textbuf = '' + end + + + ### + ## encode interface. + # + def encode_data(generator, ns, data, parent) + attrs = {} + name = generator.encode_name(ns, data, attrs) + data.extraattr.each do |k, v| + # ToDo: check generator.attributeformdefault here + if k.is_a?(XSD::QName) + if k.namespace + SOAPGenerator.assign_ns(attrs, ns, k.namespace) + k = ns.name(k) + else + k = k.name + end + end + attrs[k] = v + end + case data + when SOAPRawString + generator.encode_tag(name, attrs) + generator.encode_rawstring(data.to_s) + when XSD::XSDString + generator.encode_tag(name, attrs) + str = data.to_s + str = XSD::Charset.encoding_to_xml(str, @charset) if @charset + generator.encode_string(str) + when XSD::XSDAnySimpleType + generator.encode_tag(name, attrs) + generator.encode_string(data.to_s) + when SOAPStruct + generator.encode_tag(name, attrs) + data.each do |key, value| + generator.encode_child(ns, value, data) + end + when SOAPArray + generator.encode_tag(name, attrs) + data.traverse do |child, *rank| + data.position = nil + generator.encode_child(ns, child, data) + end + when SOAPElement + # passes 2 times for simplifying namespace definition + data.each do |key, value| + if value.elename.namespace + SOAPGenerator.assign_ns(attrs, ns, value.elename.namespace) + end + end + generator.encode_tag(name, attrs) + generator.encode_rawstring(data.text) if data.text + data.each do |key, value| + generator.encode_child(ns, value, data) + end + else + raise EncodingStyleError.new( + "unknown object:#{data} in this encodingStyle") + end + end + + def encode_data_end(generator, ns, data, parent) + name = generator.encode_name_end(ns, data) + cr = (data.is_a?(SOAPCompoundtype) or + (data.is_a?(SOAPElement) and !data.text)) + generator.encode_tag_end(name, cr) + end + + + ### + ## decode interface. + # + class SOAPTemporalObject + attr_accessor :parent + + def initialize + @parent = nil + end + end + + class SOAPUnknown < SOAPTemporalObject + def initialize(handler, elename, extraattr) + super() + @handler = handler + @elename = elename + @extraattr = extraattr + end + + def as_element + o = SOAPElement.decode(@elename) + o.parent = @parent + o.extraattr.update(@extraattr) + @handler.decode_parent(@parent, o) + o + end + + def as_string + o = SOAPString.decode(@elename) + o.parent = @parent + o.extraattr.update(@extraattr) + @handler.decode_parent(@parent, o) + o + end + + def as_nil + o = SOAPNil.decode(@elename) + o.parent = @parent + o.extraattr.update(@extraattr) + @handler.decode_parent(@parent, o) + o + end + end + + def decode_tag(ns, elename, attrs, parent) + @textbuf = '' + o = SOAPUnknown.new(self, elename, decode_attrs(ns, attrs)) + o.parent = parent + o + end + + def decode_tag_end(ns, node) + o = node.node + if o.is_a?(SOAPUnknown) + newnode = if /\A\s*\z/ =~ @textbuf + o.as_element + else + o.as_string + end + node.replace_node(newnode) + o = node.node + end + + decode_textbuf(o) + @textbuf = '' + end + + def decode_text(ns, text) + # @textbuf is set at decode_tag_end. + @textbuf << text + end + + def decode_attrs(ns, attrs) + extraattr = {} + attrs.each do |key, value| + qname = ns.parse_local(key) + extraattr[qname] = value + end + extraattr + end + + def decode_prologue + end + + def decode_epilogue + end + + def decode_parent(parent, node) + return unless parent.node + case parent.node + when SOAPUnknown + newparent = parent.node.as_element + node.parent = newparent + parent.replace_node(newparent) + decode_parent(parent, node) + when SOAPElement + parent.node.add(node) + node.parent = parent.node + when SOAPStruct + parent.node.add(node.elename.name, node) + node.parent = parent.node + when SOAPArray + if node.position + parent.node[*(decode_arypos(node.position))] = node + parent.node.sparse = true + else + parent.node.add(node) + end + node.parent = parent.node + else + raise EncodingStyleError.new("illegal parent: #{parent.node}") + end + end + +private + + def decode_textbuf(node) + if node.is_a?(XSD::XSDString) + if @charset + node.set(XSD::Charset.encoding_from_xml(@textbuf, @charset)) + else + node.set(@textbuf) + end + else + # Nothing to do... + end + end +end + +LiteralHandler.new + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/soapHandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/soapHandler.rb new file mode 100644 index 00000000..a5223926 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/encodingstyle/soapHandler.rb @@ -0,0 +1,582 @@ +# SOAP4R - SOAP EncodingStyle handler library +# Copyright (C) 2001, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/encodingstyle/handler' + + +module SOAP +module EncodingStyle + + +class SOAPHandler < Handler + Namespace = SOAP::EncodingNamespace + add_handler + + def initialize(charset = nil) + super(charset) + @refpool = [] + @idpool = [] + @textbuf = '' + @is_first_top_ele = true + end + + + ### + ## encode interface. + # + def encode_data(generator, ns, data, parent) + attrs = encode_attrs(generator, ns, data, parent) + if parent && parent.is_a?(SOAPArray) && parent.position + attrs[ns.name(AttrPositionName)] = "[#{parent.position.join(',')}]" + end + name = generator.encode_name(ns, data, attrs) + case data + when SOAPReference + attrs['href'] = data.refidstr + generator.encode_tag(name, attrs) + when SOAPExternalReference + data.referred + attrs['href'] = data.refidstr + generator.encode_tag(name, attrs) + when SOAPRawString + generator.encode_tag(name, attrs) + generator.encode_rawstring(data.to_s) + when XSD::XSDString + generator.encode_tag(name, attrs) + generator.encode_string(@charset ? + XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s) + when XSD::XSDAnySimpleType + generator.encode_tag(name, attrs) + generator.encode_string(data.to_s) + when SOAPStruct + generator.encode_tag(name, attrs) + data.each do |key, value| + generator.encode_child(ns, value, data) + end + when SOAPArray + generator.encode_tag(name, attrs) + data.traverse do |child, *rank| + data.position = data.sparse ? rank : nil + generator.encode_child(ns, child, data) + end + else + raise EncodingStyleError.new( + "unknown object:#{data} in this encodingStyle") + end + end + + def encode_data_end(generator, ns, data, parent) + name = generator.encode_name_end(ns, data) + cr = data.is_a?(SOAPCompoundtype) + generator.encode_tag_end(name, cr) + end + + + ### + ## decode interface. + # + class SOAPTemporalObject + attr_accessor :parent + attr_accessor :position + attr_accessor :id + attr_accessor :root + + def initialize + @parent = nil + @position = nil + @id = nil + @root = nil + end + end + + class SOAPUnknown < SOAPTemporalObject + attr_reader :type + attr_accessor :definedtype + attr_reader :extraattr + + def initialize(handler, elename, type, extraattr) + super() + @handler = handler + @elename = elename + @type = type + @extraattr = extraattr + @definedtype = nil + end + + def as_struct + o = SOAPStruct.decode(@elename, @type) + o.id = @id + o.root = @root + o.parent = @parent + o.position = @position + o.extraattr.update(@extraattr) + @handler.decode_parent(@parent, o) + o + end + + def as_string + o = SOAPString.decode(@elename) + o.id = @id + o.root = @root + o.parent = @parent + o.position = @position + o.extraattr.update(@extraattr) + @handler.decode_parent(@parent, o) + o + end + + def as_nil + o = SOAPNil.decode(@elename) + o.id = @id + o.root = @root + o.parent = @parent + o.position = @position + o.extraattr.update(@extraattr) + @handler.decode_parent(@parent, o) + o + end + end + + def decode_tag(ns, elename, attrs, parent) + @textbuf = '' + is_nil, type, arytype, root, offset, position, href, id, extraattr = + decode_attrs(ns, attrs) + o = nil + if is_nil + o = SOAPNil.decode(elename) + elsif href + o = SOAPReference.decode(elename, href) + @refpool << o + elsif @decode_typemap + o = decode_tag_by_wsdl(ns, elename, type, parent.node, arytype, extraattr) + else + o = decode_tag_by_type(ns, elename, type, parent.node, arytype, extraattr) + end + + if o.is_a?(SOAPArray) + if offset + o.offset = decode_arypos(offset) + o.sparse = true + else + o.sparse = false + end + end + + o.parent = parent + o.id = id + o.root = root + o.position = position + + unless o.is_a?(SOAPTemporalObject) + @idpool << o if o.id + decode_parent(parent, o) + end + o + end + + def decode_tag_end(ns, node) + o = node.node + if o.is_a?(SOAPUnknown) + newnode = if /\A\s*\z/ =~ @textbuf + o.as_struct + else + o.as_string + end + if newnode.id + @idpool << newnode + end + node.replace_node(newnode) + o = node.node + end + decode_textbuf(o) + # unlink definedtype + o.definedtype = nil + end + + def decode_text(ns, text) + @textbuf << text + end + + def decode_prologue + @refpool.clear + @idpool.clear + @is_first_top_ele = true + end + + def decode_epilogue + decode_resolve_id + end + + def decode_parent(parent, node) + return unless parent.node + case parent.node + when SOAPUnknown + newparent = parent.node.as_struct + node.parent = newparent + if newparent.id + @idpool << newparent + end + parent.replace_node(newparent) + decode_parent(parent, node) + when SOAPStruct + parent.node.add(node.elename.name, node) + node.parent = parent.node + when SOAPArray + if node.position + parent.node[*(decode_arypos(node.position))] = node + parent.node.sparse = true + else + parent.node.add(node) + end + node.parent = parent.node + else + raise EncodingStyleError.new("illegal parent: #{parent.node}") + end + end + +private + + def content_ranksize(typename) + typename.scan(/\[[\d,]*\]$/)[0] + end + + def content_typename(typename) + typename.sub(/\[,*\]$/, '') + end + + def create_arytype(ns, data) + XSD::QName.new(data.arytype.namespace, + content_typename(data.arytype.name) + "[#{data.size.join(',')}]") + end + + def encode_attrs(generator, ns, data, parent) + attrs = {} + return attrs if data.is_a?(SOAPReference) + + if !parent || parent.encodingstyle != EncodingNamespace + if @generate_explicit_type + SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace) + attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace + end + data.encodingstyle = EncodingNamespace + end + + if data.is_a?(SOAPNil) + attrs[ns.name(XSD::AttrNilName)] = XSD::NilValue + elsif @generate_explicit_type + if data.type.namespace + SOAPGenerator.assign_ns(attrs, ns, data.type.namespace) + end + if data.is_a?(SOAPArray) + if data.arytype.namespace + SOAPGenerator.assign_ns(attrs, ns, data.arytype.namespace) + end + SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace) + attrs[ns.name(AttrArrayTypeName)] = ns.name(create_arytype(ns, data)) + if data.type.name + attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type) + end + elsif parent && parent.is_a?(SOAPArray) && (parent.arytype == data.type) + # No need to add. + elsif !data.type.namespace + # No need to add. + else + attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type) + end + end + + data.extraattr.each do |key, value| + SOAPGenerator.assign_ns(attrs, ns, key.namespace) + attrs[ns.name(key)] = encode_attr_value(generator, ns, key, value) + end + if data.id + attrs['id'] = data.id + end + attrs + end + + def encode_attr_value(generator, ns, qname, value) + if value.is_a?(SOAPType) + ref = SOAPReference.new(value) + generator.add_reftarget(qname.name, value) + ref.refidstr + else + value.to_s + end + end + + def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, extraattr) + o = nil + if parent.class == SOAPBody + # root element: should branch by root attribute? + if @is_first_top_ele + # Unqualified name is allowed here. + @is_first_top_ele = false + type = @decode_typemap[elename] || + @decode_typemap.find_name(elename.name) + if type + o = SOAPStruct.new(elename) + o.definedtype = type + return o + end + end + # multi-ref element. + if typestr + typename = ns.parse(typestr) + typedef = @decode_typemap[typename] + if typedef + return decode_definedtype(elename, typename, typedef, arytypestr) + end + end + return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, + extraattr) + end + + if parent.type == XSD::AnyTypeName + return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, + extraattr) + end + + # parent.definedtype == nil means the parent is SOAPUnknown. SOAPUnknown + # is generated by decode_tag_by_type when its type is anyType. + parenttype = parent.definedtype || @decode_typemap[parent.type] + unless parenttype + return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, + extraattr) + end + + definedtype_name = parenttype.child_type(elename) + if definedtype_name and (klass = TypeMap[definedtype_name]) + return decode_basetype(klass, elename) + elsif definedtype_name == XSD::AnyTypeName + return decode_tag_by_type(ns, elename, typestr, parent, arytypestr, + extraattr) + end + + if definedtype_name + typedef = @decode_typemap[definedtype_name] + else + typedef = parenttype.child_defined_complextype(elename) + end + decode_definedtype(elename, definedtype_name, typedef, arytypestr) + end + + def decode_definedtype(elename, typename, typedef, arytypestr) + unless typedef + raise EncodingStyleError.new("unknown type '#{typename}'") + end + if typedef.is_a?(::WSDL::XMLSchema::SimpleType) + decode_defined_simpletype(elename, typename, typedef, arytypestr) + else + decode_defined_complextype(elename, typename, typedef, arytypestr) + end + end + + def decode_basetype(klass, elename) + klass.decode(elename) + end + + def decode_defined_simpletype(elename, typename, typedef, arytypestr) + o = decode_basetype(TypeMap[typedef.base], elename) + o.definedtype = typedef + o + end + + def decode_defined_complextype(elename, typename, typedef, arytypestr) + case typedef.compoundtype + when :TYPE_STRUCT, :TYPE_MAP + o = SOAPStruct.decode(elename, typename) + o.definedtype = typedef + return o + when :TYPE_ARRAY + expected_arytype = typedef.find_arytype + if arytypestr + actual_arytype = XSD::QName.new(expected_arytype.namespace, + content_typename(expected_arytype.name) << + content_ranksize(arytypestr)) + o = SOAPArray.decode(elename, typename, actual_arytype) + else + o = SOAPArray.new(typename, 1, expected_arytype) + o.elename = elename + end + o.definedtype = typedef + return o + when :TYPE_EMPTY + o = SOAPNil.decode(elename) + o.definedtype = typedef + return o + else + raise RuntimeError.new( + "Unknown kind of complexType: #{typedef.compoundtype}") + end + nil + end + + def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr) + if arytypestr + type = typestr ? ns.parse(typestr) : ValueArrayName + node = SOAPArray.decode(elename, type, ns.parse(arytypestr)) + node.extraattr.update(extraattr) + return node + end + + type = nil + if typestr + type = ns.parse(typestr) + elsif parent.is_a?(SOAPArray) + type = parent.arytype + else + # Since it's in dynamic(without any type) encoding process, + # assumes entity as its type itself. + # => type Array in SOAP-ENC. + # => type Country in foo. + type = elename + end + + if (klass = TypeMap[type]) + node = decode_basetype(klass, elename) + node.extraattr.update(extraattr) + return node + end + + # Unknown type... Struct or String + SOAPUnknown.new(self, elename, type, extraattr) + end + + def decode_textbuf(node) + case node + when XSD::XSDHexBinary, XSD::XSDBase64Binary + node.set_encoded(@textbuf) + when XSD::XSDString + if @charset + @textbuf = XSD::Charset.encoding_from_xml(@textbuf, @charset) + end + if node.definedtype + node.definedtype.check_lexical_format(@textbuf) + end + node.set(@textbuf) + when SOAPNil + # Nothing to do. + when SOAPBasetype + node.set(@textbuf) + else + # Nothing to do... + end + @textbuf = '' + end + + NilLiteralMap = { + 'true' => true, + '1' => true, + 'false' => false, + '0' => false + } + RootLiteralMap = { + '1' => 1, + '0' => 0 + } + def decode_attrs(ns, attrs) + is_nil = false + type = nil + arytype = nil + root = nil + offset = nil + position = nil + href = nil + id = nil + extraattr = {} + + attrs.each do |key, value| + qname = ns.parse(key) + case qname.namespace + when XSD::InstanceNamespace + case qname.name + when XSD::NilLiteral + is_nil = NilLiteralMap[value] or + raise EncodingStyleError.new("cannot accept attribute value: #{value} as the value of xsi:#{XSD::NilLiteral} (expected 'true', 'false', '1', or '0')") + next + when XSD::AttrType + type = value + next + end + when EncodingNamespace + case qname.name + when AttrArrayType + arytype = value + next + when AttrRoot + root = RootLiteralMap[value] or + raise EncodingStyleError.new( + "illegal root attribute value: #{value}") + next + when AttrOffset + offset = value + next + when AttrPosition + position = value + next + end + end + if key == 'href' + href = value + next + elsif key == 'id' + id = value + next + end + qname = ns.parse_local(key) + extraattr[qname] = decode_attr_value(ns, qname, value) + end + + return is_nil, type, arytype, root, offset, position, href, id, extraattr + end + + def decode_attr_value(ns, qname, value) + if /\A#/ =~ value + o = SOAPReference.decode(nil, value) + @refpool << o + o + else + value + end + end + + def decode_arypos(position) + /^\[(.+)\]$/ =~ position + $1.split(',').collect { |s| s.to_i } + end + + def decode_resolve_id + count = @refpool.length # To avoid infinite loop + while !@refpool.empty? && count > 0 + @refpool = @refpool.find_all { |ref| + o = @idpool.find { |item| + item.id == ref.refid + } + if o.is_a?(SOAPReference) + true # link of link. + elsif o + ref.__setobj__(o) + false + elsif o = ref.rootnode.external_content[ref.refid] + ref.__setobj__(o) + false + else + raise EncodingStyleError.new("unresolved reference: #{ref.refid}") + end + } + count -= 1 + end + end +end + +SOAPHandler.new + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/generator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/generator.rb new file mode 100644 index 00000000..f179555e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/generator.rb @@ -0,0 +1,268 @@ +# SOAP4R - SOAP XML Instance Generator library. +# Copyright (C) 2001, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/ns' +require 'soap/soap' +require 'soap/baseData' +require 'soap/encodingstyle/handler' + + +module SOAP + + +### +## CAUTION: MT-unsafe +# +class SOAPGenerator + include SOAP + + class FormatEncodeError < Error; end + +public + + attr_accessor :charset + attr_accessor :default_encodingstyle + attr_accessor :generate_explicit_type + attr_accessor :use_numeric_character_reference + + def initialize(opt = {}) + @reftarget = nil + @handlers = {} + @charset = opt[:charset] || XSD::Charset.xml_encoding_label + @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace + @generate_explicit_type = + opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true + @elementformdefault = opt[:elementformdefault] + @attributeformdefault = opt[:attributeformdefault] + @use_numeric_character_reference = opt[:use_numeric_character_reference] + @indentstr = opt[:no_indent] ? '' : ' ' + @buf = @indent = @curr = nil + end + + def generate(obj, io = nil) + @buf = io || '' + @indent = '' + + prologue + @handlers.each do |uri, handler| + handler.encode_prologue + end + + ns = XSD::NS.new + @buf << xmldecl + encode_data(ns, obj, nil) + + @handlers.each do |uri, handler| + handler.encode_epilogue + end + epilogue + + @buf + end + + def encode_data(ns, obj, parent) + if obj.is_a?(SOAPEnvelopeElement) + encode_element(ns, obj, parent) + return + end + if @reftarget && !obj.precedents.empty? + add_reftarget(obj.elename.name, obj) + ref = SOAPReference.new(obj) + ref.elename = ref.elename.dup_name(obj.elename.name) + obj.precedents.clear # Avoid cyclic delay. + obj.encodingstyle = parent.encodingstyle + # SOAPReference is encoded here. + obj = ref + end + encodingstyle = obj.encodingstyle + # Children's encodingstyle is derived from its parent. + encodingstyle ||= parent.encodingstyle if parent + obj.encodingstyle = encodingstyle + handler = find_handler(encodingstyle || @default_encodingstyle) + unless handler + raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.") + end + if !obj.elename.name + raise FormatEncodeError.new("Element name not defined: #{ obj }.") + end + handler.encode_data(self, ns, obj, parent) + handler.encode_data_end(self, ns, obj, parent) + end + + def add_reftarget(name, node) + unless @reftarget + raise FormatEncodeError.new("Reftarget is not defined.") + end + @reftarget.add(name, node) + end + + def encode_child(ns, child, parent) + indent_backup, @indent = @indent, @indent + @indentstr + encode_data(ns.clone_ns, child, parent) + @indent = indent_backup + end + + def encode_element(ns, obj, parent) + attrs = {} + if obj.is_a?(SOAPBody) + @reftarget = obj + obj.encode(self, ns, attrs) do |child| + indent_backup, @indent = @indent, @indent + @indentstr + encode_data(ns.clone_ns, child, obj) + @indent = indent_backup + end + @reftarget = nil + else + if obj.is_a?(SOAPEnvelope) + # xsi:nil="true" can appear even if dumping without explicit type. + SOAPGenerator.assign_ns(attrs, ns, + XSD::InstanceNamespace, XSINamespaceTag) + if @generate_explicit_type + SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag) + end + end + obj.encode(self, ns, attrs) do |child| + indent_backup, @indent = @indent, @indent + @indentstr + encode_data(ns.clone_ns, child, obj) + @indent = indent_backup + end + end + end + + def encode_name(ns, data, attrs) + if element_local?(data) + data.elename.name + else + if element_qualified?(data) + SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '') + else + SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace) + end + ns.name(data.elename) + end + end + + def encode_name_end(ns, data) + if element_local?(data) + data.elename.name + else + ns.name(data.elename) + end + end + + def encode_tag(elename, attrs = nil) + if !attrs or attrs.empty? + @buf << "\n#{ @indent }<#{ elename }>" + elsif attrs.size == 1 + key, value = attrs.shift + @buf << %Q[\n#{ @indent }<#{ elename } #{ key }="#{ value }">] + else + @buf << "\n#{ @indent }<#{ elename } " << + attrs.collect { |key, value| + %Q[#{ key }="#{ value }"] + }.join("\n#{ @indent }#{ @indentstr * 2 }") << + '>' + end + end + + def encode_tag_end(elename, cr = nil) + if cr + @buf << "\n#{ @indent }" + else + @buf << "" + end + end + + def encode_rawstring(str) + @buf << str + end + + EncodeMap = { + '&' => '&', + '<' => '<', + '>' => '>', + '"' => '"', + '\'' => ''', + "\r" => ' ' + } + EncodeCharRegexp = Regexp.new("[#{EncodeMap.keys.join}]") + def encode_string(str) + if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str) + str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] } + @buf << str.unpack("U*").collect { |c| + if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f) + c.chr + else + sprintf("&#x%x;", c) + end + }.join + else + @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] } + end + end + + def element_local?(element) + element.elename.namespace.nil? + end + + def element_qualified?(element) + if element.respond_to?(:qualified) + if element.qualified.nil? + @elementformdefault + else + element.qualified + end + else + @elementformdefault + end + end + + def self.assign_ns(attrs, ns, namespace, tag = nil) + if namespace.nil? + raise FormatEncodeError.new("empty namespace") + end + unless ns.assigned?(namespace) + tag = ns.assign(namespace, tag) + if tag == '' + attr = 'xmlns' + else + attr = "xmlns:#{tag}" + end + attrs[attr] = namespace + end + end + +private + + def prologue + end + + def epilogue + end + + def find_handler(encodingstyle) + unless @handlers.key?(encodingstyle) + handler = SOAP::EncodingStyle::Handler.handler(encodingstyle).new(@charset) + handler.generate_explicit_type = @generate_explicit_type + handler.encode_prologue + @handlers[encodingstyle] = handler + end + @handlers[encodingstyle] + end + + def xmldecl + if @charset + %Q[] + else + %Q[] + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/handler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/handler.rb new file mode 100644 index 00000000..7da2836e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/handler.rb @@ -0,0 +1,57 @@ +# SOAP4R - SOAP Header handler item +# Copyright (C) 2003, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/element' + + +module SOAP +module Header + + +class Handler + attr_reader :elename + attr_reader :mustunderstand + attr_reader :encodingstyle + + def initialize(elename) + @elename = elename + @mustunderstand = false + @encodingstyle = nil + end + + # Should return a SOAP/OM, a SOAPHeaderItem or nil. + def on_outbound + nil + end + + # Given header is a SOAPHeaderItem or nil. + def on_inbound(header, mustunderstand = false) + # do something. + end + + def on_outbound_headeritem + item = on_outbound + if item.nil? + nil + elsif item.is_a?(::SOAP::SOAPHeaderItem) + item.elename = @elename + item + else + item.elename = @elename + ::SOAP::SOAPHeaderItem.new(item, @mustunderstand, @encodingstyle) + end + end + + def on_inbound_headeritem(header) + on_inbound(header.element, header.mustunderstand) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/handlerset.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/handlerset.rb new file mode 100644 index 00000000..a8eee030 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/handlerset.rb @@ -0,0 +1,70 @@ +# SOAP4R - SOAP Header handler set +# Copyright (C) 2003, 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/namedelements' + + +module SOAP +module Header + + +class HandlerSet + def initialize + @store = XSD::NamedElements.new + end + + def dup + obj = HandlerSet.new + obj.store = @store.dup + obj + end + + def add(handler) + @store << handler + end + alias << add + + def delete(handler) + @store.delete(handler) + end + + def include?(handler) + @store.include?(handler) + end + + # returns: Array of SOAPHeaderItem + def on_outbound + @store.collect { |handler| + handler.on_outbound_headeritem + }.compact + end + + # headers: SOAPHeaderItem enumerable object + def on_inbound(headers) + headers.each do |name, item| + handler = @store.find { |handler| + handler.elename == item.element.elename + } + if handler + handler.on_inbound_headeritem(item) + elsif item.mustunderstand + raise UnhandledMustUnderstandHeaderError.new(item.element.elename.to_s) + end + end + end + +protected + + def store=(store) + @store = store + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/simplehandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/simplehandler.rb new file mode 100644 index 00000000..7b206f77 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/header/simplehandler.rb @@ -0,0 +1,44 @@ +# SOAP4R - SOAP Simple header item handler +# Copyright (C) 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/header/handler' +require 'soap/baseData' + + +module SOAP +module Header + + +class SimpleHandler < SOAP::Header::Handler + def initialize(elename) + super(elename) + end + + # Should return a Hash, String or nil. + def on_simple_outbound + nil + end + + # Given header is a Hash, String or nil. + def on_simple_inbound(header, mustunderstand) + end + + def on_outbound + h = on_simple_outbound + h ? SOAPElement.from_obj(h, elename.namespace) : nil + end + + def on_inbound(header, mustunderstand) + h = header.respond_to?(:to_obj) ? header.to_obj : header.data + on_simple_inbound(h, mustunderstand) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/httpconfigloader.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/httpconfigloader.rb new file mode 100644 index 00000000..cd7bca8a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/httpconfigloader.rb @@ -0,0 +1,119 @@ +# SOAP4R - HTTP config loader. +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/property' + + +module SOAP + + +module HTTPConfigLoader +module_function + + def set_options(client, options) + client.proxy = options["proxy"] + options.add_hook("proxy") do |key, value| + client.proxy = value + end + client.no_proxy = options["no_proxy"] + options.add_hook("no_proxy") do |key, value| + client.no_proxy = value + end + if client.respond_to?(:protocol_version=) + client.protocol_version = options["protocol_version"] + options.add_hook("protocol_version") do |key, value| + client.protocol_version = value + end + end + ssl_config = options["ssl_config"] ||= ::SOAP::Property.new + set_ssl_config(client, ssl_config) + ssl_config.add_hook(true) do |key, value| + set_ssl_config(client, ssl_config) + end + basic_auth = options["basic_auth"] ||= ::SOAP::Property.new + set_basic_auth(client, basic_auth) + basic_auth.add_hook do |key, value| + set_basic_auth(client, basic_auth) + end + options.add_hook("connect_timeout") do |key, value| + client.connect_timeout = value + end + options.add_hook("send_timeout") do |key, value| + client.send_timeout = value + end + options.add_hook("receive_timeout") do |key, value| + client.receive_timeout = value + end + end + + def set_basic_auth(client, basic_auth) + basic_auth.values.each do |url, userid, passwd| + client.set_basic_auth(url, userid, passwd) + end + end + + def set_ssl_config(client, ssl_config) + ssl_config.each do |key, value| + cfg = client.ssl_config + if cfg.nil? + raise NotImplementedError.new("SSL not supported") + end + case key + when 'client_cert' + cfg.client_cert = cert_from_file(value) + when 'client_key' + cfg.client_key = key_from_file(value) + when 'client_ca' + cfg.client_ca = value + when 'ca_path' + cfg.set_trust_ca(value) + when 'ca_file' + cfg.set_trust_ca(value) + when 'crl' + cfg.set_crl(value) + when 'verify_mode' + cfg.verify_mode = ssl_config_int(value) + when 'verify_depth' + cfg.verify_depth = ssl_config_int(value) + when 'options' + cfg.options = value + when 'ciphers' + cfg.ciphers = value + when 'verify_callback' + cfg.verify_callback = value + when 'cert_store' + cfg.cert_store = value + else + raise ArgumentError.new("unknown ssl_config property #{key}") + end + end + end + + def ssl_config_int(value) + if value.nil? or value.to_s.empty? + nil + else + begin + Integer(value) + rescue ArgumentError + ::SOAP::Property::Util.const_from_name(value.to_s) + end + end + end + + def cert_from_file(filename) + OpenSSL::X509::Certificate.new(File.open(filename) { |f| f.read }) + end + + def key_from_file(filename) + OpenSSL::PKey::RSA.new(File.open(filename) { |f| f.read }) + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping.rb new file mode 100644 index 00000000..b83f8b48 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping.rb @@ -0,0 +1,10 @@ +# SOAP4R - Ruby type mapping utility. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/mapping/mapping' +require 'soap/mapping/registry' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/factory.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/factory.rb new file mode 100644 index 00000000..978b303b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/factory.rb @@ -0,0 +1,355 @@ +# SOAP4R - Mapping factory. +# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module SOAP +module Mapping + + +class Factory + include TraverseSupport + + def initialize + # nothing to do + end + + def obj2soap(soap_class, obj, info, map) + raise NotImplementError.new + # return soap_obj + end + + def soap2obj(obj_class, node, info, map) + raise NotImplementError.new + # return convert_succeeded_or_not, obj + end + + def setiv2obj(obj, node, map) + return if node.nil? + if obj.is_a?(Array) + setiv2ary(obj, node, map) + else + setiv2struct(obj, node, map) + end + end + + def setiv2soap(node, obj, map) + if obj.class.class_variables.include?('@@schema_element') + obj.class.class_eval('@@schema_element').each do |name, info| + type, qname = info + if qname + elename = qname.name + else + elename = Mapping.name2elename(name) + end + node.add(elename, + Mapping._obj2soap(obj.instance_variable_get('@' + name), map)) + end + else + # should we sort instance_variables? + obj.instance_variables.each do |var| + name = var.sub(/^@/, '') + elename = Mapping.name2elename(name) + node.add(elename, + Mapping._obj2soap(obj.instance_variable_get(var), map)) + end + end + end + +private + + def setiv2ary(obj, node, map) + node.each do |name, value| + Array.instance_method(:<<).bind(obj).call(Mapping._soap2obj(value, map)) + end + end + + def setiv2struct(obj, node, map) + vars = {} + node.each do |name, value| + vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map) + end + Mapping.set_attributes(obj, vars) + end +end + +class StringFactory_ < Factory + def initialize(allow_original_mapping = false) + super() + @allow_original_mapping = allow_original_mapping + end + + def obj2soap(soap_class, obj, info, map) + if !@allow_original_mapping and !obj.instance_variables.empty? + return nil + end + begin + unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES]) + return nil + end + encoded = XSD::Charset.encoding_conv(obj, + Thread.current[:SOAPExternalCES], XSD::Charset.encoding) + soap_obj = soap_class.new(encoded) + rescue XSD::ValueSpaceError + return nil + end + mark_marshalled_obj(obj, soap_obj) + soap_obj + end + + def soap2obj(obj_class, node, info, map) + obj = Mapping.create_empty_object(obj_class) + decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, + Thread.current[:SOAPExternalCES]) + obj.replace(decoded) + mark_unmarshalled_obj(node, obj) + return true, obj + end +end + +class BasetypeFactory_ < Factory + def initialize(allow_original_mapping = false) + super() + @allow_original_mapping = allow_original_mapping + end + + def obj2soap(soap_class, obj, info, map) + if !@allow_original_mapping and !obj.instance_variables.empty? + return nil + end + soap_obj = nil + begin + soap_obj = soap_class.new(obj) + rescue XSD::ValueSpaceError + return nil + end + if @allow_original_mapping + # Basetype except String should not be multiref-ed in SOAP/1.1. + mark_marshalled_obj(obj, soap_obj) + end + soap_obj + end + + def soap2obj(obj_class, node, info, map) + obj = node.data + mark_unmarshalled_obj(node, obj) + return true, obj + end +end + +class DateTimeFactory_ < Factory + def initialize(allow_original_mapping = false) + super() + @allow_original_mapping = allow_original_mapping + end + + def obj2soap(soap_class, obj, info, map) + if !@allow_original_mapping and + Time === obj and !obj.instance_variables.empty? + return nil + end + soap_obj = nil + begin + soap_obj = soap_class.new(obj) + rescue XSD::ValueSpaceError + return nil + end + mark_marshalled_obj(obj, soap_obj) + soap_obj + end + + def soap2obj(obj_class, node, info, map) + if node.respond_to?(:to_obj) + obj = node.to_obj(obj_class) + return false if obj.nil? + mark_unmarshalled_obj(node, obj) + return true, obj + else + return false + end + end +end + +class Base64Factory_ < Factory + def obj2soap(soap_class, obj, info, map) + return nil unless obj.instance_variables.empty? + soap_obj = soap_class.new(obj) + mark_marshalled_obj(obj, soap_obj) if soap_obj + soap_obj + end + + def soap2obj(obj_class, node, info, map) + obj = node.string + mark_unmarshalled_obj(node, obj) + return true, obj + end +end + +class URIFactory_ < Factory + def obj2soap(soap_class, obj, info, map) + soap_obj = soap_class.new(obj) + mark_marshalled_obj(obj, soap_obj) if soap_obj + soap_obj + end + + def soap2obj(obj_class, node, info, map) + obj = node.data + mark_unmarshalled_obj(node, obj) + return true, obj + end +end + +class ArrayFactory_ < Factory + def initialize(allow_original_mapping = false) + super() + @allow_original_mapping = allow_original_mapping + end + + # [[1], [2]] is converted to Array of Array, not 2-D Array. + # To create M-D Array, you must call Mapping.ary2md. + def obj2soap(soap_class, obj, info, map) + if !@allow_original_mapping and !obj.instance_variables.empty? + return nil + end + arytype = Mapping.obj2element(obj) + if arytype.name + arytype.namespace ||= RubyTypeNamespace + else + arytype = XSD::AnyTypeName + end + soap_obj = SOAPArray.new(ValueArrayName, 1, arytype) + mark_marshalled_obj(obj, soap_obj) + obj.each do |item| + soap_obj.add(Mapping._obj2soap(item, map)) + end + soap_obj + end + + def soap2obj(obj_class, node, info, map) + obj = Mapping.create_empty_object(obj_class) + mark_unmarshalled_obj(node, obj) + node.soap2array(obj) do |elem| + elem ? Mapping._soap2obj(elem, map) : nil + end + return true, obj + end +end + +class TypedArrayFactory_ < Factory + def initialize(allow_original_mapping = false) + super() + @allow_original_mapping = allow_original_mapping + end + + def obj2soap(soap_class, obj, info, map) + if !@allow_original_mapping and !obj.instance_variables.empty? + return nil + end + arytype = info[:type] || info[0] + soap_obj = SOAPArray.new(ValueArrayName, 1, arytype) + mark_marshalled_obj(obj, soap_obj) + obj.each do |var| + soap_obj.add(Mapping._obj2soap(var, map)) + end + soap_obj + end + + def soap2obj(obj_class, node, info, map) + if node.rank > 1 + return false + end + arytype = info[:type] || info[0] + unless node.arytype == arytype + return false + end + obj = Mapping.create_empty_object(obj_class) + mark_unmarshalled_obj(node, obj) + node.soap2array(obj) do |elem| + elem ? Mapping._soap2obj(elem, map) : nil + end + return true, obj + end +end + +class TypedStructFactory_ < Factory + def obj2soap(soap_class, obj, info, map) + type = info[:type] || info[0] + soap_obj = soap_class.new(type) + mark_marshalled_obj(obj, soap_obj) + if obj.class <= SOAP::Marshallable + setiv2soap(soap_obj, obj, map) + else + setiv2soap(soap_obj, obj, map) + end + soap_obj + end + + def soap2obj(obj_class, node, info, map) + type = info[:type] || info[0] + unless node.type == type + return false + end + obj = Mapping.create_empty_object(obj_class) + mark_unmarshalled_obj(node, obj) + setiv2obj(obj, node, map) + return true, obj + end +end + +MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map') +class HashFactory_ < Factory + def initialize(allow_original_mapping = false) + super() + @allow_original_mapping = allow_original_mapping + end + + def obj2soap(soap_class, obj, info, map) + if !@allow_original_mapping and !obj.instance_variables.empty? + return nil + end + if !obj.default.nil? or + (obj.respond_to?(:default_proc) and obj.default_proc) + return nil + end + soap_obj = SOAPStruct.new(MapQName) + mark_marshalled_obj(obj, soap_obj) + obj.each do |key, value| + elem = SOAPStruct.new + elem.add("key", Mapping._obj2soap(key, map)) + elem.add("value", Mapping._obj2soap(value, map)) + # ApacheAxis allows only 'item' here. + soap_obj.add("item", elem) + end + soap_obj + end + + def soap2obj(obj_class, node, info, map) + unless node.type == MapQName + return false + end + if node.class == SOAPStruct and node.key?('default') + return false + end + obj = Mapping.create_empty_object(obj_class) + mark_unmarshalled_obj(node, obj) + if node.class == SOAPStruct + node.each do |key, value| + obj[Mapping._soap2obj(value['key'], map)] = + Mapping._soap2obj(value['value'], map) + end + else + node.each do |value| + obj[Mapping._soap2obj(value['key'], map)] = + Mapping._soap2obj(value['value'], map) + end + end + return true, obj + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/mapping.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/mapping.rb new file mode 100644 index 00000000..65d6bb4d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/mapping.rb @@ -0,0 +1,381 @@ +# SOAP4R - Ruby type mapping utility. +# Copyright (C) 2000, 2001, 2003-2005 NAKAMURA Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' + + +module SOAP + + +module Mapping + RubyTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/1.6' + RubyTypeInstanceNamespace = + 'http://www.ruby-lang.org/xmlns/ruby/type-instance' + RubyCustomTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/custom' + ApacheSOAPTypeNamespace = 'http://xml.apache.org/xml-soap' + + + # TraverseSupport breaks following thread variables. + # Thread.current[:SOAPMarshalDataKey] + module TraverseSupport + def mark_marshalled_obj(obj, soap_obj) + raise if obj.nil? + Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj + end + + def mark_unmarshalled_obj(node, obj) + return if obj.nil? + # node.id is not Object#id but SOAPReference#id + Thread.current[:SOAPMarshalDataKey][node.id] = obj + end + end + + + EMPTY_OPT = {} + def self.obj2soap(obj, registry = nil, type = nil, opt = EMPTY_OPT) + registry ||= Mapping::DefaultRegistry + soap_obj = nil + protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do + Thread.current[:SOAPMarshalDataKey] = {} + Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE + Thread.current[:SOAPMarshalNoReference] = opt[:no_reference] + soap_obj = _obj2soap(obj, registry, type) + end + soap_obj + end + + def self.soap2obj(node, registry = nil, klass = nil, opt = EMPTY_OPT) + registry ||= Mapping::DefaultRegistry + obj = nil + protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do + Thread.current[:SOAPMarshalDataKey] = {} + Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE + Thread.current[:SOAPMarshalNoReference] = opt[:no_reference] + obj = _soap2obj(node, registry, klass) + end + obj + end + + def self.ary2soap(ary, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT) + registry ||= Mapping::DefaultRegistry + type = XSD::QName.new(type_ns, typename) + soap_ary = SOAPArray.new(ValueArrayName, 1, type) + protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do + Thread.current[:SOAPMarshalDataKey] = {} + Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE + Thread.current[:SOAPMarshalNoReference] = opt[:no_reference] + ary.each do |ele| + soap_ary.add(_obj2soap(ele, registry, type)) + end + end + soap_ary + end + + def self.ary2md(ary, rank, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT) + registry ||= Mapping::DefaultRegistry + type = XSD::QName.new(type_ns, typename) + md_ary = SOAPArray.new(ValueArrayName, rank, type) + protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do + Thread.current[:SOAPMarshalDataKey] = {} + Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE + Thread.current[:SOAPMarshalNoReference] = opt[:no_reference] + add_md_ary(md_ary, ary, [], registry) + end + md_ary + end + + def self.fault2exception(fault, registry = nil) + registry ||= Mapping::DefaultRegistry + detail = if fault.detail + soap2obj(fault.detail, registry) || "" + else + "" + end + if detail.is_a?(Mapping::SOAPException) + begin + e = detail.to_e + remote_backtrace = e.backtrace + e.set_backtrace(nil) + raise e # ruby sets current caller as local backtrace of e => e2. + rescue Exception => e + e.set_backtrace(remote_backtrace + e.backtrace[1..-1]) + raise + end + else + fault.detail = detail + fault.set_backtrace( + if detail.is_a?(Array) + detail + else + [detail.to_s] + end + ) + raise + end + end + + def self._obj2soap(obj, registry, type = nil) + if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] and + !Thread.current[:SOAPMarshalNoReference] + SOAPReference.new(referent) + elsif registry + registry.obj2soap(obj, type) + else + raise MappingError.new("no mapping registry given") + end + end + + def self._soap2obj(node, registry, klass = nil) + if node.nil? + return nil + elsif node.is_a?(SOAPReference) + target = node.__getobj__ + # target.id is not Object#id but SOAPReference#id + if referent = Thread.current[:SOAPMarshalDataKey][target.id] and + !Thread.current[:SOAPMarshalNoReference] + return referent + else + return _soap2obj(target, registry, klass) + end + end + return registry.soap2obj(node, klass) + end + + if Object.respond_to?(:allocate) + # ruby/1.7 or later. + def self.create_empty_object(klass) + klass.allocate + end + else + MARSHAL_TAG = { + String => ['"', 1], + Regexp => ['/', 2], + Array => ['[', 1], + Hash => ['{', 1] + } + def self.create_empty_object(klass) + if klass <= Struct + name = klass.name + return ::Marshal.load(sprintf("\004\006S:%c%s\000", name.length + 5, name)) + end + if MARSHAL_TAG.has_key?(klass) + tag, terminate = MARSHAL_TAG[klass] + return ::Marshal.load(sprintf("\004\006%s%s", tag, "\000" * terminate)) + end + MARSHAL_TAG.each do |k, v| + if klass < k + name = klass.name + tag, terminate = v + return ::Marshal.load(sprintf("\004\006C:%c%s%s%s", name.length + 5, name, tag, "\000" * terminate)) + end + end + name = klass.name + ::Marshal.load(sprintf("\004\006o:%c%s\000", name.length + 5, name)) + end + end + + # Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here. + # Caution: '.' is not allowed here. + # To follow XML spec., it should be NCName. + # (denied chars) => .[0-F][0-F] + # ex. a.b => a.2eb + # + def self.name2elename(name) + name.gsub(/([^a-zA-Z0-9:_\-]+)/n) { + '.' << $1.unpack('H2' * $1.size).join('.') + }.gsub(/::/n, '..') + end + + def self.elename2name(name) + name.gsub(/\.\./n, '::').gsub(/((?:\.[0-9a-fA-F]{2})+)/n) { + [$1.delete('.')].pack('H*') + } + end + + def self.const_from_name(name, lenient = false) + const = ::Object + name.sub(/\A::/, '').split('::').each do |const_str| + if XSD::CodeGen::GenSupport.safeconstname?(const_str) + if const.const_defined?(const_str) + const = const.const_get(const_str) + next + end + elsif lenient + const_str = XSD::CodeGen::GenSupport.safeconstname(const_str) + if const.const_defined?(const_str) + const = const.const_get(const_str) + next + end + end + return nil + end + const + end + + def self.class_from_name(name, lenient = false) + const = const_from_name(name, lenient) + if const.is_a?(::Class) + const + else + nil + end + end + + def self.module_from_name(name, lenient = false) + const = const_from_name(name, lenient) + if const.is_a?(::Module) + const + else + nil + end + end + + def self.class2qname(klass) + name = schema_type_definition(klass) + namespace = schema_ns_definition(klass) + XSD::QName.new(namespace, name) + end + + def self.class2element(klass) + type = Mapping.class2qname(klass) + type.name ||= Mapping.name2elename(klass.name) + type.namespace ||= RubyCustomTypeNamespace + type + end + + def self.obj2element(obj) + name = namespace = nil + ivars = obj.instance_variables + if ivars.include?('@schema_type') + name = obj.instance_variable_get('@schema_type') + end + if ivars.include?('@schema_ns') + namespace = obj.instance_variable_get('@schema_ns') + end + if !name or !namespace + class2qname(obj.class) + else + XSD::QName.new(namespace, name) + end + end + + def self.define_singleton_method(obj, name, &block) + sclass = (class << obj; self; end) + sclass.class_eval { + define_method(name, &block) + } + end + + def self.get_attribute(obj, attr_name) + if obj.is_a?(::Hash) + obj[attr_name] || obj[attr_name.intern] + else + name = XSD::CodeGen::GenSupport.safevarname(attr_name) + if obj.instance_variables.include?('@' + name) + obj.instance_variable_get('@' + name) + elsif ((obj.is_a?(::Struct) or obj.is_a?(Marshallable)) and + obj.respond_to?(name)) + obj.__send__(name) + end + end + end + + def self.set_attributes(obj, values) + if obj.is_a?(::SOAP::Mapping::Object) + values.each do |attr_name, value| + obj.__add_xmlele_value(attr_name, value) + end + else + values.each do |attr_name, value| + name = XSD::CodeGen::GenSupport.safevarname(attr_name) + setter = name + "=" + if obj.respond_to?(setter) + obj.__send__(setter, value) + else + obj.instance_variable_set('@' + name, value) + begin + define_attr_accessor(obj, name, + proc { instance_variable_get('@' + name) }, + proc { |value| instance_variable_set('@' + name, value) }) + rescue TypeError + # singleton class may not exist (e.g. Float) + end + end + end + end + end + + def self.define_attr_accessor(obj, name, getterproc, setterproc = nil) + define_singleton_method(obj, name, &getterproc) + define_singleton_method(obj, name + '=', &setterproc) if setterproc + end + + def self.schema_type_definition(klass) + class_schema_variable(:schema_type, klass) + end + + def self.schema_ns_definition(klass) + class_schema_variable(:schema_ns, klass) + end + + def self.schema_element_definition(klass) + schema_element = class_schema_variable(:schema_element, klass) or return nil + schema_ns = schema_ns_definition(klass) + elements = [] + as_array = [] + schema_element.each do |varname, definition| + class_name, name = definition + if /\[\]$/ =~ class_name + class_name = class_name.sub(/\[\]$/, '') + as_array << (name ? name.name : varname) + end + elements << [name || XSD::QName.new(schema_ns, varname), class_name] + end + [elements, as_array] + end + + def self.schema_attribute_definition(klass) + class_schema_variable(:schema_attribute, klass) + end + + class << Mapping + private + + def class_schema_variable(sym, klass) + var = "@@#{sym}" + klass.class_variables.include?(var) ? klass.class_eval(var) : nil + end + + def protect_threadvars(*symbols) + backup = {} + begin + symbols.each do |sym| + backup[sym] = Thread.current[sym] + end + yield + ensure + symbols.each do |sym| + Thread.current[sym] = backup[sym] + end + end + end + + def add_md_ary(md_ary, ary, indices, registry) + for idx in 0..(ary.size - 1) + if ary[idx].is_a?(Array) + add_md_ary(md_ary, ary[idx], indices + [idx], registry) + else + md_ary[*(indices + [idx])] = _obj2soap(ary[idx], registry) + end + end + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/registry.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/registry.rb new file mode 100644 index 00000000..823e8066 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/registry.rb @@ -0,0 +1,541 @@ +# SOAP4R - Mapping registry. +# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/baseData' +require 'soap/mapping/mapping' +require 'soap/mapping/typeMap' +require 'soap/mapping/factory' +require 'soap/mapping/rubytypeFactory' + + +module SOAP + + +module Marshallable + # @@type_ns = Mapping::RubyCustomTypeNamespace +end + + +module Mapping + + +module MappedException; end + + +RubyTypeName = XSD::QName.new(RubyTypeInstanceNamespace, 'rubyType') +RubyExtendName = XSD::QName.new(RubyTypeInstanceNamespace, 'extends') +RubyIVarName = XSD::QName.new(RubyTypeInstanceNamespace, 'ivars') + + +# Inner class to pass an exception. +class SOAPException; include Marshallable + attr_reader :excn_type_name, :cause + def initialize(e) + @excn_type_name = Mapping.name2elename(e.class.to_s) + @cause = e + end + + def to_e + if @cause.is_a?(::Exception) + @cause.extend(::SOAP::Mapping::MappedException) + return @cause + elsif @cause.respond_to?(:message) and @cause.respond_to?(:backtrace) + e = RuntimeError.new(@cause.message) + e.set_backtrace(@cause.backtrace) + return e + end + klass = Mapping.class_from_name(Mapping.elename2name(@excn_type_name.to_s)) + if klass.nil? or not klass <= ::Exception + return RuntimeError.new(@cause.inspect) + end + obj = klass.new(@cause.message) + obj.extend(::SOAP::Mapping::MappedException) + obj + end +end + + +# For anyType object: SOAP::Mapping::Object not ::Object +class Object; include Marshallable + def initialize + @__xmlele_type = {} + @__xmlele = [] + @__xmlattr = {} + end + + def inspect + sprintf("#<%s:0x%x%s>", self.class.name, __id__, + @__xmlele.collect { |name, value| " #{name}=#{value.inspect}" }.join) + end + + def __xmlattr + @__xmlattr + end + + def __xmlele + @__xmlele + end + + def [](qname) + unless qname.is_a?(XSD::QName) + qname = XSD::QName.new(nil, qname) + end + @__xmlele.each do |k, v| + return v if k == qname + end + # fallback + @__xmlele.each do |k, v| + return v if k.name == qname.name + end + nil + end + + def []=(qname, value) + unless qname.is_a?(XSD::QName) + qname = XSD::QName.new(nil, qname) + end + found = false + @__xmlele.each do |pair| + if pair[0] == qname + found = true + pair[1] = value + end + end + unless found + __define_attr_accessor(qname) + @__xmlele << [qname, value] + end + @__xmlele_type[qname] = :single + end + + def __add_xmlele_value(qname, value) + found = false + @__xmlele.map! do |k, v| + if k == qname + found = true + [k, __set_xmlele_value(k, v, value)] + else + [k, v] + end + end + unless found + __define_attr_accessor(qname) + @__xmlele << [qname, value] + @__xmlele_type[qname] = :single + end + value + end + +private + + if RUBY_VERSION > "1.7.0" + def __define_attr_accessor(qname) + name = XSD::CodeGen::GenSupport.safemethodname(qname.name) + Mapping.define_attr_accessor(self, name, + proc { self[qname] }, + proc { |value| self[qname] = value }) + end + else + def __define_attr_accessor(qname) + name = XSD::CodeGen::GenSupport.safemethodname(qname.name) + instance_eval <<-EOS + def #{name} + self[#{qname.dump}] + end + + def #{name}=(value) + self[#{qname.dump}] = value + end + EOS + end + end + + def __set_xmlele_value(key, org, value) + case @__xmlele_type[key] + when :multi + org << value + org + when :single + @__xmlele_type[key] = :multi + [org, value] + else + raise RuntimeError.new("unknown type") + end + end +end + + +class MappingError < Error; end + + +class Registry + class Map + def initialize(registry) + @obj2soap = {} + @soap2obj = {} + @registry = registry + end + + def obj2soap(obj) + klass = obj.class + if map = @obj2soap[klass] + map.each do |soap_class, factory, info| + ret = factory.obj2soap(soap_class, obj, info, @registry) + return ret if ret + end + end + ancestors = klass.ancestors + ancestors.delete(klass) + ancestors.delete(::Object) + ancestors.delete(::Kernel) + ancestors.each do |klass| + if map = @obj2soap[klass] + map.each do |soap_class, factory, info| + if info[:derived_class] + ret = factory.obj2soap(soap_class, obj, info, @registry) + return ret if ret + end + end + end + end + nil + end + + def soap2obj(node, klass = nil) + if map = @soap2obj[node.class] + map.each do |obj_class, factory, info| + next if klass and obj_class != klass + conv, obj = factory.soap2obj(obj_class, node, info, @registry) + return true, obj if conv + end + end + return false, nil + end + + # Give priority to former entry. + def init(init_map = []) + clear + init_map.reverse_each do |obj_class, soap_class, factory, info| + add(obj_class, soap_class, factory, info) + end + end + + # Give priority to latter entry. + def add(obj_class, soap_class, factory, info) + info ||= {} + (@obj2soap[obj_class] ||= []).unshift([soap_class, factory, info]) + (@soap2obj[soap_class] ||= []).unshift([obj_class, factory, info]) + end + + def clear + @obj2soap.clear + @soap2obj.clear + end + + def find_mapped_soap_class(target_obj_class) + map = @obj2soap[target_obj_class] + map.empty? ? nil : map[0][1] + end + + def find_mapped_obj_class(target_soap_class) + map = @soap2obj[target_soap_class] + map.empty? ? nil : map[0][0] + end + end + + StringFactory = StringFactory_.new + BasetypeFactory = BasetypeFactory_.new + DateTimeFactory = DateTimeFactory_.new + ArrayFactory = ArrayFactory_.new + Base64Factory = Base64Factory_.new + URIFactory = URIFactory_.new + TypedArrayFactory = TypedArrayFactory_.new + TypedStructFactory = TypedStructFactory_.new + + HashFactory = HashFactory_.new + + SOAPBaseMap = [ + [::NilClass, ::SOAP::SOAPNil, BasetypeFactory], + [::TrueClass, ::SOAP::SOAPBoolean, BasetypeFactory], + [::FalseClass, ::SOAP::SOAPBoolean, BasetypeFactory], + [::String, ::SOAP::SOAPString, StringFactory], + [::DateTime, ::SOAP::SOAPDateTime, DateTimeFactory], + [::Date, ::SOAP::SOAPDate, DateTimeFactory], + [::Time, ::SOAP::SOAPDateTime, DateTimeFactory], + [::Time, ::SOAP::SOAPTime, DateTimeFactory], + [::Float, ::SOAP::SOAPDouble, BasetypeFactory, + {:derived_class => true}], + [::Float, ::SOAP::SOAPFloat, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPInt, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPLong, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPShort, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPByte, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPNonPositiveInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPNegativeInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPNonNegativeInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPPositiveInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedLong, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedInt, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedShort, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedByte, BasetypeFactory, + {:derived_class => true}], + [::URI::Generic, ::SOAP::SOAPAnyURI, URIFactory, + {:derived_class => true}], + [::String, ::SOAP::SOAPBase64, Base64Factory], + [::String, ::SOAP::SOAPHexBinary, Base64Factory], + [::String, ::SOAP::SOAPDecimal, BasetypeFactory], + [::String, ::SOAP::SOAPDuration, BasetypeFactory], + [::String, ::SOAP::SOAPGYearMonth, BasetypeFactory], + [::String, ::SOAP::SOAPGYear, BasetypeFactory], + [::String, ::SOAP::SOAPGMonthDay, BasetypeFactory], + [::String, ::SOAP::SOAPGDay, BasetypeFactory], + [::String, ::SOAP::SOAPGMonth, BasetypeFactory], + [::String, ::SOAP::SOAPQName, BasetypeFactory], + + [::Hash, ::SOAP::SOAPArray, HashFactory], + [::Hash, ::SOAP::SOAPStruct, HashFactory], + + [::Array, ::SOAP::SOAPArray, ArrayFactory, + {:derived_class => true}], + + [::SOAP::Mapping::SOAPException, + ::SOAP::SOAPStruct, TypedStructFactory, + {:type => XSD::QName.new(RubyCustomTypeNamespace, "SOAPException")}], + ] + + RubyOriginalMap = [ + [::NilClass, ::SOAP::SOAPNil, BasetypeFactory], + [::TrueClass, ::SOAP::SOAPBoolean, BasetypeFactory], + [::FalseClass, ::SOAP::SOAPBoolean, BasetypeFactory], + [::String, ::SOAP::SOAPString, StringFactory], + [::DateTime, ::SOAP::SOAPDateTime, DateTimeFactory], + [::Date, ::SOAP::SOAPDate, DateTimeFactory], + [::Time, ::SOAP::SOAPDateTime, DateTimeFactory], + [::Time, ::SOAP::SOAPTime, DateTimeFactory], + [::Float, ::SOAP::SOAPDouble, BasetypeFactory, + {:derived_class => true}], + [::Float, ::SOAP::SOAPFloat, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPInt, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPLong, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPShort, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPByte, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPNonPositiveInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPNegativeInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPNonNegativeInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPPositiveInteger, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedLong, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedInt, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedShort, BasetypeFactory, + {:derived_class => true}], + [::Integer, ::SOAP::SOAPUnsignedByte, BasetypeFactory, + {:derived_class => true}], + [::URI::Generic, ::SOAP::SOAPAnyURI, URIFactory, + {:derived_class => true}], + [::String, ::SOAP::SOAPBase64, Base64Factory], + [::String, ::SOAP::SOAPHexBinary, Base64Factory], + [::String, ::SOAP::SOAPDecimal, BasetypeFactory], + [::String, ::SOAP::SOAPDuration, BasetypeFactory], + [::String, ::SOAP::SOAPGYearMonth, BasetypeFactory], + [::String, ::SOAP::SOAPGYear, BasetypeFactory], + [::String, ::SOAP::SOAPGMonthDay, BasetypeFactory], + [::String, ::SOAP::SOAPGDay, BasetypeFactory], + [::String, ::SOAP::SOAPGMonth, BasetypeFactory], + [::String, ::SOAP::SOAPQName, BasetypeFactory], + + [::Hash, ::SOAP::SOAPArray, HashFactory], + [::Hash, ::SOAP::SOAPStruct, HashFactory], + + # Does not allow Array's subclass here. + [::Array, ::SOAP::SOAPArray, ArrayFactory], + + [::SOAP::Mapping::SOAPException, + ::SOAP::SOAPStruct, TypedStructFactory, + {:type => XSD::QName.new(RubyCustomTypeNamespace, "SOAPException")}], + ] + + attr_accessor :default_factory + attr_accessor :excn_handler_obj2soap + attr_accessor :excn_handler_soap2obj + + def initialize(config = {}) + @config = config + @map = Map.new(self) + if @config[:allow_original_mapping] + @allow_original_mapping = true + @map.init(RubyOriginalMap) + else + @allow_original_mapping = false + @map.init(SOAPBaseMap) + end + @allow_untyped_struct = @config.key?(:allow_untyped_struct) ? + @config[:allow_untyped_struct] : true + @rubytype_factory = RubytypeFactory.new( + :allow_untyped_struct => @allow_untyped_struct, + :allow_original_mapping => @allow_original_mapping + ) + @default_factory = @rubytype_factory + @excn_handler_obj2soap = nil + @excn_handler_soap2obj = nil + end + + def add(obj_class, soap_class, factory, info = nil) + @map.add(obj_class, soap_class, factory, info) + end + alias set add + + # general Registry ignores type_qname + def obj2soap(obj, type_qname = nil) + soap = _obj2soap(obj) + if @allow_original_mapping + addextend2soap(soap, obj) + end + soap + end + + def soap2obj(node, klass = nil) + obj = _soap2obj(node, klass) + if @allow_original_mapping + addextend2obj(obj, node.extraattr[RubyExtendName]) + addiv2obj(obj, node.extraattr[RubyIVarName]) + end + obj + end + + def find_mapped_soap_class(obj_class) + @map.find_mapped_soap_class(obj_class) + end + + def find_mapped_obj_class(soap_class) + @map.find_mapped_obj_class(soap_class) + end + +private + + def _obj2soap(obj) + ret = nil + if obj.is_a?(SOAPStruct) or obj.is_a?(SOAPArray) + obj.replace do |ele| + Mapping._obj2soap(ele, self) + end + return obj + elsif obj.is_a?(SOAPBasetype) + return obj + end + begin + ret = @map.obj2soap(obj) || + @default_factory.obj2soap(nil, obj, nil, self) + return ret if ret + rescue MappingError + end + if @excn_handler_obj2soap + ret = @excn_handler_obj2soap.call(obj) { |yield_obj| + Mapping._obj2soap(yield_obj, self) + } + return ret if ret + end + raise MappingError.new("Cannot map #{ obj.class.name } to SOAP/OM.") + end + + # Might return nil as a mapping result. + def _soap2obj(node, klass = nil) + if node.extraattr.key?(RubyTypeName) + conv, obj = @rubytype_factory.soap2obj(nil, node, nil, self) + return obj if conv + else + conv, obj = @map.soap2obj(node, klass) + return obj if conv + conv, obj = @default_factory.soap2obj(nil, node, nil, self) + return obj if conv + end + if @excn_handler_soap2obj + begin + return @excn_handler_soap2obj.call(node) { |yield_node| + Mapping._soap2obj(yield_node, self) + } + rescue Exception + end + end + raise MappingError.new("Cannot map #{ node.type.name } to Ruby object.") + end + + def addiv2obj(obj, attr) + return unless attr + vars = {} + attr.__getobj__.each do |name, value| + vars[name] = Mapping._soap2obj(value, self) + end + Mapping.set_attributes(obj, vars) + end + + if RUBY_VERSION >= '1.8.0' + def addextend2obj(obj, attr) + return unless attr + attr.split(/ /).reverse_each do |mstr| + obj.extend(Mapping.module_from_name(mstr)) + end + end + else + # (class < false; self; end).ancestors includes "TrueClass" under 1.6... + def addextend2obj(obj, attr) + return unless attr + attr.split(/ /).reverse_each do |mstr| + m = Mapping.module_from_name(mstr) + obj.extend(m) + end + end + end + + def addextend2soap(node, obj) + return if obj.is_a?(Symbol) or obj.is_a?(Fixnum) + list = (class << obj; self; end).ancestors - obj.class.ancestors + unless list.empty? + node.extraattr[RubyExtendName] = list.collect { |c| + if c.name.empty? + raise TypeError.new("singleton can't be dumped #{ obj }") + end + c.name + }.join(" ") + end + end + +end + + +DefaultRegistry = Registry.new +RubyOriginalRegistry = Registry.new(:allow_original_mapping => true) + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/rubytypeFactory.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/rubytypeFactory.rb new file mode 100644 index 00000000..61c21d8b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/rubytypeFactory.rb @@ -0,0 +1,475 @@ +# SOAP4R - Ruby type mapping factory. +# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module SOAP +module Mapping + + +class RubytypeFactory < Factory + TYPE_STRING = XSD::QName.new(RubyTypeNamespace, 'String') + TYPE_TIME = XSD::QName.new(RubyTypeNamespace, 'Time') + TYPE_ARRAY = XSD::QName.new(RubyTypeNamespace, 'Array') + TYPE_REGEXP = XSD::QName.new(RubyTypeNamespace, 'Regexp') + TYPE_RANGE = XSD::QName.new(RubyTypeNamespace, 'Range') + TYPE_CLASS = XSD::QName.new(RubyTypeNamespace, 'Class') + TYPE_MODULE = XSD::QName.new(RubyTypeNamespace, 'Module') + TYPE_SYMBOL = XSD::QName.new(RubyTypeNamespace, 'Symbol') + TYPE_STRUCT = XSD::QName.new(RubyTypeNamespace, 'Struct') + TYPE_HASH = XSD::QName.new(RubyTypeNamespace, 'Map') + + def initialize(config = {}) + @config = config + @allow_untyped_struct = @config.key?(:allow_untyped_struct) ? + @config[:allow_untyped_struct] : true + @allow_original_mapping = @config.key?(:allow_original_mapping) ? + @config[:allow_original_mapping] : false + @string_factory = StringFactory_.new(true) + @basetype_factory = BasetypeFactory_.new(true) + @datetime_factory = DateTimeFactory_.new(true) + @array_factory = ArrayFactory_.new(true) + @hash_factory = HashFactory_.new(true) + end + + def obj2soap(soap_class, obj, info, map) + param = nil + case obj + when ::String + unless @allow_original_mapping + return nil + end + param = @string_factory.obj2soap(SOAPString, obj, info, map) + if obj.class != String + param.extraattr[RubyTypeName] = obj.class.name + end + addiv2soapattr(param, obj, map) + when ::Time + unless @allow_original_mapping + return nil + end + param = @datetime_factory.obj2soap(SOAPDateTime, obj, info, map) + if obj.class != Time + param.extraattr[RubyTypeName] = obj.class.name + end + addiv2soapattr(param, obj, map) + when ::Array + unless @allow_original_mapping + return nil + end + param = @array_factory.obj2soap(nil, obj, info, map) + if obj.class != Array + param.extraattr[RubyTypeName] = obj.class.name + end + addiv2soapattr(param, obj, map) + when ::NilClass + unless @allow_original_mapping + return nil + end + param = @basetype_factory.obj2soap(SOAPNil, obj, info, map) + addiv2soapattr(param, obj, map) + when ::FalseClass, ::TrueClass + unless @allow_original_mapping + return nil + end + param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map) + addiv2soapattr(param, obj, map) + when ::Integer + unless @allow_original_mapping + return nil + end + param = @basetype_factory.obj2soap(SOAPInt, obj, info, map) + param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map) + param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map) + addiv2soapattr(param, obj, map) + when ::Float + unless @allow_original_mapping + return nil + end + param = @basetype_factory.obj2soap(SOAPDouble, obj, info, map) + if obj.class != Float + param.extraattr[RubyTypeName] = obj.class.name + end + addiv2soapattr(param, obj, map) + when ::Hash + unless @allow_original_mapping + return nil + end + if obj.respond_to?(:default_proc) && obj.default_proc + raise TypeError.new("cannot dump hash with default proc") + end + param = SOAPStruct.new(TYPE_HASH) + mark_marshalled_obj(obj, param) + if obj.class != Hash + param.extraattr[RubyTypeName] = obj.class.name + end + obj.each do |key, value| + elem = SOAPStruct.new # Undefined type. + elem.add("key", Mapping._obj2soap(key, map)) + elem.add("value", Mapping._obj2soap(value, map)) + param.add("item", elem) + end + param.add('default', Mapping._obj2soap(obj.default, map)) + addiv2soapattr(param, obj, map) + when ::Regexp + unless @allow_original_mapping + return nil + end + param = SOAPStruct.new(TYPE_REGEXP) + mark_marshalled_obj(obj, param) + if obj.class != Regexp + param.extraattr[RubyTypeName] = obj.class.name + end + param.add('source', SOAPBase64.new(obj.source)) + if obj.respond_to?('options') + # Regexp#options is from Ruby/1.7 + options = obj.options + else + options = 0 + obj.inspect.sub(/^.*\//, '').each_byte do |c| + options += case c + when ?i + 1 + when ?x + 2 + when ?m + 4 + when ?n + 16 + when ?e + 32 + when ?s + 48 + when ?u + 64 + end + end + end + param.add('options', SOAPInt.new(options)) + addiv2soapattr(param, obj, map) + when ::Range + unless @allow_original_mapping + return nil + end + param = SOAPStruct.new(TYPE_RANGE) + mark_marshalled_obj(obj, param) + if obj.class != Range + param.extraattr[RubyTypeName] = obj.class.name + end + param.add('begin', Mapping._obj2soap(obj.begin, map)) + param.add('end', Mapping._obj2soap(obj.end, map)) + param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?)) + addiv2soapattr(param, obj, map) + when ::Class + unless @allow_original_mapping + return nil + end + if obj.to_s[0] == ?# + raise TypeError.new("can't dump anonymous class #{obj}") + end + param = SOAPStruct.new(TYPE_CLASS) + mark_marshalled_obj(obj, param) + param.add('name', SOAPString.new(obj.name)) + addiv2soapattr(param, obj, map) + when ::Module + unless @allow_original_mapping + return nil + end + if obj.to_s[0] == ?# + raise TypeError.new("can't dump anonymous module #{obj}") + end + param = SOAPStruct.new(TYPE_MODULE) + mark_marshalled_obj(obj, param) + param.add('name', SOAPString.new(obj.name)) + addiv2soapattr(param, obj, map) + when ::Symbol + unless @allow_original_mapping + return nil + end + param = SOAPStruct.new(TYPE_SYMBOL) + mark_marshalled_obj(obj, param) + param.add('id', SOAPString.new(obj.id2name)) + addiv2soapattr(param, obj, map) + when ::Struct + unless @allow_original_mapping + # treat it as an user defined class. [ruby-talk:104980] + #param = unknownobj2soap(soap_class, obj, info, map) + param = SOAPStruct.new(XSD::AnyTypeName) + mark_marshalled_obj(obj, param) + obj.members.each do |member| + param.add(Mapping.name2elename(member), + Mapping._obj2soap(obj[member], map)) + end + else + param = SOAPStruct.new(TYPE_STRUCT) + mark_marshalled_obj(obj, param) + param.add('type', ele_type = SOAPString.new(obj.class.to_s)) + ele_member = SOAPStruct.new + obj.members.each do |member| + ele_member.add(Mapping.name2elename(member), + Mapping._obj2soap(obj[member], map)) + end + param.add('member', ele_member) + addiv2soapattr(param, obj, map) + end + when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat, + ::MatchData, Method, ::Proc, ::Thread, ::ThreadGroup + # from 1.8: Process::Status, UnboundMethod + return nil + when ::SOAP::Mapping::Object + param = SOAPStruct.new(XSD::AnyTypeName) + mark_marshalled_obj(obj, param) + obj.__xmlele.each do |key, value| + param.add(key.name, Mapping._obj2soap(value, map)) + end + obj.__xmlattr.each do |key, value| + param.extraattr[key] = value + end + when ::Exception + typestr = Mapping.name2elename(obj.class.to_s) + param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr)) + mark_marshalled_obj(obj, param) + param.add('message', Mapping._obj2soap(obj.message, map)) + param.add('backtrace', Mapping._obj2soap(obj.backtrace, map)) + addiv2soapattr(param, obj, map) + else + param = unknownobj2soap(soap_class, obj, info, map) + end + param + end + + def soap2obj(obj_class, node, info, map) + rubytype = node.extraattr[RubyTypeName] + if rubytype or node.type.namespace == RubyTypeNamespace + rubytype2obj(node, info, map, rubytype) + elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName + anytype2obj(node, info, map) + else + unknowntype2obj(node, info, map) + end + end + +private + + def addiv2soapattr(node, obj, map) + return if obj.instance_variables.empty? + ivars = SOAPStruct.new # Undefined type. + setiv2soap(ivars, obj, map) + node.extraattr[RubyIVarName] = ivars + end + + def unknownobj2soap(soap_class, obj, info, map) + if obj.class.name.empty? + raise TypeError.new("can't dump anonymous class #{obj}") + end + singleton_class = class << obj; self; end + if !singleton_methods_true(obj).empty? or + !singleton_class.instance_variables.empty? + raise TypeError.new("singleton can't be dumped #{obj}") + end + if !(singleton_class.ancestors - obj.class.ancestors).empty? + typestr = Mapping.name2elename(obj.class.to_s) + type = XSD::QName.new(RubyTypeNamespace, typestr) + else + type = Mapping.class2element(obj.class) + end + param = SOAPStruct.new(type) + mark_marshalled_obj(obj, param) + setiv2soap(param, obj, map) + param + end + + if RUBY_VERSION >= '1.8.0' + def singleton_methods_true(obj) + obj.singleton_methods(true) + end + else + def singleton_methods_true(obj) + obj.singleton_methods + end + end + + def rubytype2obj(node, info, map, rubytype) + klass = rubytype ? Mapping.class_from_name(rubytype) : nil + obj = nil + case node + when SOAPString + return @string_factory.soap2obj(klass || String, node, info, map) + when SOAPDateTime + #return @datetime_factory.soap2obj(klass || Time, node, info, map) + klass ||= Time + t = node.to_time + arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec] + obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg) + mark_unmarshalled_obj(node, obj) + return true, obj + when SOAPArray + return @array_factory.soap2obj(klass || Array, node, info, map) + when SOAPNil, SOAPBoolean, SOAPInt, SOAPInteger, SOAPDecimal, SOAPDouble + return @basetype_factory.soap2obj(nil, node, info, map) + when SOAPStruct + return rubytypestruct2obj(node, info, map, rubytype) + else + raise + end + end + + def rubytypestruct2obj(node, info, map, rubytype) + klass = rubytype ? Mapping.class_from_name(rubytype) : nil + obj = nil + case node.type + when TYPE_HASH + klass = rubytype ? Mapping.class_from_name(rubytype) : Hash + obj = Mapping.create_empty_object(klass) + mark_unmarshalled_obj(node, obj) + node.each do |key, value| + next unless key == 'item' + obj[Mapping._soap2obj(value['key'], map)] = + Mapping._soap2obj(value['value'], map) + end + if node.key?('default') + obj.default = Mapping._soap2obj(node['default'], map) + end + when TYPE_REGEXP + klass = rubytype ? Mapping.class_from_name(rubytype) : Regexp + obj = Mapping.create_empty_object(klass) + mark_unmarshalled_obj(node, obj) + source = node['source'].string + options = node['options'].data || 0 + Regexp.instance_method(:initialize).bind(obj).call(source, options) + when TYPE_RANGE + klass = rubytype ? Mapping.class_from_name(rubytype) : Range + obj = Mapping.create_empty_object(klass) + mark_unmarshalled_obj(node, obj) + first = Mapping._soap2obj(node['begin'], map) + last = Mapping._soap2obj(node['end'], map) + exclude_end = node['exclude_end'].data + Range.instance_method(:initialize).bind(obj).call(first, last, exclude_end) + when TYPE_CLASS + obj = Mapping.class_from_name(node['name'].data) + when TYPE_MODULE + obj = Mapping.class_from_name(node['name'].data) + when TYPE_SYMBOL + obj = node['id'].data.intern + when TYPE_STRUCT + typestr = Mapping.elename2name(node['type'].data) + klass = Mapping.class_from_name(typestr) + if klass.nil? + return false + end + unless klass <= ::Struct + return false + end + obj = Mapping.create_empty_object(klass) + mark_unmarshalled_obj(node, obj) + node['member'].each do |name, value| + obj[Mapping.elename2name(name)] = Mapping._soap2obj(value, map) + end + else + return unknowntype2obj(node, info, map) + end + return true, obj + end + + def anytype2obj(node, info, map) + case node + when SOAPBasetype + return true, node.data + when SOAPStruct + klass = ::SOAP::Mapping::Object + obj = klass.new + mark_unmarshalled_obj(node, obj) + node.each do |name, value| + obj.__add_xmlele_value(XSD::QName.new(nil, name), + Mapping._soap2obj(value, map)) + end + unless node.extraattr.empty? + obj.instance_variable_set('@__xmlattr', node.extraattr) + end + return true, obj + else + return false + end + end + + def unknowntype2obj(node, info, map) + case node + when SOAPBasetype + return true, node.data + when SOAPArray + return @array_factory.soap2obj(Array, node, info, map) + when SOAPStruct + obj = unknownstruct2obj(node, info, map) + return true, obj if obj + if !@allow_untyped_struct + return false + end + return anytype2obj(node, info, map) + else + # Basetype which is not defined... + return false + end + end + + def unknownstruct2obj(node, info, map) + unless node.type.name + return nil + end + typestr = Mapping.elename2name(node.type.name) + klass = Mapping.class_from_name(typestr) + if klass.nil? and @allow_untyped_struct + klass = Mapping.class_from_name(typestr, true) # lenient + end + if klass.nil? + return nil + end + if klass <= ::Exception + return exception2obj(klass, node, map) + end + klass_type = Mapping.class2qname(klass) + return nil unless node.type.match(klass_type) + obj = nil + begin + obj = Mapping.create_empty_object(klass) + rescue + # type name "data" tries Data.new which raises TypeError + nil + end + mark_unmarshalled_obj(node, obj) + setiv2obj(obj, node, map) + obj + end + + def exception2obj(klass, node, map) + message = Mapping._soap2obj(node['message'], map) + backtrace = Mapping._soap2obj(node['backtrace'], map) + obj = Mapping.create_empty_object(klass) + obj = obj.exception(message) + mark_unmarshalled_obj(node, obj) + obj.set_backtrace(backtrace) + obj + end + + # Only creates empty array. Do String#replace it with real string. + def array2obj(node, map, rubytype) + klass = rubytype ? Mapping.class_from_name(rubytype) : Array + obj = Mapping.create_empty_object(klass) + mark_unmarshalled_obj(node, obj) + obj + end + + # Only creates empty string. Do String#replace it with real string. + def string2obj(node, map, rubytype) + klass = rubytype ? Mapping.class_from_name(rubytype) : String + obj = Mapping.create_empty_object(klass) + mark_unmarshalled_obj(node, obj) + obj + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/typeMap.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/typeMap.rb new file mode 100644 index 00000000..34db19a5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/typeMap.rb @@ -0,0 +1,50 @@ +# SOAP4R - Base type mapping definition +# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module SOAP + + +TypeMap = { + XSD::XSDAnySimpleType::Type => SOAPAnySimpleType, + XSD::XSDString::Type => SOAPString, + XSD::XSDBoolean::Type => SOAPBoolean, + XSD::XSDDecimal::Type => SOAPDecimal, + XSD::XSDFloat::Type => SOAPFloat, + XSD::XSDDouble::Type => SOAPDouble, + XSD::XSDDuration::Type => SOAPDuration, + XSD::XSDDateTime::Type => SOAPDateTime, + XSD::XSDTime::Type => SOAPTime, + XSD::XSDDate::Type => SOAPDate, + XSD::XSDGYearMonth::Type => SOAPGYearMonth, + XSD::XSDGYear::Type => SOAPGYear, + XSD::XSDGMonthDay::Type => SOAPGMonthDay, + XSD::XSDGDay::Type => SOAPGDay, + XSD::XSDGMonth::Type => SOAPGMonth, + XSD::XSDHexBinary::Type => SOAPHexBinary, + XSD::XSDBase64Binary::Type => SOAPBase64, + XSD::XSDAnyURI::Type => SOAPAnyURI, + XSD::XSDQName::Type => SOAPQName, + XSD::XSDInteger::Type => SOAPInteger, + XSD::XSDNonPositiveInteger::Type => SOAPNonPositiveInteger, + XSD::XSDNegativeInteger::Type => SOAPNegativeInteger, + XSD::XSDLong::Type => SOAPLong, + XSD::XSDInt::Type => SOAPInt, + XSD::XSDShort::Type => SOAPShort, + XSD::XSDByte::Type => SOAPByte, + XSD::XSDNonNegativeInteger::Type => SOAPNonNegativeInteger, + XSD::XSDUnsignedLong::Type => SOAPUnsignedLong, + XSD::XSDUnsignedInt::Type => SOAPUnsignedInt, + XSD::XSDUnsignedShort::Type => SOAPUnsignedShort, + XSD::XSDUnsignedByte::Type => SOAPUnsignedByte, + XSD::XSDPositiveInteger::Type => SOAPPositiveInteger, + + SOAP::SOAPBase64::Type => SOAPBase64, +} + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb new file mode 100644 index 00000000..4efb6018 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/wsdlencodedregistry.rb @@ -0,0 +1,280 @@ +# SOAP4R - WSDL encoded mapping registry. +# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'xsd/namedelements' +require 'soap/baseData' +require 'soap/mapping/mapping' +require 'soap/mapping/typeMap' + + +module SOAP +module Mapping + + +class WSDLEncodedRegistry < Registry + include TraverseSupport + + attr_reader :definedelements + attr_reader :definedtypes + attr_accessor :excn_handler_obj2soap + attr_accessor :excn_handler_soap2obj + + def initialize(definedtypes = XSD::NamedElements::Empty) + @definedtypes = definedtypes + # @definedelements = definedelements needed? + @excn_handler_obj2soap = nil + @excn_handler_soap2obj = nil + # For mapping AnyType element. + @rubytype_factory = RubytypeFactory.new( + :allow_untyped_struct => true, + :allow_original_mapping => true + ) + @schema_element_cache = {} + end + + def obj2soap(obj, qname = nil) + soap_obj = nil + if type = @definedtypes[qname] + soap_obj = obj2typesoap(obj, type) + else + soap_obj = any2soap(obj, qname) + end + return soap_obj if soap_obj + if @excn_handler_obj2soap + soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj| + Mapping._obj2soap(yield_obj, self) + } + return soap_obj if soap_obj + end + if qname + raise MappingError.new("cannot map #{obj.class.name} as #{qname}") + else + raise MappingError.new("cannot map #{obj.class.name} to SOAP/OM") + end + end + + # map anything for now: must refer WSDL while mapping. [ToDo] + def soap2obj(node, obj_class = nil) + begin + return any2obj(node, obj_class) + rescue MappingError + end + if @excn_handler_soap2obj + begin + return @excn_handler_soap2obj.call(node) { |yield_node| + Mapping._soap2obj(yield_node, self) + } + rescue Exception + end + end + raise MappingError.new("cannot map #{node.type.name} to Ruby object") + end + +private + + def any2soap(obj, qname) + if obj.nil? + SOAPNil.new + elsif qname.nil? or qname == XSD::AnyTypeName + @rubytype_factory.obj2soap(nil, obj, nil, self) + elsif obj.is_a?(XSD::NSDBase) + soap2soap(obj, qname) + elsif (type = TypeMap[qname]) + base2soap(obj, type) + else + nil + end + end + + def soap2soap(obj, type_qname) + if obj.is_a?(SOAPBasetype) + obj + elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname]) + soap_obj = obj + mark_marshalled_obj(obj, soap_obj) + elements2soap(obj, soap_obj, type.content.elements) + soap_obj + elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname]) + soap_obj = obj + contenttype = type.child_type + mark_marshalled_obj(obj, soap_obj) + obj.replace do |ele| + Mapping._obj2soap(ele, self, contenttype) + end + soap_obj + else + nil + end + end + + def obj2typesoap(obj, type) + if type.is_a?(::WSDL::XMLSchema::SimpleType) + simpleobj2soap(obj, type) + else + complexobj2soap(obj, type) + end + end + + def simpleobj2soap(obj, type) + type.check_lexical_format(obj) + return SOAPNil.new if obj.nil? # ToDo: check nillable. + o = base2soap(obj, TypeMap[type.base]) + o + end + + def complexobj2soap(obj, type) + case type.compoundtype + when :TYPE_STRUCT + struct2soap(obj, type.name, type) + when :TYPE_ARRAY + array2soap(obj, type.name, type) + when :TYPE_MAP + map2soap(obj, type.name, type) + when :TYPE_SIMPLE + simpleobj2soap(obj, type.simplecontent) + when :TYPE_EMPTY + raise MappingError.new("should be empty") unless obj.nil? + SOAPNil.new + else + raise MappingError.new("unknown compound type: #{type.compoundtype}") + end + end + + def base2soap(obj, type) + soap_obj = nil + if type <= XSD::XSDString + str = XSD::Charset.encoding_conv(obj.to_s, + Thread.current[:SOAPExternalCES], XSD::Charset.encoding) + soap_obj = type.new(str) + mark_marshalled_obj(obj, soap_obj) + else + soap_obj = type.new(obj) + end + soap_obj + end + + def struct2soap(obj, type_qname, type) + return SOAPNil.new if obj.nil? # ToDo: check nillable. + soap_obj = SOAPStruct.new(type_qname) + unless obj.nil? + mark_marshalled_obj(obj, soap_obj) + elements2soap(obj, soap_obj, type.content.elements) + end + soap_obj + end + + def array2soap(obj, type_qname, type) + return SOAPNil.new if obj.nil? # ToDo: check nillable. + arytype = type.child_type + soap_obj = SOAPArray.new(ValueArrayName, 1, arytype) + unless obj.nil? + mark_marshalled_obj(obj, soap_obj) + obj.each do |item| + soap_obj.add(Mapping._obj2soap(item, self, arytype)) + end + end + soap_obj + end + + MapKeyName = XSD::QName.new(nil, "key") + MapValueName = XSD::QName.new(nil, "value") + def map2soap(obj, type_qname, type) + return SOAPNil.new if obj.nil? # ToDo: check nillable. + keytype = type.child_type(MapKeyName) || XSD::AnyTypeName + valuetype = type.child_type(MapValueName) || XSD::AnyTypeName + soap_obj = SOAPStruct.new(MapQName) + unless obj.nil? + mark_marshalled_obj(obj, soap_obj) + obj.each do |key, value| + elem = SOAPStruct.new + elem.add("key", Mapping._obj2soap(key, self, keytype)) + elem.add("value", Mapping._obj2soap(value, self, valuetype)) + # ApacheAxis allows only 'item' here. + soap_obj.add("item", elem) + end + end + soap_obj + end + + def elements2soap(obj, soap_obj, elements) + elements.each do |element| + name = element.name.name + child_obj = Mapping.get_attribute(obj, name) + soap_obj.add(name, + Mapping._obj2soap(child_obj, self, element.type || element.name)) + end + end + + def any2obj(node, obj_class) + unless obj_class + typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name) + obj_class = Mapping.class_from_name(typestr) + end + if obj_class and obj_class.class_variables.include?('@@schema_element') + soap2stubobj(node, obj_class) + else + Mapping._soap2obj(node, Mapping::DefaultRegistry, obj_class) + end + end + + def soap2stubobj(node, obj_class) + obj = Mapping.create_empty_object(obj_class) + unless node.is_a?(SOAPNil) + add_elements2stubobj(node, obj) + end + obj + end + + def add_elements2stubobj(node, obj) + elements, as_array = schema_element_definition(obj.class) + vars = {} + node.each do |name, value| + item = elements.find { |k, v| k.name == name } + if item + elename, class_name = item + if klass = Mapping.class_from_name(class_name) + # klass must be a SOAPBasetype or a class + if klass.ancestors.include?(::SOAP::SOAPBasetype) + if value.respond_to?(:data) + child = klass.new(value.data).data + else + child = klass.new(nil).data + end + else + child = Mapping._soap2obj(value, self, klass) + end + elsif klass = Mapping.module_from_name(class_name) + # simpletype + if value.respond_to?(:data) + child = value.data + else + raise MappingError.new( + "cannot map to a module value: #{class_name}") + end + else + raise MappingError.new("unknown class: #{class_name}") + end + else # untyped element is treated as anyType. + child = Mapping._soap2obj(value, self) + end + vars[name] = child + end + Mapping.set_attributes(obj, vars) + end + + # it caches @@schema_element. this means that @@schema_element must not be + # changed while a lifetime of a WSDLLiteralRegistry. + def schema_element_definition(klass) + @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb new file mode 100644 index 00000000..7bb8e122 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb @@ -0,0 +1,418 @@ +# SOAP4R - WSDL literal mapping registry. +# Copyright (C) 2004, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/baseData' +require 'soap/mapping/mapping' +require 'soap/mapping/typeMap' +require 'xsd/codegen/gensupport' +require 'xsd/namedelements' + + +module SOAP +module Mapping + + +class WSDLLiteralRegistry < Registry + attr_reader :definedelements + attr_reader :definedtypes + attr_accessor :excn_handler_obj2soap + attr_accessor :excn_handler_soap2obj + + def initialize(definedtypes = XSD::NamedElements::Empty, + definedelements = XSD::NamedElements::Empty) + @definedtypes = definedtypes + @definedelements = definedelements + @excn_handler_obj2soap = nil + @excn_handler_soap2obj = nil + @schema_element_cache = {} + @schema_attribute_cache = {} + end + + def obj2soap(obj, qname) + soap_obj = nil + if ele = @definedelements[qname] + soap_obj = obj2elesoap(obj, ele) + elsif type = @definedtypes[qname] + soap_obj = obj2typesoap(obj, type, true) + else + soap_obj = any2soap(obj, qname) + end + return soap_obj if soap_obj + if @excn_handler_obj2soap + soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj| + Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT) + } + return soap_obj if soap_obj + end + raise MappingError.new("cannot map #{obj.class.name} as #{qname}") + end + + # node should be a SOAPElement + def soap2obj(node, obj_class = nil) + # obj_class is given when rpc/literal service. but ignored for now. + begin + return any2obj(node) + rescue MappingError + end + if @excn_handler_soap2obj + begin + return @excn_handler_soap2obj.call(node) { |yield_node| + Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT) + } + rescue Exception + end + end + if node.respond_to?(:type) + raise MappingError.new("cannot map #{node.type.name} to Ruby object") + else + raise MappingError.new("cannot map #{node.elename.name} to Ruby object") + end + end + +private + + MAPPING_OPT = { :no_reference => true } + + def obj2elesoap(obj, ele) + o = nil + qualified = (ele.elementform == 'qualified') + if ele.type + if type = @definedtypes[ele.type] + o = obj2typesoap(obj, type, qualified) + elsif type = TypeMap[ele.type] + o = base2soap(obj, type) + else + raise MappingError.new("cannot find type #{ele.type}") + end + elsif ele.local_complextype + o = obj2typesoap(obj, ele.local_complextype, qualified) + add_attributes2soap(obj, o) + elsif ele.local_simpletype + o = obj2typesoap(obj, ele.local_simpletype, qualified) + else + raise MappingError.new('illegal schema?') + end + o.elename = ele.name + o + end + + def obj2typesoap(obj, type, qualified) + if type.is_a?(::WSDL::XMLSchema::SimpleType) + simpleobj2soap(obj, type) + else + complexobj2soap(obj, type, qualified) + end + end + + def simpleobj2soap(obj, type) + type.check_lexical_format(obj) + return SOAPNil.new if obj.nil? # ToDo: check nillable. + o = base2soap(obj, TypeMap[type.base]) + o + end + + def complexobj2soap(obj, type, qualified) + o = SOAPElement.new(type.name) + o.qualified = qualified + type.each_element do |child_ele| + child = Mapping.get_attribute(obj, child_ele.name.name) + if child.nil? + if child_ele.nillable + # ToDo: test + # add empty element + child_soap = obj2elesoap(nil, child_ele) + o.add(child_soap) + elsif Integer(child_ele.minoccurs) == 0 + # nothing to do + else + raise MappingError.new("nil not allowed: #{child_ele.name.name}") + end + elsif child_ele.map_as_array? + child.each do |item| + child_soap = obj2elesoap(item, child_ele) + o.add(child_soap) + end + else + child_soap = obj2elesoap(child, child_ele) + o.add(child_soap) + end + end + o + end + + def any2soap(obj, qname) + if obj.is_a?(SOAPElement) + obj + elsif obj.class.class_variables.include?('@@schema_element') + stubobj2soap(obj, qname) + elsif obj.is_a?(SOAP::Mapping::Object) + mappingobj2soap(obj, qname) + elsif obj.is_a?(Hash) + ele = SOAPElement.from_obj(obj) + ele.elename = qname + ele + else + # expected to be a basetype or an anyType. + # SOAPStruct, etc. is used instead of SOAPElement. + begin + ele = Mapping.obj2soap(obj, nil, nil, MAPPING_OPT) + ele.elename = qname + ele + rescue MappingError + ele = SOAPElement.new(qname, obj.to_s) + end + if obj.respond_to?(:__xmlattr) + obj.__xmlattr.each do |key, value| + ele.extraattr[key] = value + end + end + ele + end + end + + def stubobj2soap(obj, qname) + ele = SOAPElement.new(qname) + ele.qualified = + (obj.class.class_variables.include?('@@schema_qualified') and + obj.class.class_eval('@@schema_qualified')) + add_elements2soap(obj, ele) + add_attributes2soap(obj, ele) + ele + end + + def mappingobj2soap(obj, qname) + ele = SOAPElement.new(qname) + obj.__xmlele.each do |key, value| + if value.is_a?(::Array) + value.each do |item| + ele.add(obj2soap(item, key)) + end + else + ele.add(obj2soap(value, key)) + end + end + obj.__xmlattr.each do |key, value| + ele.extraattr[key] = value + end + ele + end + + def add_elements2soap(obj, ele) + elements, as_array = schema_element_definition(obj.class) + if elements + elements.each do |elename, type| + if child = Mapping.get_attribute(obj, elename.name) + if as_array.include?(elename.name) + child.each do |item| + ele.add(obj2soap(item, elename)) + end + else + ele.add(obj2soap(child, elename)) + end + elsif obj.is_a?(::Array) and as_array.include?(elename.name) + obj.each do |item| + ele.add(obj2soap(item, elename)) + end + end + end + end + end + + def add_attributes2soap(obj, ele) + attributes = schema_attribute_definition(obj.class) + if attributes + attributes.each do |qname, param| + attr = obj.__send__('xmlattr_' + + XSD::CodeGen::GenSupport.safevarname(qname.name)) + ele.extraattr[qname] = attr + end + end + end + + def base2soap(obj, type) + soap_obj = nil + if type <= XSD::XSDString + str = XSD::Charset.encoding_conv(obj.to_s, + Thread.current[:SOAPExternalCES], XSD::Charset.encoding) + soap_obj = type.new(str) + else + soap_obj = type.new(obj) + end + soap_obj + end + + def anytype2obj(node) + if node.is_a?(::SOAP::SOAPBasetype) + return node.data + end + klass = ::SOAP::Mapping::Object + obj = klass.new + obj + end + + def any2obj(node, obj_class = nil) + unless obj_class + typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name) + obj_class = Mapping.class_from_name(typestr) + end + if obj_class and obj_class.class_variables.include?('@@schema_element') + soapele2stubobj(node, obj_class) + elsif node.is_a?(SOAPElement) or node.is_a?(SOAPStruct) + # SOAPArray for literal? + soapele2plainobj(node) + else + obj = Mapping.soap2obj(node, nil, obj_class, MAPPING_OPT) + add_attributes2plainobj(node, obj) + obj + end + end + + def soapele2stubobj(node, obj_class) + obj = Mapping.create_empty_object(obj_class) + add_elements2stubobj(node, obj) + add_attributes2stubobj(node, obj) + obj + end + + def soapele2plainobj(node) + obj = anytype2obj(node) + add_elements2plainobj(node, obj) + add_attributes2plainobj(node, obj) + obj + end + + def add_elements2stubobj(node, obj) + elements, as_array = schema_element_definition(obj.class) + vars = {} + node.each do |name, value| + item = elements.find { |k, v| k.name == name } + if item + elename, class_name = item + if klass = Mapping.class_from_name(class_name) + # klass must be a SOAPBasetype or a class + if klass.ancestors.include?(::SOAP::SOAPBasetype) + if value.respond_to?(:data) + child = klass.new(value.data).data + else + child = klass.new(nil).data + end + else + child = any2obj(value, klass) + end + elsif klass = Mapping.module_from_name(class_name) + # simpletype + if value.respond_to?(:data) + child = value.data + else + raise MappingError.new( + "cannot map to a module value: #{class_name}") + end + else + raise MappingError.new("unknown class/module: #{class_name}") + end + else # untyped element is treated as anyType. + child = any2obj(value) + end + if as_array.include?(elename.name) + (vars[name] ||= []) << child + else + vars[name] = child + end + end + Mapping.set_attributes(obj, vars) + end + + def add_attributes2stubobj(node, obj) + if attributes = schema_attribute_definition(obj.class) + define_xmlattr(obj) + attributes.each do |qname, class_name| + attr = node.extraattr[qname] + next if attr.nil? or attr.empty? + klass = Mapping.class_from_name(class_name) + if klass.ancestors.include?(::SOAP::SOAPBasetype) + child = klass.new(attr).data + else + child = attr + end + obj.__xmlattr[qname] = child + define_xmlattr_accessor(obj, qname) + end + end + end + + def add_elements2plainobj(node, obj) + node.each do |name, value| + obj.__add_xmlele_value(value.elename, any2obj(value)) + end + end + + def add_attributes2plainobj(node, obj) + return if node.extraattr.empty? + define_xmlattr(obj) + node.extraattr.each do |qname, value| + obj.__xmlattr[qname] = value + define_xmlattr_accessor(obj, qname) + end + end + + if RUBY_VERSION > "1.7.0" + def define_xmlattr_accessor(obj, qname) + name = XSD::CodeGen::GenSupport.safemethodname(qname.name) + Mapping.define_attr_accessor(obj, 'xmlattr_' + name, + proc { @__xmlattr[qname] }, + proc { |value| @__xmlattr[qname] = value }) + end + else + def define_xmlattr_accessor(obj, qname) + name = XSD::CodeGen::GenSupport.safemethodname(qname.name) + obj.instance_eval <<-EOS + def #{name} + @__xmlattr[#{qname.dump}] + end + + def #{name}=(value) + @__xmlattr[#{qname.dump}] = value + end + EOS + end + end + + if RUBY_VERSION > "1.7.0" + def define_xmlattr(obj) + obj.instance_variable_set('@__xmlattr', {}) + unless obj.respond_to?(:__xmlattr) + Mapping.define_attr_accessor(obj, :__xmlattr, proc { @__xmlattr }) + end + end + else + def define_xmlattr(obj) + obj.instance_variable_set('@__xmlattr', {}) + unless obj.respond_to?(:__xmlattr) + obj.instance_eval <<-EOS + def __xmlattr + @__xmlattr + end + EOS + end + end + end + + # it caches @@schema_element. this means that @@schema_element must not be + # changed while a lifetime of a WSDLLiteralRegistry. + def schema_element_definition(klass) + @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass) + end + + def schema_attribute_definition(klass) + @schema_attribute_cache[klass] ||= Mapping.schema_attribute_definition(klass) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/marshal.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/marshal.rb new file mode 100644 index 00000000..1c3d5b01 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/marshal.rb @@ -0,0 +1,59 @@ +# SOAP4R - Marshalling/Unmarshalling Ruby's object using SOAP Encoding. +# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require "soap/mapping" +require "soap/processor" + + +module SOAP + + +module Marshal + # Trying xsd:dateTime data to be recovered as aTime. + MarshalMappingRegistry = Mapping::Registry.new( + :allow_original_mapping => true) + MarshalMappingRegistry.add( + Time, + ::SOAP::SOAPDateTime, + ::SOAP::Mapping::Registry::DateTimeFactory + ) + + class << self + public + def dump(obj, io = nil) + marshal(obj, MarshalMappingRegistry, io) + end + + def load(stream) + unmarshal(stream, MarshalMappingRegistry) + end + + def marshal(obj, mapping_registry = MarshalMappingRegistry, io = nil) + elename = Mapping.name2elename(obj.class.to_s) + soap_obj = Mapping.obj2soap(obj, mapping_registry) + body = SOAPBody.new + body.add(elename, soap_obj) + env = SOAPEnvelope.new(nil, body) + SOAP::Processor.marshal(env, {}, io) + end + + def unmarshal(stream, mapping_registry = MarshalMappingRegistry) + env = SOAP::Processor.unmarshal(stream) + if env.nil? + raise ArgumentError.new("Illegal SOAP marshal format.") + end + Mapping.soap2obj(env.body.root_node, mapping_registry) + end + end +end + + +end + + +SOAPMarshal = SOAP::Marshal diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mimemessage.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mimemessage.rb new file mode 100644 index 00000000..acb4322e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/mimemessage.rb @@ -0,0 +1,240 @@ +# SOAP4R - MIME Message implementation. +# Copyright (C) 2002 Jamie Herre. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/attachment' + + +module SOAP + + +# Classes for MIME message handling. Should be put somewhere else! +# Tried using the 'tmail' module but found that I needed something +# lighter in weight. + + +class MIMEMessage + class MIMEMessageError < StandardError; end + + MultipartContentType = 'multipart/\w+' + + class Header + attr_accessor :str, :key, :root + + def initialize + @attrs = {} + end + + def [](key) + @attrs[key] + end + + def []=(key, value) + @attrs[key] = value + end + + def to_s + @key + ": " + @str + end + end + + class Headers < Hash + def self.parse(str) + new.parse(str) + end + + def parse(str) + header_cache = nil + str.each do |line| + case line + when /^\A[^\: \t]+:\s*.+$/ + parse_line(header_cache) if header_cache + header_cache = line.sub(/\r?\n\z/, '') + when /^\A\s+(.*)$/ + # a continuous line at the beginning line crashes here. + header_cache << line + else + raise RuntimeError.new("unexpected header: #{line.inspect}") + end + end + parse_line(header_cache) if header_cache + self + end + + def parse_line(line) + if /^\A([^\: \t]+):\s*(.+)\z/ =~ line + header = parse_rhs($2.strip) + header.key = $1.strip + self[header.key.downcase] = header + else + raise RuntimeError.new("unexpected header line: #{line.inspect}") + end + end + + def parse_rhs(str) + a = str.split(/;+\s+/) + header = Header.new + header.str = str + header.root = a.shift + a.each do |pair| + if pair =~ /(\w+)\s*=\s*"?([^"]+)"?/ + header[$1.downcase] = $2 + else + raise RuntimeError.new("unexpected header component: #{pair.inspect}") + end + end + header + end + + def add(key, value) + if key != nil and value != nil + header = parse_rhs(value) + header.key = key + self[key.downcase] = header + end + end + + def to_s + self.values.collect { |hdr| + hdr.to_s + }.join("\r\n") + end + end + + class Part + attr_accessor :headers, :body + + def initialize + @headers = Headers.new + @headers.add("Content-Transfer-Encoding", "8bit") + @body = nil + @contentid = nil + end + + def self.parse(str) + new.parse(str) + end + + def parse(str) + headers, body = str.split(/\r\n\r\n/s) + if headers != nil and body != nil + @headers = Headers.parse(headers) + @body = body.sub(/\r\n\z/, '') + else + raise RuntimeError.new("unexpected part: #{str.inspect}") + end + self + end + + def contentid + if @contentid == nil and @headers.key?('content-id') + @contentid = @headers['content-id'].str + @contentid = $1 if @contentid =~ /^<(.+)>$/ + end + @contentid + end + + alias content body + + def to_s + @headers.to_s + "\r\n\r\n" + @body + end + end + + def initialize + @parts = [] + @headers = Headers.new + @root = nil + end + + def self.parse(head, str) + new.parse(head, str) + end + + attr_reader :parts, :headers + + def close + @headers.add( + "Content-Type", + "multipart/related; type=\"text/xml\"; boundary=\"#{boundary}\"; start=\"#{@parts[0].contentid}\"" + ) + end + + def parse(head, str) + @headers = Headers.parse(head + "\r\n" + "From: jfh\r\n") + boundary = @headers['content-type']['boundary'] + if boundary != nil + parts = str.split(/--#{Regexp.quote(boundary)}\s*(?:\r\n|--\r\n)/) + part = parts.shift # preamble must be ignored. + @parts = parts.collect { |part| Part.parse(part) } + else + @parts = [Part.parse(str)] + end + if @parts.length < 1 + raise MIMEMessageError.new("This message contains no valid parts!") + end + self + end + + def root + if @root == nil + start = @headers['content-type']['start'] + @root = (start && @parts.find { |prt| prt.contentid == start }) || + @parts[0] + end + @root + end + + def boundary + if @boundary == nil + @boundary = "----=Part_" + __id__.to_s + rand.to_s + end + @boundary + end + + def add_part(content) + part = Part.new + part.headers.add("Content-Type", + "text/xml; charset=" + XSD::Charset.xml_encoding_label) + part.headers.add("Content-ID", Attachment.contentid(part)) + part.body = content + @parts.unshift(part) + end + + def add_attachment(attach) + part = Part.new + part.headers.add("Content-Type", attach.contenttype) + part.headers.add("Content-ID", attach.mime_contentid) + part.body = attach.content + @parts.unshift(part) + end + + def has_parts? + (@parts.length > 0) + end + + def headers_str + @headers.to_s + end + + def content_str + str = '' + @parts.each do |prt| + str << "--" + boundary + "\r\n" + str << prt.to_s + "\r\n" + end + str << '--' + boundary + "--\r\n" + str + end + + def to_s + str = headers_str + "\r\n\r\n" + conent_str + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/netHttpClient.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/netHttpClient.rb new file mode 100644 index 00000000..10d68e2a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/netHttpClient.rb @@ -0,0 +1,190 @@ +# SOAP4R - net/http wrapper +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'net/http' + + +module SOAP + + +class NetHttpClient + + SSLEnabled = begin + require 'net/https' + true + rescue LoadError + false + end + + attr_reader :proxy + attr_accessor :no_proxy + attr_accessor :debug_dev + attr_accessor :ssl_config # ignored for now. + attr_accessor :protocol_version # ignored for now. + attr_accessor :connect_timeout + attr_accessor :send_timeout # ignored for now. + attr_accessor :receive_timeout + + def initialize(proxy = nil, agent = nil) + @proxy = proxy ? URI.parse(proxy) : nil + @agent = agent + @debug_dev = nil + @session_manager = SessionManager.new + @no_proxy = @ssl_config = @protocol_version = nil + @connect_timeout = @send_timeout = @receive_timeout = nil + end + + def test_loopback_response + raise NotImplementedError.new("not supported for now") + end + + def proxy=(proxy) + if proxy.nil? + @proxy = nil + else + if proxy.is_a?(URI) + @proxy = proxy + else + @proxy = URI.parse(proxy) + end + if @proxy.scheme == nil or @proxy.scheme.downcase != 'http' or + @proxy.host == nil or @proxy.port == nil + raise ArgumentError.new("unsupported proxy `#{proxy}'") + end + end + reset_all + @proxy + end + + def set_basic_auth(uri, user_id, passwd) + # net/http does not handle url. + @basic_auth = [user_id, passwd] + raise NotImplementedError.new("basic_auth is not supported under soap4r + net/http.") + end + + def set_cookie_store(filename) + raise NotImplementedError.new + end + + def save_cookie_store(filename) + raise NotImplementedError.new + end + + def reset(url) + # no persistent connection. ignored. + end + + def reset_all + # no persistent connection. ignored. + end + + def post(url, req_body, header = {}) + unless url.is_a?(URI) + url = URI.parse(url) + end + extra = header.dup + extra['User-Agent'] = @agent if @agent + res = start(url) { |http| + http.post(url.request_uri, req_body, extra) + } + Response.new(res) + end + + def get_content(url, header = {}) + unless url.is_a?(URI) + url = URI.parse(url) + end + extra = header.dup + extra['User-Agent'] = @agent if @agent + res = start(url) { |http| + http.get(url.request_uri, extra) + } + res.body + end + +private + + def start(url) + http = create_connection(url) + response = nil + http.start { |worker| + response = yield(worker) + worker.finish + } + @debug_dev << response.body if @debug_dev + response + end + + def create_connection(url) + proxy_host = proxy_port = nil + unless no_proxy?(url) + proxy_host = @proxy.host + proxy_port = @proxy.port + end + http = Net::HTTP::Proxy(proxy_host, proxy_port).new(url.host, url.port) + if http.respond_to?(:set_debug_output) + http.set_debug_output(@debug_dev) + end + http.open_timeout = @connect_timeout if @connect_timeout + http.read_timeout = @receive_timeout if @receive_timeout + case url + when URI::HTTPS + if SSLEnabled + http.use_ssl = true + else + raise RuntimeError.new("Cannot connect to #{url} (OpenSSL is not installed.)") + end + when URI::HTTP + # OK + else + raise RuntimeError.new("Cannot connect to #{url} (Not HTTP.)") + end + http + end + + NO_PROXY_HOSTS = ['localhost'] + + def no_proxy?(uri) + if !@proxy or NO_PROXY_HOSTS.include?(uri.host) + return true + end + if @no_proxy + @no_proxy.scan(/([^:,]*)(?::(\d+))?/) do |host, port| + if /(\A|\.)#{Regexp.quote(host)}\z/i =~ uri.host && + (!port || uri.port == port.to_i) + return true + end + end + else + false + end + end + + class SessionManager + attr_accessor :connect_timeout + attr_accessor :send_timeout + attr_accessor :receive_timeout + end + + class Response + attr_reader :content + attr_reader :status + attr_reader :reason + attr_reader :contenttype + + def initialize(res) + @status = res.code.to_i + @reason = res.message + @contenttype = res['content-type'] + @content = res.body + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/parser.rb new file mode 100644 index 00000000..412fd485 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/parser.rb @@ -0,0 +1,251 @@ +# SOAP4R - SOAP XML Instance Parser library. +# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/ns' +require 'xsd/xmlparser' +require 'soap/soap' +require 'soap/baseData' +require 'soap/encodingstyle/handler' + + +module SOAP + + +class Parser + include SOAP + + class ParseError < Error; end + class FormatDecodeError < ParseError; end + class UnexpectedElementError < ParseError; end + +private + + class ParseFrame + attr_reader :node + attr_reader :name + attr_reader :ns, :encodingstyle + + class NodeContainer + def initialize(node) + @node = node + end + + def node + @node + end + + def replace_node(node) + @node = node + end + end + + public + + def initialize(ns, name, node, encodingstyle) + @ns = ns + @name = name + self.node = node + @encodingstyle = encodingstyle + end + + def node=(node) + @node = NodeContainer.new(node) + end + end + +public + + attr_accessor :envelopenamespace + attr_accessor :default_encodingstyle + attr_accessor :decode_typemap + attr_accessor :allow_unqualified_element + + def initialize(opt = {}) + @opt = opt + @parser = XSD::XMLParser.create_parser(self, opt) + @parsestack = nil + @lastnode = nil + @handlers = {} + @envelopenamespace = opt[:envelopenamespace] || EnvelopeNamespace + @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace + @decode_typemap = opt[:decode_typemap] || nil + @allow_unqualified_element = opt[:allow_unqualified_element] || false + end + + def charset + @parser.charset + end + + def parse(string_or_readable) + @parsestack = [] + @lastnode = nil + + @handlers.each do |uri, handler| + handler.decode_prologue + end + + @parser.do_parse(string_or_readable) + + unless @parsestack.empty? + raise FormatDecodeError.new("Unbalanced tag in XML.") + end + + @handlers.each do |uri, handler| + handler.decode_epilogue + end + + @lastnode + end + + def start_element(name, attrs) + lastframe = @parsestack.last + ns = parent = parent_encodingstyle = nil + if lastframe + ns = lastframe.ns.clone_ns + parent = lastframe.node + parent_encodingstyle = lastframe.encodingstyle + else + ns = XSD::NS.new + parent = ParseFrame::NodeContainer.new(nil) + parent_encodingstyle = nil + end + + attrs = XSD::XMLParser.filter_ns(ns, attrs) + encodingstyle = find_encodingstyle(ns, attrs) + + # Children's encodingstyle is derived from its parent. + if encodingstyle.nil? + if parent.node.is_a?(SOAPHeader) + encodingstyle = LiteralNamespace + else + encodingstyle = parent_encodingstyle || @default_encodingstyle + end + end + + node = decode_tag(ns, name, attrs, parent, encodingstyle) + + @parsestack << ParseFrame.new(ns, name, node, encodingstyle) + end + + def characters(text) + lastframe = @parsestack.last + if lastframe + # Need not to be cloned because character does not have attr. + decode_text(lastframe.ns, text, lastframe.encodingstyle) + else + # Ignore Text outside of SOAP Envelope. + p text if $DEBUG + end + end + + def end_element(name) + lastframe = @parsestack.pop + unless name == lastframe.name + raise UnexpectedElementError.new("Closing element name '#{ name }' does not match with opening element '#{ lastframe.name }'.") + end + decode_tag_end(lastframe.ns, lastframe.node, lastframe.encodingstyle) + @lastnode = lastframe.node.node + end + +private + + def find_encodingstyle(ns, attrs) + attrs.each do |key, value| + if (ns.compare(@envelopenamespace, AttrEncodingStyle, key)) + return value + end + end + nil + end + + def decode_tag(ns, name, attrs, parent, encodingstyle) + ele = ns.parse(name) + + # Envelope based parsing. + if ((ele.namespace == @envelopenamespace) || + (@allow_unqualified_element && ele.namespace.nil?)) + o = decode_soap_envelope(ns, ele, attrs, parent) + return o if o + end + + # Encoding based parsing. + handler = find_handler(encodingstyle) + if handler + return handler.decode_tag(ns, ele, attrs, parent) + else + raise FormatDecodeError.new("Unknown encodingStyle: #{ encodingstyle }.") + end + end + + def decode_tag_end(ns, node, encodingstyle) + return unless encodingstyle + + handler = find_handler(encodingstyle) + if handler + return handler.decode_tag_end(ns, node) + else + raise FormatDecodeError.new("Unknown encodingStyle: #{ encodingstyle }.") + end + end + + def decode_text(ns, text, encodingstyle) + handler = find_handler(encodingstyle) + + if handler + handler.decode_text(ns, text) + else + # How should I do? + end + end + + def decode_soap_envelope(ns, ele, attrs, parent) + o = nil + if ele.name == EleEnvelope + o = SOAPEnvelope.new + if ext = @opt[:external_content] + ext.each do |k, v| + o.external_content[k] = v + end + end + elsif ele.name == EleHeader + unless parent.node.is_a?(SOAPEnvelope) + raise FormatDecodeError.new("Header should be a child of Envelope.") + end + o = SOAPHeader.new + parent.node.header = o + elsif ele.name == EleBody + unless parent.node.is_a?(SOAPEnvelope) + raise FormatDecodeError.new("Body should be a child of Envelope.") + end + o = SOAPBody.new + parent.node.body = o + elsif ele.name == EleFault + unless parent.node.is_a?(SOAPBody) + raise FormatDecodeError.new("Fault should be a child of Body.") + end + o = SOAPFault.new + parent.node.fault = o + end + o + end + + def find_handler(encodingstyle) + unless @handlers.key?(encodingstyle) + handler_factory = SOAP::EncodingStyle::Handler.handler(encodingstyle) || + SOAP::EncodingStyle::Handler.handler(EncodingNamespace) + handler = handler_factory.new(@parser.charset) + handler.decode_typemap = @decode_typemap + handler.decode_prologue + @handlers[encodingstyle] = handler + end + @handlers[encodingstyle] + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/processor.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/processor.rb new file mode 100644 index 00000000..3c6dbedf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/processor.rb @@ -0,0 +1,66 @@ +# SOAP4R - marshal/unmarshal interface. +# Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/datatypes' +require 'soap/soap' +require 'soap/element' +require 'soap/parser' +require 'soap/generator' +require 'soap/encodingstyle/soapHandler' +require 'soap/encodingstyle/literalHandler' +require 'soap/encodingstyle/aspDotNetHandler' + + +module SOAP + + +module Processor + @@default_parser_option = {} + + class << self + public + + def marshal(env, opt = {}, io = nil) + generator = create_generator(opt) + marshalled_str = generator.generate(env, io) + unless env.external_content.empty? + opt[:external_content] = env.external_content + end + marshalled_str + end + + def unmarshal(stream, opt = {}) + parser = create_parser(opt) + parser.parse(stream) + end + + def default_parser_option=(rhs) + @@default_parser_option = rhs + end + + def default_parser_option + @@default_parser_option + end + + private + + def create_generator(opt) + SOAPGenerator.new(opt) + end + + def create_parser(opt) + if opt.empty? + opt = @@default_parser_option + end + ::SOAP::Parser.new(opt) + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/property.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/property.rb new file mode 100644 index 00000000..882dcc6e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/property.rb @@ -0,0 +1,333 @@ +# soap/property.rb: SOAP4R - Property implementation. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module SOAP + + +# Property stream format: +# +# line separator is \r?\n. 1 line per a property. +# line which begins with '#' is a comment line. empty line is ignored, too. +# key/value separator is ':' or '='. +# '\' as escape character. but line separator cannot be escaped. +# \s at the head/tail of key/value are trimmed. +# +# '[' + key + ']' indicates property section. for example, +# +# [aaa.bbb] +# ccc = ddd +# eee.fff = ggg +# [] +# aaa.hhh = iii +# +# is the same as; +# +# aaa.bbb.ccc = ddd +# aaa.bbb.eee.fff = ggg +# aaa.hhh = iii +# +class Property + FrozenError = (RUBY_VERSION >= "1.9.0") ? RuntimeError : TypeError + + include Enumerable + + module Util + def const_from_name(fqname) + fqname.split("::").inject(Kernel) { |klass, name| klass.const_get(name) } + end + module_function :const_from_name + + def require_from_name(fqname) + require File.join(fqname.split("::").collect { |ele| ele.downcase }) + end + module_function :require_from_name + end + + def self.load(stream) + new.load(stream) + end + + def self.loadproperty(propname) + new.loadproperty(propname) + end + + def initialize + @store = Hash.new + @hook = Hash.new + @self_hook = Array.new + @locked = false + end + + KEY_REGSRC = '([^=:\\\\]*(?:\\\\.[^=:\\\\]*)*)' + DEF_REGSRC = '\\s*' + KEY_REGSRC + '\\s*[=:]\\s*(.*)' + COMMENT_REGEXP = Regexp.new('^(?:#.*|)$') + CATDEF_REGEXP = Regexp.new("^\\[\\s*#{KEY_REGSRC}\\s*\\]$") + LINE_REGEXP = Regexp.new("^#{DEF_REGSRC}$") + def load(stream) + key_prefix = "" + stream.each_with_index do |line, lineno| + line.sub!(/\r?\n\z/, '') + case line + when COMMENT_REGEXP + next + when CATDEF_REGEXP + key_prefix = $1.strip + when LINE_REGEXP + key, value = $1.strip, $2.strip + key = "#{key_prefix}.#{key}" unless key_prefix.empty? + key, value = loadstr(key), loadstr(value) + self[key] = value + else + raise TypeError.new( + "property format error at line #{lineno + 1}: `#{line}'") + end + end + self + end + + # find property from $:. + def loadproperty(propname) + return loadpropertyfile(propname) if File.file?(propname) + $:.each do |path| + if File.file?(file = File.join(path, propname)) + return loadpropertyfile(file) + end + end + nil + end + + # name: a Symbol, String or an Array + def [](name) + referent(name_to_a(name)) + end + + # name: a Symbol, String or an Array + # value: an Object + def []=(name, value) + name_pair = name_to_a(name).freeze + hooks = assign(name_pair, value) + hooks.each do |hook| + hook.call(name_pair, value) + end + value + end + + # value: an Object + # key is generated by property + def <<(value) + self[generate_new_key] = value + end + + # name: a Symbol, String or an Array; nil means hook to the root + # cascade: true/false; for cascading hook of sub key + # hook: block which will be called with 2 args, name and value + def add_hook(name = nil, cascade = false, &hook) + if name == nil or name == true or name == false + cascade = name + assign_self_hook(cascade, &hook) + else + assign_hook(name_to_a(name), cascade, &hook) + end + end + + def each + @store.each do |key, value| + yield(key, value) + end + end + + def empty? + @store.empty? + end + + def keys + @store.keys + end + + def values + @store.values + end + + def lock(cascade = false) + if cascade + each_key do |key| + key.lock(cascade) + end + end + @locked = true + self + end + + def unlock(cascade = false) + @locked = false + if cascade + each_key do |key| + key.unlock(cascade) + end + end + self + end + + def locked? + @locked + end + +protected + + def deref_key(key) + check_lock(key) + ref = @store[key] ||= self.class.new + unless propkey?(ref) + raise ArgumentError.new("key `#{key}' already defined as a value") + end + ref + end + + def local_referent(key) + check_lock(key) + if propkey?(@store[key]) and @store[key].locked? + raise FrozenError.new("cannot split any key from locked property") + end + @store[key] + end + + def local_assign(key, value) + check_lock(key) + if @locked + if propkey?(value) + raise FrozenError.new("cannot add any key to locked property") + elsif propkey?(@store[key]) + raise FrozenError.new("cannot override any key in locked property") + end + end + @store[key] = value + end + + def local_hook(key, direct) + hooks = [] + (@self_hook + (@hook[key] || NO_HOOK)).each do |hook, cascade| + hooks << hook if direct or cascade + end + hooks + end + + def local_assign_hook(key, cascade, &hook) + check_lock(key) + @store[key] ||= nil + (@hook[key] ||= []) << [hook, cascade] + end + +private + + NO_HOOK = [].freeze + + def referent(ary) + ary[0..-2].inject(self) { |ref, name| + ref.deref_key(to_key(name)) + }.local_referent(to_key(ary.last)) + end + + def assign(ary, value) + ref = self + hook = NO_HOOK + ary[0..-2].each do |name| + key = to_key(name) + hook += ref.local_hook(key, false) + ref = ref.deref_key(key) + end + last_key = to_key(ary.last) + ref.local_assign(last_key, value) + hook + ref.local_hook(last_key, true) + end + + def assign_hook(ary, cascade, &hook) + ary[0..-2].inject(self) { |ref, name| + ref.deref_key(to_key(name)) + }.local_assign_hook(to_key(ary.last), cascade, &hook) + end + + def assign_self_hook(cascade, &hook) + check_lock(nil) + @self_hook << [hook, cascade] + end + + def each_key + self.each do |key, value| + if propkey?(value) + yield(value) + end + end + end + + def check_lock(key) + if @locked and (key.nil? or !@store.key?(key)) + raise FrozenError.new("cannot add any key to locked property") + end + end + + def propkey?(value) + value.is_a?(::SOAP::Property) + end + + def name_to_a(name) + case name + when Symbol + [name] + when String + name.scan(/[^.\\]+(?:\\.[^.\\])*/) # split with unescaped '.' + when Array + name + else + raise ArgumentError.new("Unknown name #{name}(#{name.class})") + end + end + + def to_key(name) + name.to_s.downcase + end + + def generate_new_key + if @store.empty? + "0" + else + (key_max + 1).to_s + end + end + + def key_max + (@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i + end + + def loadpropertyfile(file) + puts "find property at #{file}" if $DEBUG + File.open(file) do |f| + load(f) + end + end + + def loadstr(str) + str.gsub(/\\./) { |c| eval("\"#{c}\"") } + end +end + + +end + + +# for ruby/1.6. +unless Enumerable.instance_methods.include?('inject') + module Enumerable + def inject(init) + result = init + each do |item| + result = yield(result, item) + end + result + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/cgistub.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/cgistub.rb new file mode 100644 index 00000000..487f05a9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/cgistub.rb @@ -0,0 +1,206 @@ +# SOAP4R - CGI/mod_ruby stub library +# Copyright (C) 2001, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/streamHandler' +require 'webrick/httpresponse' +require 'webrick/httpstatus' +require 'logger' +require 'soap/rpc/soaplet' + + +module SOAP +module RPC + + +### +# SYNOPSIS +# CGIStub.new +# +# DESCRIPTION +# To be written... +# +class CGIStub < Logger::Application + include SOAP + include WEBrick + + class SOAPRequest + attr_reader :body + + def [](var); end + + def meta_vars; end + end + + class SOAPStdinRequest < SOAPRequest + attr_reader :body + + def initialize(stream) + size = ENV['CONTENT_LENGTH'].to_i || 0 + @body = stream.read(size) + end + + def [](var) + ENV[var.gsub(/-/, '_').upcase] + end + + def meta_vars + { + 'HTTP_SOAPACTION' => ENV['HTTP_SOAPAction'] + } + end + end + + class SOAPFCGIRequest < SOAPRequest + attr_reader :body + + def initialize(request) + @request = request + @body = @request.in.read + end + + def [](var) + @request.env[var.gsub(/-/, '_').upcase] + end + + def meta_vars + { + 'HTTP_SOAPACTION' => @request.env['HTTP_SOAPAction'] + } + end + end + + def initialize(appname, default_namespace) + super(appname) + set_log(STDERR) + self.level = ERROR + @default_namespace = default_namespace + @remote_host = ENV['REMOTE_HOST'] || ENV['REMOTE_ADDR'] || 'unknown' + @router = ::SOAP::RPC::Router.new(self.class.name) + @soaplet = ::SOAP::RPC::SOAPlet.new(@router) + on_init + end + + def on_init + # do extra initialization in a derived class if needed. + end + + def mapping_registry + @router.mapping_registry + end + + def mapping_registry=(value) + @router.mapping_registry = value + end + + def generate_explicit_type + @router.generate_explicit_type + end + + def generate_explicit_type=(generate_explicit_type) + @router.generate_explicit_type = generate_explicit_type + end + + # servant entry interface + + def add_rpc_servant(obj, namespace = @default_namespace) + @router.add_rpc_servant(obj, namespace) + end + alias add_servant add_rpc_servant + + def add_headerhandler(obj) + @router.add_headerhandler(obj) + end + alias add_rpc_headerhandler add_headerhandler + + # method entry interface + + def add_rpc_method(obj, name, *param) + add_rpc_method_with_namespace_as(@default_namespace, obj, name, name, *param) + end + alias add_method add_rpc_method + + def add_rpc_method_as(obj, name, name_as, *param) + add_rpc_method_with_namespace_as(@default_namespace, obj, name, name_as, *param) + end + alias add_method_as add_rpc_method_as + + def add_rpc_method_with_namespace(namespace, obj, name, *param) + add_rpc_method_with_namespace_as(namespace, obj, name, name, *param) + end + alias add_method_with_namespace add_rpc_method_with_namespace + + def add_rpc_method_with_namespace_as(namespace, obj, name, name_as, *param) + qname = XSD::QName.new(namespace, name_as) + soapaction = nil + param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param) + @router.add_rpc_operation(obj, qname, soapaction, name, param_def) + end + alias add_method_with_namespace_as add_rpc_method_with_namespace_as + + def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {}) + @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt) + end + + def add_document_operation(receiver, soapaction, name, param_def, opt = {}) + @router.add_document_operation(receiver, soapaction, name, param_def, opt) + end + + def set_fcgi_request(request) + @fcgi = request + end + +private + + HTTPVersion = WEBrick::HTTPVersion.new('1.0') # dummy; ignored + + def run + res = WEBrick::HTTPResponse.new({:HTTPVersion => HTTPVersion}) + begin + @log.info { "received a request from '#{ @remote_host }'" } + if @fcgi + req = SOAPFCGIRequest.new(@fcgi) + else + req = SOAPStdinRequest.new($stdin) + end + @soaplet.do_POST(req, res) + rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex + res.set_error(ex) + rescue HTTPStatus::Error => ex + res.set_error(ex) + rescue HTTPStatus::Status => ex + res.status = ex.code + rescue StandardError, NameError => ex # for Ruby 1.6 + res.set_error(ex, true) + ensure + if defined?(MOD_RUBY) + r = Apache.request + r.status = res.status + r.content_type = res.content_type + r.send_http_header + buf = res.body + else + buf = '' + res.send_response(buf) + buf.sub!(/^[^\r]+\r\n/, '') # Trim status line. + end + @log.debug { "SOAP CGI Response:\n#{ buf }" } + if @fcgi + @fcgi.out.print buf + @fcgi.finish + @fcgi = nil + else + print buf + end + end + 0 + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/driver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/driver.rb new file mode 100644 index 00000000..0fb4e824 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/driver.rb @@ -0,0 +1,254 @@ +# SOAP4R - SOAP RPC driver +# Copyright (C) 2000, 2001, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/soap' +require 'soap/mapping' +require 'soap/mapping/wsdlliteralregistry' +require 'soap/rpc/rpc' +require 'soap/rpc/proxy' +require 'soap/rpc/element' +require 'soap/streamHandler' +require 'soap/property' +require 'soap/header/handlerset' + + +module SOAP +module RPC + + +class Driver + class << self + if RUBY_VERSION >= "1.7.0" + def __attr_proxy(symbol, assignable = false) + name = symbol.to_s + define_method(name) { + @proxy.__send__(name) + } + if assignable + aname = name + '=' + define_method(aname) { |rhs| + @proxy.__send__(aname, rhs) + } + end + end + else + def __attr_proxy(symbol, assignable = false) + name = symbol.to_s + module_eval <<-EOS + def #{name} + @proxy.#{name} + end + EOS + if assignable + module_eval <<-EOS + def #{name}=(value) + @proxy.#{name} = value + end + EOS + end + end + end + end + + __attr_proxy :endpoint_url, true + __attr_proxy :mapping_registry, true + __attr_proxy :default_encodingstyle, true + __attr_proxy :generate_explicit_type, true + __attr_proxy :allow_unqualified_element, true + __attr_proxy :headerhandler + __attr_proxy :streamhandler + __attr_proxy :test_loopback_response + __attr_proxy :reset_stream + + attr_reader :proxy + attr_reader :options + attr_accessor :soapaction + + def inspect + "#<#{self.class}:#{@proxy.inspect}>" + end + + def httpproxy + options["protocol.http.proxy"] + end + + def httpproxy=(httpproxy) + options["protocol.http.proxy"] = httpproxy + end + + def wiredump_dev + options["protocol.http.wiredump_dev"] + end + + def wiredump_dev=(wiredump_dev) + options["protocol.http.wiredump_dev"] = wiredump_dev + end + + def mandatorycharset + options["protocol.mandatorycharset"] + end + + def mandatorycharset=(mandatorycharset) + options["protocol.mandatorycharset"] = mandatorycharset + end + + def wiredump_file_base + options["protocol.wiredump_file_base"] + end + + def wiredump_file_base=(wiredump_file_base) + options["protocol.wiredump_file_base"] = wiredump_file_base + end + + def initialize(endpoint_url, namespace = nil, soapaction = nil) + @namespace = namespace + @soapaction = soapaction + @options = setup_options + @wiredump_file_base = nil + @proxy = Proxy.new(endpoint_url, @soapaction, @options) + end + + def loadproperty(propertyname) + unless options.loadproperty(propertyname) + raise LoadError.new("No such property to load -- #{propertyname}") + end + end + + def add_rpc_method(name, *params) + add_rpc_method_with_soapaction_as(name, name, @soapaction, *params) + end + + def add_rpc_method_as(name, name_as, *params) + add_rpc_method_with_soapaction_as(name, name_as, @soapaction, *params) + end + + def add_rpc_method_with_soapaction(name, soapaction, *params) + add_rpc_method_with_soapaction_as(name, name, soapaction, *params) + end + + def add_rpc_method_with_soapaction_as(name, name_as, soapaction, *params) + param_def = SOAPMethod.create_rpc_param_def(params) + qname = XSD::QName.new(@namespace, name_as) + @proxy.add_rpc_method(qname, soapaction, name, param_def) + add_rpc_method_interface(name, param_def) + end + + # add_method is for shortcut of typical rpc/encoded method definition. + alias add_method add_rpc_method + alias add_method_as add_rpc_method_as + alias add_method_with_soapaction add_rpc_method_with_soapaction + alias add_method_with_soapaction_as add_rpc_method_with_soapaction_as + + def add_document_method(name, soapaction, req_qname, res_qname) + param_def = SOAPMethod.create_doc_param_def(req_qname, res_qname) + @proxy.add_document_method(soapaction, name, param_def) + add_document_method_interface(name, param_def) + end + + def add_rpc_operation(qname, soapaction, name, param_def, opt = {}) + @proxy.add_rpc_operation(qname, soapaction, name, param_def, opt) + add_rpc_method_interface(name, param_def) + end + + def add_document_operation(soapaction, name, param_def, opt = {}) + @proxy.add_document_operation(soapaction, name, param_def, opt) + add_document_method_interface(name, param_def) + end + + def invoke(headers, body) + if headers and !headers.is_a?(SOAPHeader) + headers = create_header(headers) + end + set_wiredump_file_base(body.elename.name) + env = @proxy.invoke(headers, body) + if env.nil? + return nil, nil + else + return env.header, env.body + end + end + + def call(name, *params) + set_wiredump_file_base(name) + @proxy.call(name, *params) + end + +private + + def set_wiredump_file_base(name) + if @wiredump_file_base + @proxy.set_wiredump_file_base("#{@wiredump_file_base}_#{name}") + end + end + + def create_header(headers) + header = SOAPHeader.new() + headers.each do |content, mustunderstand, encodingstyle| + header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle)) + end + header + end + + def setup_options + if opt = Property.loadproperty(::SOAP::PropertyName) + opt = opt["client"] + end + opt ||= Property.new + opt.add_hook("protocol.mandatorycharset") do |key, value| + @proxy.mandatorycharset = value + end + opt.add_hook("protocol.wiredump_file_base") do |key, value| + @wiredump_file_base = value + end + opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label + opt["protocol.http.proxy"] ||= Env::HTTP_PROXY + opt["protocol.http.no_proxy"] ||= Env::NO_PROXY + opt + end + + def add_rpc_method_interface(name, param_def) + param_count = RPC::SOAPMethod.param_count(param_def, + RPC::SOAPMethod::IN, RPC::SOAPMethod::INOUT) + add_method_interface(name, param_count) + end + + def add_document_method_interface(name, param_def) + param_count = RPC::SOAPMethod.param_count(param_def, RPC::SOAPMethod::IN) + add_method_interface(name, param_count) + end + + if RUBY_VERSION > "1.7.0" + def add_method_interface(name, param_count) + ::SOAP::Mapping.define_singleton_method(self, name) do |*arg| + unless arg.size == param_count + raise ArgumentError.new( + "wrong number of arguments (#{arg.size} for #{param_count})") + end + call(name, *arg) + end + self.method(name) + end + else + def add_method_interface(name, param_count) + instance_eval <<-EOS + def #{name}(*arg) + unless arg.size == #{param_count} + raise ArgumentError.new( + "wrong number of arguments (\#{arg.size} for #{param_count})") + end + call(#{name.dump}, *arg) + end + EOS + self.method(name) + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/element.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/element.rb new file mode 100644 index 00000000..c224b03d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/element.rb @@ -0,0 +1,325 @@ +# SOAP4R - RPC element definition. +# Copyright (C) 2000, 2001, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/baseData' + + +module SOAP + +# Add method definitions for RPC to common definition in element.rb +class SOAPBody < SOAPStruct + public + + def request + root_node + end + + def response + root = root_node + if !@is_fault + if root.nil? + nil + elsif root.is_a?(SOAPBasetype) + root + else + # Initial element is [retval]. + root[0] + end + else + root + end + end + + def outparams + root = root_node + if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype) + op = root[1..-1] + op = nil if op && op.empty? + op + else + nil + end + end + + def fault + if @is_fault + self['fault'] + else + nil + end + end + + def fault=(fault) + @is_fault = true + add_member('fault', fault) + end +end + + +module RPC + + +class RPCError < Error; end +class MethodDefinitionError < RPCError; end +class ParameterError < RPCError; end + +class SOAPMethod < SOAPStruct + RETVAL = 'retval' + IN = 'in' + OUT = 'out' + INOUT = 'inout' + + attr_reader :param_def + attr_reader :inparam + attr_reader :outparam + attr_reader :retval_name + attr_reader :retval_class_name + + def initialize(qname, param_def = nil) + super(nil) + @elename = qname + @encodingstyle = nil + + @param_def = param_def + + @signature = [] + @inparam_names = [] + @inoutparam_names = [] + @outparam_names = [] + + @inparam = {} + @outparam = {} + @retval_name = nil + @retval_class_name = nil + + init_param(@param_def) if @param_def + end + + def have_outparam? + @outparam_names.size > 0 + end + + def input_params + collect_params(IN, INOUT) + end + + def output_params + collect_params(OUT, INOUT) + end + + def set_param(params) + params.each do |param, data| + @inparam[param] = data + data.elename.name = param + data.parent = self + end + end + + def set_outparam(params) + params.each do |param, data| + @outparam[param] = data + data.elename.name = param + end + end + + def SOAPMethod.param_count(param_def, *type) + count = 0 + param_def.each do |io_type, name, param_type| + if type.include?(io_type) + count += 1 + end + end + count + end + + def SOAPMethod.derive_rpc_param_def(obj, name, *param) + if param.size == 1 and param[0].is_a?(Array) + return param[0] + end + if param.empty? + method = obj.method(name) + param_names = (1..method.arity.abs).collect { |i| "p#{i}" } + else + param_names = param + end + create_rpc_param_def(param_names) + end + + def SOAPMethod.create_rpc_param_def(param_names) + param_def = [] + param_names.each do |param_name| + param_def.push([IN, param_name, nil]) + end + param_def.push([RETVAL, 'return', nil]) + param_def + end + + def SOAPMethod.create_doc_param_def(req_qnames, res_qnames) + req_qnames = [req_qnames] if req_qnames.is_a?(XSD::QName) + res_qnames = [res_qnames] if res_qnames.is_a?(XSD::QName) + param_def = [] + req_qnames.each do |qname| + param_def << [IN, qname.name, [nil, qname.namespace, qname.name]] + end + res_qnames.each do |qname| + param_def << [OUT, qname.name, [nil, qname.namespace, qname.name]] + end + param_def + end + +private + + def collect_params(*type) + names = [] + @signature.each do |io_type, name, param_type| + names << name if type.include?(io_type) + end + names + end + + def init_param(param_def) + param_def.each do |io_type, name, param_type| + case io_type + when IN + @signature.push([IN, name, param_type]) + @inparam_names.push(name) + when OUT + @signature.push([OUT, name, param_type]) + @outparam_names.push(name) + when INOUT + @signature.push([INOUT, name, param_type]) + @inoutparam_names.push(name) + when RETVAL + if @retval_name + raise MethodDefinitionError.new('duplicated retval') + end + @retval_name = name + @retval_class_name = nil + if param_type + if param_type[0].is_a?(String) + @retval_class_name = Mapping.class_from_name(param_type[0]) + else + @retval_class_name = param_type[0] + end + end + else + raise MethodDefinitionError.new("unknown type: #{io_type}") + end + end + end +end + + +class SOAPMethodRequest < SOAPMethod + attr_accessor :soapaction + + def SOAPMethodRequest.create_request(qname, *params) + param_def = [] + param_value = [] + i = 0 + params.each do |param| + param_name = "p#{i}" + i += 1 + param_def << [IN, param_name, nil] + param_value << [param_name, param] + end + param_def << [RETVAL, 'return', nil] + o = new(qname, param_def) + o.set_param(param_value) + o + end + + def initialize(qname, param_def = nil, soapaction = nil) + check_elename(qname) + super(qname, param_def) + @soapaction = soapaction + end + + def each + input_params.each do |name| + unless @inparam[name] + raise ParameterError.new("parameter: #{name} was not given") + end + yield(name, @inparam[name]) + end + end + + def dup + req = self.class.new(@elename.dup, @param_def, @soapaction) + req.encodingstyle = @encodingstyle + req + end + + def create_method_response(response_name = nil) + response_name ||= + XSD::QName.new(@elename.namespace, @elename.name + 'Response') + SOAPMethodResponse.new(response_name, @param_def) + end + +private + + def check_elename(qname) + # NCName & ruby's method name + unless /\A[\w_][\w\d_\-]*\z/ =~ qname.name + raise MethodDefinitionError.new("element name '#{qname.name}' not allowed") + end + end +end + + +class SOAPMethodResponse < SOAPMethod + + def initialize(qname, param_def = nil) + super(qname, param_def) + @retval = nil + end + + def retval=(retval) + @retval = retval + @retval.elename = @retval.elename.dup_name(@retval_name || 'return') + retval.parent = self + retval + end + + def each + if @retval_name and !@retval.is_a?(SOAPVoid) + yield(@retval_name, @retval) + end + + output_params.each do |name| + unless @outparam[name] + raise ParameterError.new("parameter: #{name} was not given") + end + yield(name, @outparam[name]) + end + end +end + + +# To return(?) void explicitly. +# def foo(input_var) +# ... +# return SOAP::RPC::SOAPVoid.new +# end +class SOAPVoid < XSD::XSDAnySimpleType + include SOAPBasetype + extend SOAPModuleUtils + Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil) + +public + def initialize() + @elename = Name + @id = nil + @precedents = [] + @parent = nil + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/httpserver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/httpserver.rb new file mode 100644 index 00000000..6d2a72eb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/httpserver.rb @@ -0,0 +1,129 @@ +# SOAP4R - WEBrick HTTP Server +# Copyright (C) 2003, 2004 by NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'logger' +require 'soap/rpc/soaplet' +require 'soap/streamHandler' +require 'webrick' + + +module SOAP +module RPC + + +class HTTPServer < Logger::Application + attr_reader :server + attr_accessor :default_namespace + + def initialize(config) + super(config[:SOAPHTTPServerApplicationName] || self.class.name) + @default_namespace = config[:SOAPDefaultNamespace] + @webrick_config = config.dup + self.level = Logger::Severity::ERROR # keep silent by default + @webrick_config[:Logger] ||= @log + @log = @webrick_config[:Logger] # sync logger of App and HTTPServer + @router = ::SOAP::RPC::Router.new(self.class.name) + @soaplet = ::SOAP::RPC::SOAPlet.new(@router) + on_init + @server = WEBrick::HTTPServer.new(@webrick_config) + @server.mount('/', @soaplet) + end + + def on_init + # do extra initialization in a derived class if needed. + end + + def status + @server.status if @server + end + + def shutdown + @server.shutdown if @server + end + + def mapping_registry + @router.mapping_registry + end + + def mapping_registry=(mapping_registry) + @router.mapping_registry = mapping_registry + end + + def generate_explicit_type + @router.generate_explicit_type + end + + def generate_explicit_type=(generate_explicit_type) + @router.generate_explicit_type = generate_explicit_type + end + + # servant entry interface + + def add_rpc_request_servant(factory, namespace = @default_namespace) + @router.add_rpc_request_servant(factory, namespace) + end + + def add_rpc_servant(obj, namespace = @default_namespace) + @router.add_rpc_servant(obj, namespace) + end + + def add_request_headerhandler(factory) + @router.add_request_headerhandler(factory) + end + + def add_headerhandler(obj) + @router.add_headerhandler(obj) + end + alias add_rpc_headerhandler add_headerhandler + + # method entry interface + + def add_rpc_method(obj, name, *param) + add_rpc_method_as(obj, name, name, *param) + end + alias add_method add_rpc_method + + def add_rpc_method_as(obj, name, name_as, *param) + qname = XSD::QName.new(@default_namespace, name_as) + soapaction = nil + param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param) + @router.add_rpc_operation(obj, qname, soapaction, name, param_def) + end + alias add_method_as add_rpc_method_as + + def add_document_method(obj, soapaction, name, req_qnames, res_qnames) + param_def = SOAPMethod.create_doc_param_def(req_qnames, res_qnames) + @router.add_document_operation(obj, soapaction, name, param_def) + end + + def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {}) + @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt) + end + + def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {}) + @router.add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt) + end + + def add_document_operation(receiver, soapaction, name, param_def, opt = {}) + @router.add_document_operation(receiver, soapaction, name, param_def, opt) + end + + def add_document_request_operation(factory, soapaction, name, param_def, opt = {}) + @router.add_document_request_operation(factory, soapaction, name, param_def, opt) + end + +private + + def run + @server.start + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/proxy.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/proxy.rb new file mode 100644 index 00000000..7dfda620 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/proxy.rb @@ -0,0 +1,497 @@ +# SOAP4R - RPC Proxy library. +# Copyright (C) 2000, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/soap' +require 'soap/processor' +require 'soap/mapping' +require 'soap/rpc/rpc' +require 'soap/rpc/element' +require 'soap/streamHandler' +require 'soap/mimemessage' + + +module SOAP +module RPC + + +class Proxy + include SOAP + +public + + attr_accessor :soapaction + attr_accessor :mandatorycharset + attr_accessor :allow_unqualified_element + attr_accessor :default_encodingstyle + attr_accessor :generate_explicit_type + attr_reader :headerhandler + attr_reader :streamhandler + + attr_accessor :mapping_registry + attr_accessor :literal_mapping_registry + + attr_reader :operation + + def initialize(endpoint_url, soapaction, options) + @endpoint_url = endpoint_url + @soapaction = soapaction + @options = options + @streamhandler = HTTPStreamHandler.new( + @options["protocol.http"] ||= ::SOAP::Property.new) + @operation = {} + @mandatorycharset = nil + @allow_unqualified_element = true + @default_encodingstyle = nil + @generate_explicit_type = true + @headerhandler = Header::HandlerSet.new + @mapping_registry = nil + @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new + end + + def inspect + "#<#{self.class}:#{@endpoint_url}>" + end + + def endpoint_url + @endpoint_url + end + + def endpoint_url=(endpoint_url) + @endpoint_url = endpoint_url + reset_stream + end + + def reset_stream + @streamhandler.reset(@endpoint_url) + end + + def set_wiredump_file_base(wiredump_file_base) + @streamhandler.wiredump_file_base = wiredump_file_base + end + + def test_loopback_response + @streamhandler.test_loopback_response + end + + def add_rpc_operation(qname, soapaction, name, param_def, opt = {}) + opt[:request_qname] = qname + opt[:request_style] ||= :rpc + opt[:response_style] ||= :rpc + opt[:request_use] ||= :encoded + opt[:response_use] ||= :encoded + @operation[name] = Operation.new(soapaction, param_def, opt) + end + + def add_document_operation(soapaction, name, param_def, opt = {}) + opt[:request_style] ||= :document + opt[:response_style] ||= :document + opt[:request_use] ||= :literal + opt[:response_use] ||= :literal + # default values of these values are unqualified in XML Schema. + # set true for backward compatibility. + unless opt.key?(:elementformdefault) + opt[:elementformdefault] = true + end + unless opt.key?(:attributeformdefault) + opt[:attributeformdefault] = true + end + @operation[name] = Operation.new(soapaction, param_def, opt) + end + + # add_method is for shortcut of typical rpc/encoded method definition. + alias add_method add_rpc_operation + alias add_rpc_method add_rpc_operation + alias add_document_method add_document_operation + + def invoke(req_header, req_body, opt = nil) + opt ||= create_encoding_opt + route(req_header, req_body, opt, opt) + end + + def call(name, *params) + unless op_info = @operation[name] + raise MethodDefinitionError, "method: #{name} not defined" + end + mapping_opt = create_mapping_opt + req_header = create_request_header + req_body = SOAPBody.new( + op_info.request_body(params, @mapping_registry, + @literal_mapping_registry, mapping_opt) + ) + reqopt = create_encoding_opt( + :soapaction => op_info.soapaction || @soapaction, + :envelopenamespace => @options["soap.envelope.requestnamespace"], + :default_encodingstyle => + @default_encodingstyle || op_info.request_default_encodingstyle, + :elementformdefault => op_info.elementformdefault, + :attributeformdefault => op_info.attributeformdefault + ) + resopt = create_encoding_opt( + :envelopenamespace => @options["soap.envelope.responsenamespace"], + :default_encodingstyle => + @default_encodingstyle || op_info.response_default_encodingstyle, + :elementformdefault => op_info.elementformdefault, + :attributeformdefault => op_info.attributeformdefault + ) + env = route(req_header, req_body, reqopt, resopt) + raise EmptyResponseError unless env + receive_headers(env.header) + begin + check_fault(env.body) + rescue ::SOAP::FaultError => e + op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry) + end + op_info.response_obj(env.body, @mapping_registry, + @literal_mapping_registry, mapping_opt) + end + + def route(req_header, req_body, reqopt, resopt) + req_env = ::SOAP::SOAPEnvelope.new(req_header, req_body) + unless reqopt[:envelopenamespace].nil? + set_envelopenamespace(req_env, reqopt[:envelopenamespace]) + end + reqopt[:external_content] = nil + conn_data = marshal(req_env, reqopt) + if ext = reqopt[:external_content] + mime = MIMEMessage.new + ext.each do |k, v| + mime.add_attachment(v.data) + end + mime.add_part(conn_data.send_string + "\r\n") + mime.close + conn_data.send_string = mime.content_str + conn_data.send_contenttype = mime.headers['content-type'].str + end + conn_data = @streamhandler.send(@endpoint_url, conn_data, + reqopt[:soapaction]) + if conn_data.receive_string.empty? + return nil + end + unmarshal(conn_data, resopt) + end + + def check_fault(body) + if body.fault + raise SOAP::FaultError.new(body.fault) + end + end + +private + + def set_envelopenamespace(env, namespace) + env.elename = XSD::QName.new(namespace, env.elename.name) + if env.header + env.header.elename = XSD::QName.new(namespace, env.header.elename.name) + end + if env.body + env.body.elename = XSD::QName.new(namespace, env.body.elename.name) + end + end + + def create_request_header + headers = @headerhandler.on_outbound + if headers.empty? + nil + else + h = ::SOAP::SOAPHeader.new + headers.each do |header| + h.add(header.elename.name, header) + end + h + end + end + + def receive_headers(headers) + @headerhandler.on_inbound(headers) if headers + end + + def marshal(env, opt) + send_string = Processor.marshal(env, opt) + StreamHandler::ConnectionData.new(send_string) + end + + def unmarshal(conn_data, opt) + contenttype = conn_data.receive_contenttype + if /#{MIMEMessage::MultipartContentType}/i =~ contenttype + opt[:external_content] = {} + mime = MIMEMessage.parse("Content-Type: " + contenttype, + conn_data.receive_string) + mime.parts.each do |part| + value = Attachment.new(part.content) + value.contentid = part.contentid + obj = SOAPAttachment.new(value) + opt[:external_content][value.contentid] = obj if value.contentid + end + opt[:charset] = @mandatorycharset || + StreamHandler.parse_media_type(mime.root.headers['content-type'].str) + env = Processor.unmarshal(mime.root.content, opt) + else + opt[:charset] = @mandatorycharset || + ::SOAP::StreamHandler.parse_media_type(contenttype) + env = Processor.unmarshal(conn_data.receive_string, opt) + end + unless env.is_a?(::SOAP::SOAPEnvelope) + raise ResponseFormatError.new( + "response is not a SOAP envelope: #{conn_data.receive_string}") + end + env + end + + def create_header(headers) + header = SOAPHeader.new() + headers.each do |content, mustunderstand, encodingstyle| + header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle)) + end + header + end + + def create_encoding_opt(hash = nil) + opt = {} + opt[:default_encodingstyle] = @default_encodingstyle + opt[:allow_unqualified_element] = @allow_unqualified_element + opt[:generate_explicit_type] = @generate_explicit_type + opt[:no_indent] = @options["soap.envelope.no_indent"] + opt[:use_numeric_character_reference] = + @options["soap.envelope.use_numeric_character_reference"] + opt.update(hash) if hash + opt + end + + def create_mapping_opt(hash = nil) + opt = { + :external_ces => @options["soap.mapping.external_ces"] + } + opt.update(hash) if hash + opt + end + + class Operation + attr_reader :soapaction + attr_reader :request_style + attr_reader :response_style + attr_reader :request_use + attr_reader :response_use + attr_reader :elementformdefault + attr_reader :attributeformdefault + + def initialize(soapaction, param_def, opt) + @soapaction = soapaction + @request_style = opt[:request_style] + @response_style = opt[:response_style] + @request_use = opt[:request_use] + @response_use = opt[:response_use] + # set nil(unqualified) by default + @elementformdefault = opt[:elementformdefault] + @attributeformdefault = opt[:attributeformdefault] + check_style(@request_style) + check_style(@response_style) + check_use(@request_use) + check_use(@response_use) + if @request_style == :rpc + @rpc_request_qname = opt[:request_qname] + if @rpc_request_qname.nil? + raise MethodDefinitionError.new("rpc_request_qname must be given") + end + @rpc_method_factory = + RPC::SOAPMethodRequest.new(@rpc_request_qname, param_def, @soapaction) + else + @doc_request_qnames = [] + @doc_request_qualified = [] + @doc_response_qnames = [] + @doc_response_qualified = [] + param_def.each do |inout, paramname, typeinfo, eleinfo| + klass_not_used, nsdef, namedef = typeinfo + qualified = eleinfo + if namedef.nil? + raise MethodDefinitionError.new("qname must be given") + end + case inout + when SOAPMethod::IN + @doc_request_qnames << XSD::QName.new(nsdef, namedef) + @doc_request_qualified << qualified + when SOAPMethod::OUT + @doc_response_qnames << XSD::QName.new(nsdef, namedef) + @doc_response_qualified << qualified + else + raise MethodDefinitionError.new( + "illegal inout definition for document style: #{inout}") + end + end + end + end + + def request_default_encodingstyle + (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace + end + + def response_default_encodingstyle + (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace + end + + def request_body(values, mapping_registry, literal_mapping_registry, opt) + if @request_style == :rpc + request_rpc(values, mapping_registry, literal_mapping_registry, opt) + else + request_doc(values, mapping_registry, literal_mapping_registry, opt) + end + end + + def response_obj(body, mapping_registry, literal_mapping_registry, opt) + if @response_style == :rpc + response_rpc(body, mapping_registry, literal_mapping_registry, opt) + else + response_doc(body, mapping_registry, literal_mapping_registry, opt) + end + end + + def raise_fault(e, mapping_registry, literal_mapping_registry) + if @response_style == :rpc + Mapping.fault2exception(e, mapping_registry) + else + Mapping.fault2exception(e, literal_mapping_registry) + end + end + + private + + def check_style(style) + unless [:rpc, :document].include?(style) + raise MethodDefinitionError.new("unknown style: #{style}") + end + end + + def check_use(use) + unless [:encoded, :literal].include?(use) + raise MethodDefinitionError.new("unknown use: #{use}") + end + end + + def request_rpc(values, mapping_registry, literal_mapping_registry, opt) + if @request_use == :encoded + request_rpc_enc(values, mapping_registry, opt) + else + request_rpc_lit(values, literal_mapping_registry, opt) + end + end + + def request_doc(values, mapping_registry, literal_mapping_registry, opt) + if @request_use == :encoded + request_doc_enc(values, mapping_registry, opt) + else + request_doc_lit(values, literal_mapping_registry, opt) + end + end + + def request_rpc_enc(values, mapping_registry, opt) + method = @rpc_method_factory.dup + names = method.input_params + obj = create_request_obj(names, values) + soap = Mapping.obj2soap(obj, mapping_registry, @rpc_request_qname, opt) + method.set_param(soap) + method + end + + def request_rpc_lit(values, mapping_registry, opt) + method = @rpc_method_factory.dup + params = {} + idx = 0 + method.input_params.each do |name| + params[name] = Mapping.obj2soap(values[idx], mapping_registry, + XSD::QName.new(nil, name), opt) + idx += 1 + end + method.set_param(params) + method + end + + def request_doc_enc(values, mapping_registry, opt) + (0...values.size).collect { |idx| + ele = Mapping.obj2soap(values[idx], mapping_registry, nil, opt) + ele.elename = @doc_request_qnames[idx] + ele + } + end + + def request_doc_lit(values, mapping_registry, opt) + (0...values.size).collect { |idx| + ele = Mapping.obj2soap(values[idx], mapping_registry, + @doc_request_qnames[idx], opt) + ele.encodingstyle = LiteralNamespace + if ele.respond_to?(:qualified) + ele.qualified = @doc_request_qualified[idx] + end + ele + } + end + + def response_rpc(body, mapping_registry, literal_mapping_registry, opt) + if @response_use == :encoded + response_rpc_enc(body, mapping_registry, opt) + else + response_rpc_lit(body, literal_mapping_registry, opt) + end + end + + def response_doc(body, mapping_registry, literal_mapping_registry, opt) + if @response_use == :encoded + return *response_doc_enc(body, mapping_registry, opt) + else + return *response_doc_lit(body, literal_mapping_registry, opt) + end + end + + def response_rpc_enc(body, mapping_registry, opt) + ret = nil + if body.response + ret = Mapping.soap2obj(body.response, mapping_registry, + @rpc_method_factory.retval_class_name, opt) + end + if body.outparams + outparams = body.outparams.collect { |outparam| + Mapping.soap2obj(outparam, mapping_registry, nil, opt) + } + [ret].concat(outparams) + else + ret + end + end + + def response_rpc_lit(body, mapping_registry, opt) + body.root_node.collect { |key, value| + Mapping.soap2obj(value, mapping_registry, + @rpc_method_factory.retval_class_name, opt) + } + end + + def response_doc_enc(body, mapping_registry, opt) + body.collect { |key, value| + Mapping.soap2obj(value, mapping_registry, nil, opt) + } + end + + def response_doc_lit(body, mapping_registry, opt) + body.collect { |key, value| + Mapping.soap2obj(value, mapping_registry) + } + end + + def create_request_obj(names, params) + o = Object.new + idx = 0 + while idx < params.length + o.instance_variable_set('@' + names[idx], params[idx]) + idx += 1 + end + o + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/router.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/router.rb new file mode 100644 index 00000000..71c6eb62 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/router.rb @@ -0,0 +1,594 @@ +# SOAP4R - RPC Routing library +# Copyright (C) 2001, 2002, 2004, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/soap' +require 'soap/processor' +require 'soap/mapping' +require 'soap/mapping/wsdlliteralregistry' +require 'soap/rpc/rpc' +require 'soap/rpc/element' +require 'soap/streamHandler' +require 'soap/mimemessage' +require 'soap/header/handlerset' + + +module SOAP +module RPC + + +class Router + include SOAP + + attr_reader :actor + attr_accessor :mapping_registry + attr_accessor :literal_mapping_registry + attr_accessor :generate_explicit_type + attr_accessor :external_ces + + def initialize(actor) + @actor = actor + @mapping_registry = nil + @headerhandler = Header::HandlerSet.new + @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new + @generate_explicit_type = true + @external_ces = nil + @operation_by_soapaction = {} + @operation_by_qname = {} + @headerhandlerfactory = [] + end + + ### + ## header handler interface + # + def add_request_headerhandler(factory) + unless factory.respond_to?(:create) + raise TypeError.new("factory must respond to 'create'") + end + @headerhandlerfactory << factory + end + + def add_headerhandler(handler) + @headerhandler.add(handler) + end + + ### + ## servant definition interface + # + def add_rpc_request_servant(factory, namespace) + unless factory.respond_to?(:create) + raise TypeError.new("factory must respond to 'create'") + end + obj = factory.create # a dummy instance for introspection + ::SOAP::RPC.defined_methods(obj).each do |name| + begin + qname = XSD::QName.new(namespace, name) + param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name) + opt = create_styleuse_option(:rpc, :encoded) + add_rpc_request_operation(factory, qname, nil, name, param_def, opt) + rescue SOAP::RPC::MethodDefinitionError => e + p e if $DEBUG + end + end + end + + def add_rpc_servant(obj, namespace) + ::SOAP::RPC.defined_methods(obj).each do |name| + begin + qname = XSD::QName.new(namespace, name) + param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name) + opt = create_styleuse_option(:rpc, :encoded) + add_rpc_operation(obj, qname, nil, name, param_def, opt) + rescue SOAP::RPC::MethodDefinitionError => e + p e if $DEBUG + end + end + end + alias add_servant add_rpc_servant + + ### + ## operation definition interface + # + def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {}) + ensure_styleuse_option(opt, :rpc, :encoded) + opt[:request_qname] = qname + op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def, + opt) + if opt[:request_style] != :rpc + raise RPCRoutingError.new("illegal request_style given") + end + assign_operation(soapaction, qname, op) + end + alias add_method add_rpc_operation + alias add_rpc_method add_rpc_operation + + def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {}) + ensure_styleuse_option(opt, :rpc, :encoded) + opt[:request_qname] = qname + op = RequestScopeOperation.new(soapaction, factory, name, param_def, opt) + if opt[:request_style] != :rpc + raise RPCRoutingError.new("illegal request_style given") + end + assign_operation(soapaction, qname, op) + end + + def add_document_operation(receiver, soapaction, name, param_def, opt = {}) + # + # adopt workaround for doc/lit wrapper method + # (you should consider to simply use rpc/lit service) + # + #unless soapaction + # raise RPCRoutingError.new("soapaction is a must for document method") + #end + ensure_styleuse_option(opt, :document, :literal) + op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def, + opt) + if opt[:request_style] != :document + raise RPCRoutingError.new("illegal request_style given") + end + assign_operation(soapaction, first_input_part_qname(param_def), op) + end + alias add_document_method add_document_operation + + def add_document_request_operation(factory, soapaction, name, param_def, opt = {}) + # + # adopt workaround for doc/lit wrapper method + # (you should consider to simply use rpc/lit service) + # + #unless soapaction + # raise RPCRoutingError.new("soapaction is a must for document method") + #end + ensure_styleuse_option(opt, :document, :literal) + op = RequestScopeOperation.new(soapaction, receiver, name, param_def, opt) + if opt[:request_style] != :document + raise RPCRoutingError.new("illegal request_style given") + end + assign_operation(soapaction, first_input_part_qname(param_def), op) + end + + def route(conn_data) + # we cannot set request_default_encodingsyle before parsing the content. + env = unmarshal(conn_data) + if env.nil? + raise ArgumentError.new("illegal SOAP marshal format") + end + op = lookup_operation(conn_data.soapaction, env.body) + headerhandler = @headerhandler.dup + @headerhandlerfactory.each do |f| + headerhandler.add(f.create) + end + receive_headers(headerhandler, env.header) + soap_response = default_encodingstyle = nil + begin + soap_response = + op.call(env.body, @mapping_registry, @literal_mapping_registry, + create_mapping_opt) + default_encodingstyle = op.response_default_encodingstyle + rescue Exception + soap_response = fault($!) + default_encodingstyle = nil + end + conn_data.is_fault = true if soap_response.is_a?(SOAPFault) + header = call_headers(headerhandler) + body = SOAPBody.new(soap_response) + env = SOAPEnvelope.new(header, body) + marshal(conn_data, env, default_encodingstyle) + end + + # Create fault response string. + def create_fault_response(e) + env = SOAPEnvelope.new(SOAPHeader.new, SOAPBody.new(fault(e))) + opt = {} + opt[:external_content] = nil + response_string = Processor.marshal(env, opt) + conn_data = StreamHandler::ConnectionData.new(response_string) + conn_data.is_fault = true + if ext = opt[:external_content] + mimeize(conn_data, ext) + end + conn_data + end + +private + + def first_input_part_qname(param_def) + param_def.each do |inout, paramname, typeinfo| + if inout == SOAPMethod::IN + klass, nsdef, namedef = typeinfo + return XSD::QName.new(nsdef, namedef) + end + end + nil + end + + def create_styleuse_option(style, use) + opt = {} + opt[:request_style] = opt[:response_style] = style + opt[:request_use] = opt[:response_use] = use + opt + end + + def ensure_styleuse_option(opt, style, use) + opt[:request_style] ||= style + opt[:response_style] ||= style + opt[:request_use] ||= use + opt[:response_use] ||= use + end + + def assign_operation(soapaction, qname, op) + assigned = false + if soapaction and !soapaction.empty? + @operation_by_soapaction[soapaction] = op + assigned = true + end + if qname + @operation_by_qname[qname] = op + assigned = true + end + unless assigned + raise RPCRoutingError.new("cannot assign operation") + end + end + + def lookup_operation(soapaction, body) + if op = @operation_by_soapaction[soapaction] + return op + end + qname = body.root_node.elename + if op = @operation_by_qname[qname] + return op + end + if soapaction + raise RPCRoutingError.new( + "operation: #{soapaction} #{qname} not supported") + else + raise RPCRoutingError.new("operation: #{qname} not supported") + end + end + + def call_headers(headerhandler) + headers = headerhandler.on_outbound + if headers.empty? + nil + else + h = ::SOAP::SOAPHeader.new + headers.each do |header| + h.add(header.elename.name, header) + end + h + end + end + + def receive_headers(headerhandler, headers) + headerhandler.on_inbound(headers) if headers + end + + def unmarshal(conn_data) + opt = {} + contenttype = conn_data.receive_contenttype + if /#{MIMEMessage::MultipartContentType}/i =~ contenttype + opt[:external_content] = {} + mime = MIMEMessage.parse("Content-Type: " + contenttype, + conn_data.receive_string) + mime.parts.each do |part| + value = Attachment.new(part.content) + value.contentid = part.contentid + obj = SOAPAttachment.new(value) + opt[:external_content][value.contentid] = obj if value.contentid + end + opt[:charset] = + StreamHandler.parse_media_type(mime.root.headers['content-type'].str) + env = Processor.unmarshal(mime.root.content, opt) + else + opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype) + env = Processor.unmarshal(conn_data.receive_string, opt) + end + charset = opt[:charset] + conn_data.send_contenttype = "text/xml; charset=\"#{charset}\"" + env + end + + def marshal(conn_data, env, default_encodingstyle = nil) + opt = {} + opt[:external_content] = nil + opt[:default_encodingstyle] = default_encodingstyle + opt[:generate_explicit_type] = @generate_explicit_type + response_string = Processor.marshal(env, opt) + conn_data.send_string = response_string + if ext = opt[:external_content] + mimeize(conn_data, ext) + end + conn_data + end + + def mimeize(conn_data, ext) + mime = MIMEMessage.new + ext.each do |k, v| + mime.add_attachment(v.data) + end + mime.add_part(conn_data.send_string + "\r\n") + mime.close + conn_data.send_string = mime.content_str + conn_data.send_contenttype = mime.headers['content-type'].str + conn_data + end + + # Create fault response. + def fault(e) + detail = Mapping::SOAPException.new(e) + SOAPFault.new( + SOAPString.new('Server'), + SOAPString.new(e.to_s), + SOAPString.new(@actor), + Mapping.obj2soap(detail, @mapping_registry)) + end + + def create_mapping_opt + { :external_ces => @external_ces } + end + + class Operation + attr_reader :name + attr_reader :soapaction + attr_reader :request_style + attr_reader :response_style + attr_reader :request_use + attr_reader :response_use + + def initialize(soapaction, name, param_def, opt) + @soapaction = soapaction + @name = name + @request_style = opt[:request_style] + @response_style = opt[:response_style] + @request_use = opt[:request_use] + @response_use = opt[:response_use] + check_style(@request_style) + check_style(@response_style) + check_use(@request_use) + check_use(@response_use) + if @response_style == :rpc + request_qname = opt[:request_qname] or raise + @rpc_method_factory = + RPC::SOAPMethodRequest.new(request_qname, param_def, @soapaction) + @rpc_response_qname = opt[:response_qname] + else + @doc_request_qnames = [] + @doc_request_qualified = [] + @doc_response_qnames = [] + @doc_response_qualified = [] + param_def.each do |inout, paramname, typeinfo, eleinfo| + klass, nsdef, namedef = typeinfo + qualified = eleinfo + case inout + when SOAPMethod::IN + @doc_request_qnames << XSD::QName.new(nsdef, namedef) + @doc_request_qualified << qualified + when SOAPMethod::OUT + @doc_response_qnames << XSD::QName.new(nsdef, namedef) + @doc_response_qualified << qualified + else + raise ArgumentError.new( + "illegal inout definition for document style: #{inout}") + end + end + end + end + + def request_default_encodingstyle + (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace + end + + def response_default_encodingstyle + (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace + end + + def call(body, mapping_registry, literal_mapping_registry, opt) + if @request_style == :rpc + values = request_rpc(body, mapping_registry, literal_mapping_registry, + opt) + else + values = request_document(body, mapping_registry, + literal_mapping_registry, opt) + end + result = receiver.method(@name.intern).call(*values) + return result if result.is_a?(SOAPFault) + if @response_style == :rpc + response_rpc(result, mapping_registry, literal_mapping_registry, opt) + else + response_doc(result, mapping_registry, literal_mapping_registry, opt) + end + end + + private + + def receiver + raise NotImplementedError.new('must be defined in derived class') + end + + def request_rpc(body, mapping_registry, literal_mapping_registry, opt) + request = body.request + unless request.is_a?(SOAPStruct) + raise RPCRoutingError.new("not an RPC style") + end + if @request_use == :encoded + request_rpc_enc(request, mapping_registry, opt) + else + request_rpc_lit(request, literal_mapping_registry, opt) + end + end + + def request_document(body, mapping_registry, literal_mapping_registry, opt) + # ToDo: compare names with @doc_request_qnames + if @request_use == :encoded + request_doc_enc(body, mapping_registry, opt) + else + request_doc_lit(body, literal_mapping_registry, opt) + end + end + + def request_rpc_enc(request, mapping_registry, opt) + param = Mapping.soap2obj(request, mapping_registry, nil, opt) + request.collect { |key, value| + param[key] + } + end + + def request_rpc_lit(request, mapping_registry, opt) + request.collect { |key, value| + Mapping.soap2obj(value, mapping_registry, nil, opt) + } + end + + def request_doc_enc(body, mapping_registry, opt) + body.collect { |key, value| + Mapping.soap2obj(value, mapping_registry, nil, opt) + } + end + + def request_doc_lit(body, mapping_registry, opt) + body.collect { |key, value| + Mapping.soap2obj(value, mapping_registry, nil, opt) + } + end + + def response_rpc(result, mapping_registry, literal_mapping_registry, opt) + if @response_use == :encoded + response_rpc_enc(result, mapping_registry, opt) + else + response_rpc_lit(result, literal_mapping_registry, opt) + end + end + + def response_doc(result, mapping_registry, literal_mapping_registry, opt) + if @doc_response_qnames.size == 1 and !result.is_a?(Array) + result = [result] + end + if result.size != @doc_response_qnames.size + raise "required #{@doc_response_qnames.size} responses " + + "but #{result.size} given" + end + if @response_use == :encoded + response_doc_enc(result, mapping_registry, opt) + else + response_doc_lit(result, literal_mapping_registry, opt) + end + end + + def response_rpc_enc(result, mapping_registry, opt) + soap_response = + @rpc_method_factory.create_method_response(@rpc_response_qname) + if soap_response.have_outparam? + unless result.is_a?(Array) + raise RPCRoutingError.new("out parameter was not returned") + end + outparams = {} + i = 1 + soap_response.output_params.each do |outparam| + outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry, + nil, opt) + i += 1 + end + soap_response.set_outparam(outparams) + soap_response.retval = Mapping.obj2soap(result[0], mapping_registry, + nil, opt) + else + soap_response.retval = Mapping.obj2soap(result, mapping_registry, nil, + opt) + end + soap_response + end + + def response_rpc_lit(result, mapping_registry, opt) + soap_response = + @rpc_method_factory.create_method_response(@rpc_response_qname) + if soap_response.have_outparam? + unless result.is_a?(Array) + raise RPCRoutingError.new("out parameter was not returned") + end + outparams = {} + i = 1 + soap_response.output_params.each do |outparam| + outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry, + XSD::QName.new(nil, outparam), opt) + i += 1 + end + soap_response.set_outparam(outparams) + soap_response.retval = Mapping.obj2soap(result[0], mapping_registry, + XSD::QName.new(nil, soap_response.elename), opt) + else + soap_response.retval = Mapping.obj2soap(result, mapping_registry, + XSD::QName.new(nil, soap_response.elename), opt) + end + soap_response + end + + def response_doc_enc(result, mapping_registry, opt) + (0...result.size).collect { |idx| + ele = Mapping.obj2soap(result[idx], mapping_registry, nil, opt) + ele.elename = @doc_response_qnames[idx] + ele + } + end + + def response_doc_lit(result, mapping_registry, opt) + (0...result.size).collect { |idx| + ele = Mapping.obj2soap(result[idx], mapping_registry, + @doc_response_qnames[idx]) + ele.encodingstyle = LiteralNamespace + if ele.respond_to?(:qualified) + ele.qualified = @doc_response_qualified[idx] + end + ele + } + end + + def check_style(style) + unless [:rpc, :document].include?(style) + raise ArgumentError.new("unknown style: #{style}") + end + end + + def check_use(use) + unless [:encoded, :literal].include?(use) + raise ArgumentError.new("unknown use: #{use}") + end + end + end + + class ApplicationScopeOperation < Operation + def initialize(soapaction, receiver, name, param_def, opt) + super(soapaction, name, param_def, opt) + @receiver = receiver + end + + private + + def receiver + @receiver + end + end + + class RequestScopeOperation < Operation + def initialize(soapaction, receiver_factory, name, param_def, opt) + super(soapaction, name, param_def, opt) + unless receiver_factory.respond_to?(:create) + raise TypeError.new("factory must respond to 'create'") + end + @receiver_factory = receiver_factory + end + + private + + def receiver + @receiver_factory.create + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/rpc.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/rpc.rb new file mode 100644 index 00000000..a48b525d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/rpc.rb @@ -0,0 +1,25 @@ +# SOAP4R - RPC utility. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module SOAP + + +module RPC + ServerException = Mapping::MappedException + + def self.defined_methods(obj) + if obj.is_a?(Module) + obj.methods - Module.methods + else + obj.methods - Object.instance_methods(true) + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/soaplet.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/soaplet.rb new file mode 100644 index 00000000..7cccdd3e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/soaplet.rb @@ -0,0 +1,162 @@ +# SOAP4R - SOAP handler servlet for WEBrick +# Copyright (C) 2001-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'webrick/httpservlet/abstract' +require 'webrick/httpstatus' +require 'soap/rpc/router' +require 'soap/streamHandler' +begin + require 'stringio' + require 'zlib' +rescue LoadError + warn("Loading stringio or zlib failed. No gzipped response supported.") if $DEBUG +end + + +warn("Overriding WEBrick::Log#debug") if $DEBUG +require 'webrick/log' +module WEBrick + class Log < BasicLog + alias __debug debug + def debug(msg = nil) + if block_given? and msg.nil? + __debug(yield) + else + __debug(msg) + end + end + end +end + + +module SOAP +module RPC + + +class SOAPlet < WEBrick::HTTPServlet::AbstractServlet +public + attr_reader :options + + def initialize(router = nil) + @router = router || ::SOAP::RPC::Router.new(self.class.name) + @options = {} + @config = {} + end + + # for backward compatibility + def app_scope_router + @router + end + + # for backward compatibility + def add_servant(obj, namespace) + @router.add_rpc_servant(obj, namespace) + end + + def allow_content_encoding_gzip=(allow) + @options[:allow_content_encoding_gzip] = allow + end + + ### + ## Servlet interfaces for WEBrick. + # + def get_instance(config, *options) + @config = config + self + end + + def require_path_info? + false + end + + def do_GET(req, res) + res.header['Allow'] = 'POST' + raise WEBrick::HTTPStatus::MethodNotAllowed, "GET request not allowed" + end + + def do_POST(req, res) + logger.debug { "SOAP request: " + req.body } if logger + begin + conn_data = ::SOAP::StreamHandler::ConnectionData.new + setup_req(conn_data, req) + @router.external_ces = @options[:external_ces] + conn_data = @router.route(conn_data) + setup_res(conn_data, req, res) + rescue Exception => e + conn_data = @router.create_fault_response(e) + res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR + res.body = conn_data.send_string + res['content-type'] = conn_data.send_contenttype || "text/xml" + end + if res.body.is_a?(IO) + res.chunked = true + logger.debug { "SOAP response: (chunked response not logged)" } if logger + else + logger.debug { "SOAP response: " + res.body } if logger + end + end + +private + + def logger + @config[:Logger] + end + + def setup_req(conn_data, req) + conn_data.receive_string = req.body + conn_data.receive_contenttype = req['content-type'] + conn_data.soapaction = parse_soapaction(req.meta_vars['HTTP_SOAPACTION']) + end + + def setup_res(conn_data, req, res) + res['content-type'] = conn_data.send_contenttype + if conn_data.is_fault + res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR + end + if outstring = encode_gzip(req, conn_data.send_string) + res['content-encoding'] = 'gzip' + res['content-length'] = outstring.size + res.body = outstring + else + res.body = conn_data.send_string + end + end + + def parse_soapaction(soapaction) + if !soapaction.nil? and !soapaction.empty? + if /^"(.+)"$/ =~ soapaction + return $1 + end + end + nil + end + + def encode_gzip(req, outstring) + unless encode_gzip?(req) + return nil + end + begin + ostream = StringIO.new + gz = Zlib::GzipWriter.new(ostream) + gz.write(outstring) + ostream.string + ensure + gz.close + end + end + + def encode_gzip?(req) + @options[:allow_content_encoding_gzip] and defined?(::Zlib) and + req['accept-encoding'] and + req['accept-encoding'].split(/,\s*/).include?('gzip') + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/standaloneServer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/standaloneServer.rb new file mode 100644 index 00000000..080343ba --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/rpc/standaloneServer.rb @@ -0,0 +1,43 @@ +# SOAP4R - WEBrick Server +# Copyright (C) 2003 by NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/rpc/httpserver' + + +module SOAP +module RPC + + +class StandaloneServer < HTTPServer + def initialize(appname, default_namespace, host = "0.0.0.0", port = 8080) + @appname = appname + @default_namespace = default_namespace + @host = host + @port = port + super(create_config) + end + + alias add_servant add_rpc_servant + alias add_headerhandler add_rpc_headerhandler + +private + + def create_config + { + :BindAddress => @host, + :Port => @port, + :AccessLog => [], + :SOAPDefaultNamespace => @default_namespace, + :SOAPHTTPServerApplicationName => @appname, + } + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/soap.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/soap.rb new file mode 100644 index 00000000..12e09ecc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/soap.rb @@ -0,0 +1,140 @@ +# soap/soap.rb: SOAP4R - Base definitions. +# Copyright (C) 2000-2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'xsd/charset' + + +module SOAP + + +VERSION = Version = '1.5.5' +PropertyName = 'soap/property' + +EnvelopeNamespace = 'http://schemas.xmlsoap.org/soap/envelope/' +EncodingNamespace = 'http://schemas.xmlsoap.org/soap/encoding/' +LiteralNamespace = 'http://xml.apache.org/xml-soap/literalxml' + +NextActor = 'http://schemas.xmlsoap.org/soap/actor/next' + +EleEnvelope = 'Envelope' +EleHeader = 'Header' +EleBody = 'Body' +EleFault = 'Fault' +EleFaultString = 'faultstring' +EleFaultActor = 'faultactor' +EleFaultCode = 'faultcode' +EleFaultDetail = 'detail' + +AttrMustUnderstand = 'mustUnderstand' +AttrEncodingStyle = 'encodingStyle' +AttrActor = 'actor' +AttrRoot = 'root' +AttrArrayType = 'arrayType' +AttrOffset = 'offset' +AttrPosition = 'position' +ValueArray = 'Array' + +EleEnvelopeName = XSD::QName.new(EnvelopeNamespace, EleEnvelope).freeze +EleHeaderName = XSD::QName.new(EnvelopeNamespace, EleHeader).freeze +EleBodyName = XSD::QName.new(EnvelopeNamespace, EleBody).freeze +EleFaultName = XSD::QName.new(EnvelopeNamespace, EleFault).freeze +EleFaultStringName = XSD::QName.new(nil, EleFaultString).freeze +EleFaultActorName = XSD::QName.new(nil, EleFaultActor).freeze +EleFaultCodeName = XSD::QName.new(nil, EleFaultCode).freeze +EleFaultDetailName = XSD::QName.new(nil, EleFaultDetail).freeze +AttrMustUnderstandName = XSD::QName.new(EnvelopeNamespace, AttrMustUnderstand).freeze +AttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle).freeze +AttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot).freeze +AttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType).freeze +AttrOffsetName = XSD::QName.new(EncodingNamespace, AttrOffset).freeze +AttrPositionName = XSD::QName.new(EncodingNamespace, AttrPosition).freeze +ValueArrayName = XSD::QName.new(EncodingNamespace, ValueArray).freeze + +Base64Literal = 'base64' + +SOAPNamespaceTag = 'env' +XSDNamespaceTag = 'xsd' +XSINamespaceTag = 'xsi' + +MediaType = 'text/xml' + +class Error < StandardError; end + +class StreamError < Error; end +class HTTPStreamError < StreamError; end +class PostUnavailableError < HTTPStreamError; end +class MPostUnavailableError < HTTPStreamError; end + +class ArrayIndexOutOfBoundsError < Error; end +class ArrayStoreError < Error; end + +class RPCRoutingError < Error; end +class EmptyResponseError < Error; end +class ResponseFormatError < Error; end + +class UnhandledMustUnderstandHeaderError < Error; end + +class FaultError < Error + attr_reader :faultcode + attr_reader :faultstring + attr_reader :faultactor + attr_accessor :detail + + def initialize(fault) + @faultcode = fault.faultcode + @faultstring = fault.faultstring + @faultactor = fault.faultactor + @detail = fault.detail + super(self.to_s) + end + + def to_s + str = nil + if @faultstring and @faultstring.respond_to?('data') + str = @faultstring.data + end + str || '(No faultstring)' + end +end + + +module Env + def self.getenv(name) + ENV[name.downcase] || ENV[name.upcase] + end + + use_proxy = getenv('soap_use_proxy') == 'on' + HTTP_PROXY = use_proxy ? getenv('http_proxy') : nil + NO_PROXY = use_proxy ? getenv('no_proxy') : nil +end + + +end + + +unless Object.respond_to?(:instance_variable_get) + class Object + def instance_variable_get(ivarname) + instance_eval(ivarname) + end + + def instance_variable_set(ivarname, value) + instance_eval("#{ivarname} = value") + end + end +end + + +unless Kernel.respond_to?(:warn) + module Kernel + def warn(msg) + STDERR.puts(msg + "\n") unless $VERBOSE.nil? + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/streamHandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/streamHandler.rb new file mode 100644 index 00000000..672396ec --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/streamHandler.rb @@ -0,0 +1,229 @@ +# SOAP4R - Stream handler. +# Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/soap' +require 'soap/httpconfigloader' +begin + require 'stringio' + require 'zlib' +rescue LoadError + warn("Loading stringio or zlib failed. No gzipped response support.") if $DEBUG +end + + +module SOAP + + +class StreamHandler + RUBY_VERSION_STRING = "ruby #{ RUBY_VERSION } (#{ RUBY_RELEASE_DATE }) [#{ RUBY_PLATFORM }]" + + class ConnectionData + attr_accessor :send_string + attr_accessor :send_contenttype + attr_accessor :receive_string + attr_accessor :receive_contenttype + attr_accessor :is_fault + attr_accessor :soapaction + + def initialize(send_string = nil) + @send_string = send_string + @send_contenttype = nil + @receive_string = nil + @receive_contenttype = nil + @is_fault = false + @soapaction = nil + end + end + + def self.parse_media_type(str) + if /^#{ MediaType }(?:\s*;\s*charset=([^"]+|"[^"]+"))?$/i !~ str + return nil + end + charset = $1 + charset.gsub!(/"/, '') if charset + charset || 'us-ascii' + end + + def self.create_media_type(charset) + "#{ MediaType }; charset=#{ charset }" + end +end + + +class HTTPStreamHandler < StreamHandler + include SOAP + + begin + require 'http-access2' + if HTTPAccess2::VERSION < "2.0" + raise LoadError.new("http-access/2.0 or later is required.") + end + Client = HTTPAccess2::Client + RETRYABLE = true + rescue LoadError + warn("Loading http-access2 failed. Net/http is used.") if $DEBUG + require 'soap/netHttpClient' + Client = SOAP::NetHttpClient + RETRYABLE = false + end + + +public + + attr_reader :client + attr_accessor :wiredump_file_base + + MAX_RETRY_COUNT = 10 # [times] + + def initialize(options) + super() + @client = Client.new(nil, "SOAP4R/#{ Version }") + @wiredump_file_base = nil + @charset = @wiredump_dev = nil + @options = options + set_options + @client.debug_dev = @wiredump_dev + @cookie_store = nil + @accept_encoding_gzip = false + end + + def test_loopback_response + @client.test_loopback_response + end + + def accept_encoding_gzip=(allow) + @accept_encoding_gzip = allow + end + + def inspect + "#<#{self.class}>" + end + + def send(endpoint_url, conn_data, soapaction = nil, charset = @charset) + conn_data.soapaction ||= soapaction # for backward conpatibility + send_post(endpoint_url, conn_data, charset) + end + + def reset(endpoint_url = nil) + if endpoint_url.nil? + @client.reset_all + else + @client.reset(endpoint_url) + end + @client.save_cookie_store if @cookie_store + end + +private + + def set_options + HTTPConfigLoader.set_options(@client, @options) + @charset = @options["charset"] || XSD::Charset.xml_encoding_label + @options.add_hook("charset") do |key, value| + @charset = value + end + @wiredump_dev = @options["wiredump_dev"] + @options.add_hook("wiredump_dev") do |key, value| + @wiredump_dev = value + @client.debug_dev = @wiredump_dev + end + set_cookie_store_file(@options["cookie_store_file"]) + @options.add_hook("cookie_store_file") do |key, value| + set_cookie_store_file(value) + end + ssl_config = @options["ssl_config"] + basic_auth = @options["basic_auth"] + @options.lock(true) + ssl_config.unlock + basic_auth.unlock + end + + def set_cookie_store_file(value) + value = nil if value and value.empty? + @cookie_store = value + @client.set_cookie_store(@cookie_store) if @cookie_store + end + + def send_post(endpoint_url, conn_data, charset) + conn_data.send_contenttype ||= StreamHandler.create_media_type(charset) + + if @wiredump_file_base + filename = @wiredump_file_base + '_request.xml' + f = File.open(filename, "w") + f << conn_data.send_string + f.close + end + + extra = {} + extra['Content-Type'] = conn_data.send_contenttype + extra['SOAPAction'] = "\"#{ conn_data.soapaction }\"" + extra['Accept-Encoding'] = 'gzip' if send_accept_encoding_gzip? + send_string = conn_data.send_string + @wiredump_dev << "Wire dump:\n\n" if @wiredump_dev + begin + retry_count = 0 + while true + res = @client.post(endpoint_url, send_string, extra) + if RETRYABLE and HTTP::Status.redirect?(res.status) + retry_count += 1 + if retry_count >= MAX_RETRY_COUNT + raise HTTPStreamError.new("redirect count exceeded") + end + endpoint_url = res.header["location"][0] + puts "redirected to #{endpoint_url}" if $DEBUG + else + break + end + end + rescue + @client.reset(endpoint_url) + raise + end + @wiredump_dev << "\n\n" if @wiredump_dev + receive_string = res.content + if @wiredump_file_base + filename = @wiredump_file_base + '_response.xml' + f = File.open(filename, "w") + f << receive_string + f.close + end + case res.status + when 405 + raise PostUnavailableError.new("#{ res.status }: #{ res.reason }") + when 200, 500 + # Nothing to do. + else + raise HTTPStreamError.new("#{ res.status }: #{ res.reason }") + end + if res.respond_to?(:header) and !res.header['content-encoding'].empty? and + res.header['content-encoding'][0].downcase == 'gzip' + receive_string = decode_gzip(receive_string) + end + conn_data.receive_string = receive_string + conn_data.receive_contenttype = res.contenttype + conn_data + end + + def send_accept_encoding_gzip? + @accept_encoding_gzip and defined?(::Zlib) + end + + def decode_gzip(instring) + unless send_accept_encoding_gzip? + raise HTTPStreamError.new("Gzipped response content.") + end + begin + gz = Zlib::GzipReader.new(StringIO.new(instring)) + gz.read + ensure + gz.close + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/wsdlDriver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/wsdlDriver.rb new file mode 100644 index 00000000..eba9608d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/soap/wsdlDriver.rb @@ -0,0 +1,575 @@ +# SOAP4R - SOAP WSDL driver +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/parser' +require 'wsdl/importer' +require 'xsd/qname' +require 'xsd/codegen/gensupport' +require 'soap/mapping/wsdlencodedregistry' +require 'soap/mapping/wsdlliteralregistry' +require 'soap/rpc/driver' +require 'wsdl/soap/methodDefCreator' + + +module SOAP + + +class WSDLDriverFactory + class FactoryError < StandardError; end + + attr_reader :wsdl + + def initialize(wsdl) + @wsdl = import(wsdl) + @methoddefcreator = WSDL::SOAP::MethodDefCreator.new(@wsdl) + end + + def inspect + "#<#{self.class}:#{@wsdl.name}>" + end + + def create_rpc_driver(servicename = nil, portname = nil) + port = find_port(servicename, portname) + drv = SOAP::RPC::Driver.new(port.soap_address.location) + init_driver(drv, port) + add_operation(drv, port) + drv + end + + # depricated old interface + def create_driver(servicename = nil, portname = nil) + warn("WSDLDriverFactory#create_driver is depricated. Use create_rpc_driver instead.") + port = find_port(servicename, portname) + WSDLDriver.new(@wsdl, port, nil) + end + + # Backward compatibility. + alias createDriver create_driver + +private + + def find_port(servicename = nil, portname = nil) + service = port = nil + if servicename + service = @wsdl.service( + XSD::QName.new(@wsdl.targetnamespace, servicename)) + else + service = @wsdl.services[0] + end + if service.nil? + raise FactoryError.new("service #{servicename} not found in WSDL") + end + if portname + port = service.ports[XSD::QName.new(@wsdl.targetnamespace, portname)] + if port.nil? + raise FactoryError.new("port #{portname} not found in WSDL") + end + else + port = service.ports.find { |port| !port.soap_address.nil? } + if port.nil? + raise FactoryError.new("no ports have soap:address") + end + end + if port.soap_address.nil? + raise FactoryError.new("soap:address element not found in WSDL") + end + port + end + + def init_driver(drv, port) + wsdl_elements = @wsdl.collect_elements + wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes + rpc_decode_typemap = wsdl_types + + @wsdl.soap_rpc_complextypes(port.find_binding) + drv.proxy.mapping_registry = + Mapping::WSDLEncodedRegistry.new(rpc_decode_typemap) + drv.proxy.literal_mapping_registry = + Mapping::WSDLLiteralRegistry.new(wsdl_types, wsdl_elements) + end + + def add_operation(drv, port) + port.find_binding.operations.each do |op_bind| + op_name = op_bind.soapoperation_name + soapaction = op_bind.soapaction || '' + orgname = op_name.name + name = XSD::CodeGen::GenSupport.safemethodname(orgname) + param_def = create_param_def(op_bind) + opt = { + :request_style => op_bind.soapoperation_style, + :response_style => op_bind.soapoperation_style, + :request_use => op_bind.input.soapbody_use, + :response_use => op_bind.output.soapbody_use, + :elementformdefault => false, + :attributeformdefault => false + } + if op_bind.soapoperation_style == :rpc + drv.add_rpc_operation(op_name, soapaction, name, param_def, opt) + else + drv.add_document_operation(soapaction, name, param_def, opt) + end + if orgname != name and orgname.capitalize == name.capitalize + ::SOAP::Mapping.define_singleton_method(drv, orgname) do |*arg| + __send__(name, *arg) + end + end + end + end + + def import(location) + WSDL::Importer.import(location) + end + + def create_param_def(op_bind) + op = op_bind.find_operation + if op_bind.soapoperation_style == :rpc + param_def = @methoddefcreator.collect_rpcparameter(op) + else + param_def = @methoddefcreator.collect_documentparameter(op) + end + # the first element of typedef in param_def is a String like + # "::SOAP::SOAPStruct". turn this String to a class. + param_def.collect { |io, name, typedef| + typedef[0] = Mapping.class_from_name(typedef[0]) + [io, name, typedef] + } + end + + def partqname(part) + if part.type + part.type + else + part.element + end + end + + def param_def(type, name, klass, partqname) + [type, name, [klass, partqname.namespace, partqname.name]] + end + + def filter_parts(partsdef, partssource) + parts = partsdef.split(/\s+/) + partssource.find_all { |part| parts.include?(part.name) } + end +end + + +class WSDLDriver + class << self + if RUBY_VERSION >= "1.7.0" + def __attr_proxy(symbol, assignable = false) + name = symbol.to_s + define_method(name) { + @servant.__send__(name) + } + if assignable + aname = name + '=' + define_method(aname) { |rhs| + @servant.__send__(aname, rhs) + } + end + end + else + def __attr_proxy(symbol, assignable = false) + name = symbol.to_s + module_eval <<-EOS + def #{name} + @servant.#{name} + end + EOS + if assignable + module_eval <<-EOS + def #{name}=(value) + @servant.#{name} = value + end + EOS + end + end + end + end + + __attr_proxy :options + __attr_proxy :headerhandler + __attr_proxy :streamhandler + __attr_proxy :test_loopback_response + __attr_proxy :endpoint_url, true + __attr_proxy :mapping_registry, true # for RPC unmarshal + __attr_proxy :wsdl_mapping_registry, true # for RPC marshal + __attr_proxy :default_encodingstyle, true + __attr_proxy :generate_explicit_type, true + __attr_proxy :allow_unqualified_element, true + + def httpproxy + @servant.options["protocol.http.proxy"] + end + + def httpproxy=(httpproxy) + @servant.options["protocol.http.proxy"] = httpproxy + end + + def wiredump_dev + @servant.options["protocol.http.wiredump_dev"] + end + + def wiredump_dev=(wiredump_dev) + @servant.options["protocol.http.wiredump_dev"] = wiredump_dev + end + + def mandatorycharset + @servant.options["protocol.mandatorycharset"] + end + + def mandatorycharset=(mandatorycharset) + @servant.options["protocol.mandatorycharset"] = mandatorycharset + end + + def wiredump_file_base + @servant.options["protocol.wiredump_file_base"] + end + + def wiredump_file_base=(wiredump_file_base) + @servant.options["protocol.wiredump_file_base"] = wiredump_file_base + end + + def initialize(wsdl, port, logdev) + @servant = Servant__.new(self, wsdl, port, logdev) + end + + def inspect + "#<#{self.class}:#{@servant.port.name}>" + end + + def reset_stream + @servant.reset_stream + end + + # Backward compatibility. + alias generateEncodeType= generate_explicit_type= + + class Servant__ + include SOAP + + attr_reader :options + attr_reader :port + + attr_accessor :soapaction + attr_accessor :default_encodingstyle + attr_accessor :allow_unqualified_element + attr_accessor :generate_explicit_type + attr_accessor :mapping_registry + attr_accessor :wsdl_mapping_registry + + def initialize(host, wsdl, port, logdev) + @host = host + @wsdl = wsdl + @port = port + @logdev = logdev + @soapaction = nil + @options = setup_options + @default_encodingstyle = nil + @allow_unqualified_element = nil + @generate_explicit_type = false + @mapping_registry = nil # for rpc unmarshal + @wsdl_mapping_registry = nil # for rpc marshal + @wiredump_file_base = nil + @mandatorycharset = nil + @wsdl_elements = @wsdl.collect_elements + @wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes + @rpc_decode_typemap = @wsdl_types + + @wsdl.soap_rpc_complextypes(port.find_binding) + @wsdl_mapping_registry = Mapping::WSDLEncodedRegistry.new( + @rpc_decode_typemap) + @doc_mapper = Mapping::WSDLLiteralRegistry.new( + @wsdl_types, @wsdl_elements) + endpoint_url = @port.soap_address.location + # Convert a map which key is QName, to a Hash which key is String. + @operation = {} + @port.inputoperation_map.each do |op_name, op_info| + orgname = op_name.name + name = XSD::CodeGen::GenSupport.safemethodname(orgname) + @operation[name] = @operation[orgname] = op_info + add_method_interface(op_info) + end + @proxy = ::SOAP::RPC::Proxy.new(endpoint_url, @soapaction, @options) + end + + def inspect + "#<#{self.class}:#{@proxy.inspect}>" + end + + def endpoint_url + @proxy.endpoint_url + end + + def endpoint_url=(endpoint_url) + @proxy.endpoint_url = endpoint_url + end + + def headerhandler + @proxy.headerhandler + end + + def streamhandler + @proxy.streamhandler + end + + def test_loopback_response + @proxy.test_loopback_response + end + + def reset_stream + @proxy.reset_stream + end + + def rpc_call(name, *values) + set_wiredump_file_base(name) + unless op_info = @operation[name] + raise RuntimeError, "method: #{name} not defined" + end + req_header = create_request_header + req_body = create_request_body(op_info, *values) + reqopt = create_options({ + :soapaction => op_info.soapaction || @soapaction}) + resopt = create_options({ + :decode_typemap => @rpc_decode_typemap}) + env = @proxy.route(req_header, req_body, reqopt, resopt) + raise EmptyResponseError unless env + receive_headers(env.header) + begin + @proxy.check_fault(env.body) + rescue ::SOAP::FaultError => e + Mapping.fault2exception(e) + end + ret = env.body.response ? + Mapping.soap2obj(env.body.response, @mapping_registry) : nil + if env.body.outparams + outparams = env.body.outparams.collect { |outparam| + Mapping.soap2obj(outparam) + } + return [ret].concat(outparams) + else + return ret + end + end + + # req_header: [[element, mustunderstand, encodingstyle(QName/String)], ...] + # req_body: SOAPBasetype/SOAPCompoundtype + def document_send(name, header_obj, body_obj) + set_wiredump_file_base(name) + unless op_info = @operation[name] + raise RuntimeError, "method: #{name} not defined" + end + req_header = header_obj ? header_from_obj(header_obj, op_info) : nil + req_body = body_from_obj(body_obj, op_info) + opt = create_options({ + :soapaction => op_info.soapaction || @soapaction, + :decode_typemap => @wsdl_types}) + env = @proxy.invoke(req_header, req_body, opt) + raise EmptyResponseError unless env + if env.body.fault + raise ::SOAP::FaultError.new(env.body.fault) + end + res_body_obj = env.body.response ? + Mapping.soap2obj(env.body.response, @mapping_registry) : nil + return env.header, res_body_obj + end + + private + + def create_options(hash = nil) + opt = {} + opt[:default_encodingstyle] = @default_encodingstyle + opt[:allow_unqualified_element] = @allow_unqualified_element + opt[:generate_explicit_type] = @generate_explicit_type + opt.update(hash) if hash + opt + end + + def set_wiredump_file_base(name) + if @wiredump_file_base + @proxy.set_wiredump_file_base(@wiredump_file_base + "_#{name}") + end + end + + def create_request_header + headers = @proxy.headerhandler.on_outbound + if headers.empty? + nil + else + h = SOAPHeader.new + headers.each do |header| + h.add(header.elename.name, header) + end + h + end + end + + def receive_headers(headers) + @proxy.headerhandler.on_inbound(headers) if headers + end + + def create_request_body(op_info, *values) + method = create_method_struct(op_info, *values) + SOAPBody.new(method) + end + + def create_method_struct(op_info, *params) + parts_names = op_info.bodyparts.collect { |part| part.name } + obj = create_method_obj(parts_names, params) + method = Mapping.obj2soap(obj, @wsdl_mapping_registry, op_info.op_name) + if method.members.size != parts_names.size + new_method = SOAPStruct.new + method.each do |key, value| + if parts_names.include?(key) + new_method.add(key, value) + end + end + method = new_method + end + method.elename = op_info.op_name + method.type = XSD::QName.new # Request should not be typed. + method + end + + def create_method_obj(names, params) + o = Object.new + idx = 0 + while idx < params.length + o.instance_variable_set('@' + names[idx], params[idx]) + idx += 1 + end + o + end + + def header_from_obj(obj, op_info) + if obj.is_a?(SOAPHeader) + obj + elsif op_info.headerparts.empty? + if obj.nil? + nil + else + raise RuntimeError.new("no header definition in schema: #{obj}") + end + elsif op_info.headerparts.size == 1 + part = op_info.headerparts[0] + header = SOAPHeader.new() + header.add(headeritem_from_obj(obj, part.element || part.eletype)) + header + else + header = SOAPHeader.new() + op_info.headerparts.each do |part| + child = Mapping.get_attribute(obj, part.name) + ele = headeritem_from_obj(child, part.element || part.eletype) + header.add(part.name, ele) + end + header + end + end + + def headeritem_from_obj(obj, name) + if obj.nil? + SOAPElement.new(name) + elsif obj.is_a?(SOAPHeaderItem) + obj + else + Mapping.obj2soap(obj, @doc_mapper, name) + end + end + + def body_from_obj(obj, op_info) + if obj.is_a?(SOAPBody) + obj + elsif op_info.bodyparts.empty? + if obj.nil? + nil + else + raise RuntimeError.new("no body found in schema") + end + elsif op_info.bodyparts.size == 1 + part = op_info.bodyparts[0] + ele = bodyitem_from_obj(obj, part.element || part.type) + SOAPBody.new(ele) + else + body = SOAPBody.new + op_info.bodyparts.each do |part| + child = Mapping.get_attribute(obj, part.name) + ele = bodyitem_from_obj(child, part.element || part.type) + body.add(ele.elename.name, ele) + end + body + end + end + + def bodyitem_from_obj(obj, name) + if obj.nil? + SOAPElement.new(name) + elsif obj.is_a?(SOAPElement) + obj + else + Mapping.obj2soap(obj, @doc_mapper, name) + end + end + + def add_method_interface(op_info) + name = XSD::CodeGen::GenSupport.safemethodname(op_info.op_name.name) + orgname = op_info.op_name.name + parts_names = op_info.bodyparts.collect { |part| part.name } + case op_info.style + when :document + if orgname != name and orgname.capitalize == name.capitalize + add_document_method_interface(orgname, parts_names) + end + add_document_method_interface(name, parts_names) + when :rpc + if orgname != name and orgname.capitalize == name.capitalize + add_rpc_method_interface(orgname, parts_names) + end + add_rpc_method_interface(name, parts_names) + else + raise RuntimeError.new("unknown style: #{op_info.style}") + end + end + + def add_rpc_method_interface(name, parts_names) + ::SOAP::Mapping.define_singleton_method(@host, name) do |*arg| + unless arg.size == parts_names.size + raise ArgumentError.new( + "wrong number of arguments (#{arg.size} for #{parts_names.size})") + end + @servant.rpc_call(name, *arg) + end + @host.method(name) + end + + def add_document_method_interface(name, parts_names) + ::SOAP::Mapping.define_singleton_method(@host, name) do |h, b| + @servant.document_send(name, h, b) + end + @host.method(name) + end + + def setup_options + if opt = Property.loadproperty(::SOAP::PropertyName) + opt = opt["client"] + end + opt ||= Property.new + opt.add_hook("protocol.mandatorycharset") do |key, value| + @mandatorycharset = value + end + opt.add_hook("protocol.wiredump_file_base") do |key, value| + @wiredump_file_base = value + end + opt["protocol.http.charset"] ||= XSD::Charset.xml_encoding_label + opt["protocol.http.proxy"] ||= Env::HTTP_PROXY + opt["protocol.http.no_proxy"] ||= Env::NO_PROXY + opt + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/sync.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/sync.rb new file mode 100644 index 00000000..ae46c48d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/sync.rb @@ -0,0 +1,311 @@ +# +# sync.rb - 2 phase lock with counter +# $Release Version: 1.0$ +# $Revision: 11708 $ +# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $ +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# +# -- +# Sync_m, Synchronizer_m +# Usage: +# obj.extend(Sync_m) +# or +# class Foo +# include Sync_m +# : +# end +# +# Sync_m#sync_mode +# Sync_m#sync_locked?, locked? +# Sync_m#sync_shared?, shared? +# Sync_m#sync_exclusive?, sync_exclusive? +# Sync_m#sync_try_lock, try_lock +# Sync_m#sync_lock, lock +# Sync_m#sync_unlock, unlock +# +# Sync, Synchronicer: +# include Sync_m +# Usage: +# sync = Sync.new +# +# Sync#mode +# Sync#locked? +# Sync#shared? +# Sync#exclusive? +# Sync#try_lock(mode) -- mode = :EX, :SH, :UN +# Sync#lock(mode) -- mode = :EX, :SH, :UN +# Sync#unlock +# Sync#synchronize(mode) {...} +# +# + +unless defined? Thread + fail "Thread not available for this ruby interpreter" +end + +module Sync_m + RCS_ID='-$Header$-' + + # lock mode + UN = :UN + SH = :SH + EX = :EX + + # exceptions + class Err < StandardError + def Err.Fail(*opt) + fail self, sprintf(self::Message, *opt) + end + + class UnknownLocker < Err + Message = "Thread(%s) not locked." + def UnknownLocker.Fail(th) + super(th.inspect) + end + end + + class LockModeFailer < Err + Message = "Unknown lock mode(%s)" + def LockModeFailer.Fail(mode) + if mode.id2name + mode = id2name + end + super(mode) + end + end + end + + def Sync_m.define_aliases(cl) + cl.module_eval %q{ + alias locked? sync_locked? + alias shared? sync_shared? + alias exclusive? sync_exclusive? + alias lock sync_lock + alias unlock sync_unlock + alias try_lock sync_try_lock + alias synchronize sync_synchronize + } + end + + def Sync_m.append_features(cl) + super + unless cl.instance_of?(Module) + # do nothing for Modules + # make aliases and include the proper module. + define_aliases(cl) + end + end + + def Sync_m.extend_object(obj) + super + obj.sync_extended + end + + def sync_extended + unless (defined? locked? and + defined? shared? and + defined? exclusive? and + defined? lock and + defined? unlock and + defined? try_lock and + defined? synchronize) + Sync_m.define_aliases(class< 0 + for k, v in sync_upgrade_waiting + sync_sh_locker[k] = v + end + wait = sync_upgrade_waiting + self.sync_upgrade_waiting = [] + Thread.critical = false + + for w, v in wait + w.run + end + else + wait = sync_waiting + self.sync_waiting = [] + Thread.critical = false + for w in wait + w.run + end + end + end + + Thread.critical = false + self + end + + def sync_synchronize(mode = EX) + begin + sync_lock(mode) + yield + ensure + sync_unlock + end + end + + attr :sync_mode, true + + attr :sync_waiting, true + attr :sync_upgrade_waiting, true + attr :sync_sh_locker, true + attr :sync_ex_locker, true + attr :sync_ex_count, true + + private + + def sync_initialize + @sync_mode = UN + @sync_waiting = [] + @sync_upgrade_waiting = [] + @sync_sh_locker = Hash.new + @sync_ex_locker = nil + @sync_ex_count = 0 + end + + def initialize(*args) + sync_initialize + super + end + + def sync_try_lock_sub(m) + case m + when SH + case sync_mode + when UN + self.sync_mode = m + sync_sh_locker[Thread.current] = 1 + ret = true + when SH + count = 0 unless count = sync_sh_locker[Thread.current] + sync_sh_locker[Thread.current] = count + 1 + ret = true + when EX + # in EX mode, lock will upgrade to EX lock + if sync_ex_locker == Thread.current + self.sync_ex_count = sync_ex_count + 1 + ret = true + else + ret = false + end + end + when EX + if sync_mode == UN or + sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current) + self.sync_mode = m + self.sync_ex_locker = Thread.current + self.sync_ex_count = 1 + ret = true + elsif sync_mode == EX && sync_ex_locker == Thread.current + self.sync_ex_count = sync_ex_count + 1 + ret = true + else + ret = false + end + else + Thread.critical = false + Err::LockModeFailer.Fail mode + end + return ret + end +end +Synchronizer_m = Sync_m + +class Sync + #Sync_m.extend_class self + include Sync_m + + def initialize + super + end + +end +Synchronizer = Sync diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tempfile.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tempfile.rb new file mode 100644 index 00000000..b02b2491 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tempfile.rb @@ -0,0 +1,193 @@ +# +# tempfile - manipulates temporary files +# +# $Id: tempfile.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# + +require 'delegate' +require 'tmpdir' + +# A class for managing temporary files. This library is written to be +# thread safe. +class Tempfile < DelegateClass(File) + MAX_TRY = 10 + @@cleanlist = [] + + # Creates a temporary file of mode 0600 in the temporary directory + # whose name is basename.pid.n and opens with mode "w+". A Tempfile + # object works just like a File object. + # + # If tmpdir is omitted, the temporary directory is determined by + # Dir::tmpdir provided by 'tmpdir.rb'. + # When $SAFE > 0 and the given tmpdir is tainted, it uses + # /tmp. (Note that ENV values are tainted by default) + def initialize(basename, tmpdir=Dir::tmpdir) + if $SAFE > 0 and tmpdir.tainted? + tmpdir = '/tmp' + end + + lock = nil + n = failure = 0 + + begin + Thread.critical = true + + begin + tmpname = File.join(tmpdir, make_tmpname(basename, n)) + lock = tmpname + '.lock' + n += 1 + end while @@cleanlist.include?(tmpname) or + File.exist?(lock) or File.exist?(tmpname) + + Dir.mkdir(lock) + rescue + failure += 1 + retry if failure < MAX_TRY + raise "cannot generate tempfile `%s'" % tmpname + ensure + Thread.critical = false + end + + @data = [tmpname] + @clean_proc = Tempfile.callback(@data) + ObjectSpace.define_finalizer(self, @clean_proc) + + @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600) + @tmpname = tmpname + @@cleanlist << @tmpname + @data[1] = @tmpfile + @data[2] = @@cleanlist + + super(@tmpfile) + + # Now we have all the File/IO methods defined, you must not + # carelessly put bare puts(), etc. after this. + + Dir.rmdir(lock) + end + + def make_tmpname(basename, n) + sprintf('%s.%d.%d', basename, $$, n) + end + private :make_tmpname + + # Opens or reopens the file with mode "r+". + def open + @tmpfile.close if @tmpfile + @tmpfile = File.open(@tmpname, 'r+') + @data[1] = @tmpfile + __setobj__(@tmpfile) + end + + def _close # :nodoc: + @tmpfile.close if @tmpfile + @data[1] = @tmpfile = nil + end + protected :_close + + # Closes the file. If the optional flag is true, unlinks the file + # after closing. + # + # If you don't explicitly unlink the temporary file, the removal + # will be delayed until the object is finalized. + def close(unlink_now=false) + if unlink_now + close! + else + _close + end + end + + # Closes and unlinks the file. + def close! + _close + @clean_proc.call + ObjectSpace.undefine_finalizer(self) + end + + # Unlinks the file. On UNIX-like systems, it is often a good idea + # to unlink a temporary file immediately after creating and opening + # it, because it leaves other programs zero chance to access the + # file. + def unlink + # keep this order for thread safeness + begin + File.unlink(@tmpname) if File.exist?(@tmpname) + @@cleanlist.delete(@tmpname) + @data = @tmpname = nil + ObjectSpace.undefine_finalizer(self) + rescue Errno::EACCES + # may not be able to unlink on Windows; just ignore + end + end + alias delete unlink + + # Returns the full path name of the temporary file. + def path + @tmpname + end + + # Returns the size of the temporary file. As a side effect, the IO + # buffer is flushed before determining the size. + def size + if @tmpfile + @tmpfile.flush + @tmpfile.stat.size + else + 0 + end + end + alias length size + + class << self + def callback(data) # :nodoc: + pid = $$ + lambda{ + if pid == $$ + path, tmpfile, cleanlist = *data + + print "removing ", path, "..." if $DEBUG + + tmpfile.close if tmpfile + + # keep this order for thread safeness + File.unlink(path) if File.exist?(path) + cleanlist.delete(path) if cleanlist + + print "done\n" if $DEBUG + end + } + end + + # If no block is given, this is a synonym for new(). + # + # If a block is given, it will be passed tempfile as an argument, + # and the tempfile will automatically be closed when the block + # terminates. In this case, open() returns nil. + def open(*args) + tempfile = new(*args) + + if block_given? + begin + yield(tempfile) + ensure + tempfile.close + end + + nil + else + tempfile + end + end + end +end + +if __FILE__ == $0 +# $DEBUG = true + f = Tempfile.new("foo") + f.print("foo\n") + f.close + f.open + p f.gets # => "foo\n" + f.close! +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit.rb new file mode 100644 index 00000000..b71f6445 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit.rb @@ -0,0 +1,280 @@ +require 'test/unit/testcase' +require 'test/unit/autorunner' + +module Test # :nodoc: + # + # = Test::Unit - Ruby Unit Testing Framework + # + # == Introduction + # + # Unit testing is making waves all over the place, largely due to the + # fact that it is a core practice of XP. While XP is great, unit testing + # has been around for a long time and has always been a good idea. One + # of the keys to good unit testing, though, is not just writing tests, + # but having tests. What's the difference? Well, if you just _write_ a + # test and throw it away, you have no guarantee that something won't + # change later which breaks your code. If, on the other hand, you _have_ + # tests (obviously you have to write them first), and run them as often + # as possible, you slowly build up a wall of things that cannot break + # without you immediately knowing about it. This is when unit testing + # hits its peak usefulness. + # + # Enter Test::Unit, a framework for unit testing in Ruby, helping you to + # design, debug and evaluate your code by making it easy to write and + # have tests for it. + # + # + # == Notes + # + # Test::Unit has grown out of and superceded Lapidary. + # + # + # == Feedback + # + # I like (and do my best to practice) XP, so I value early releases, + # user feedback, and clean, simple, expressive code. There is always + # room for improvement in everything I do, and Test::Unit is no + # exception. Please, let me know what you think of Test::Unit as it + # stands, and what you'd like to see expanded/changed/improved/etc. If + # you find a bug, let me know ASAP; one good way to let me know what the + # bug is is to submit a new test that catches it :-) Also, I'd love to + # hear about any successes you have with Test::Unit, and any + # documentation you might add will be greatly appreciated. My contact + # info is below. + # + # + # == Contact Information + # + # A lot of discussion happens about Ruby in general on the ruby-talk + # mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask + # any questions you might have there. I monitor the list, as do many + # other helpful Rubyists, and you're sure to get a quick answer. Of + # course, you're also welcome to email me (Nathaniel Talbott) directly + # at mailto:testunit@talbott.ws, and I'll do my best to help you out. + # + # + # == Credits + # + # I'd like to thank... + # + # Matz, for a great language! + # + # Masaki Suketa, for his work on RubyUnit, which filled a vital need in + # the Ruby world for a very long time. I'm also grateful for his help in + # polishing Test::Unit and getting the RubyUnit compatibility layer + # right. His graciousness in allowing Test::Unit to supercede RubyUnit + # continues to be a challenge to me to be more willing to defer my own + # rights. + # + # Ken McKinlay, for his interest and work on unit testing, and for his + # willingness to dialog about it. He was also a great help in pointing + # out some of the holes in the RubyUnit compatibility layer. + # + # Dave Thomas, for the original idea that led to the extremely simple + # "require 'test/unit'", plus his code to improve it even more by + # allowing the selection of tests from the command-line. Also, without + # RDoc, the documentation for Test::Unit would stink a lot more than it + # does now. + # + # Everyone who's helped out with bug reports, feature ideas, + # encouragement to continue, etc. It's a real privilege to be a part of + # the Ruby community. + # + # The guys at RoleModel Software, for putting up with me repeating, "But + # this would be so much easier in Ruby!" whenever we're coding in Java. + # + # My Creator, for giving me life, and giving it more abundantly. + # + # + # == License + # + # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free + # software, and is distributed under the Ruby license. See the COPYING + # file in the standard Ruby distribution for details. + # + # + # == Warranty + # + # This software is provided "as is" and without any express or + # implied warranties, including, without limitation, the implied + # warranties of merchantibility and fitness for a particular + # purpose. + # + # + # == Author + # + # Nathaniel Talbott. + # Copyright (c) 2000-2003, Nathaniel Talbott + # + # ---- + # + # = Usage + # + # The general idea behind unit testing is that you write a _test_ + # _method_ that makes certain _assertions_ about your code, working + # against a _test_ _fixture_. A bunch of these _test_ _methods_ are + # bundled up into a _test_ _suite_ and can be run any time the + # developer wants. The results of a run are gathered in a _test_ + # _result_ and displayed to the user through some UI. So, lets break + # this down and see how Test::Unit provides each of these necessary + # pieces. + # + # + # == Assertions + # + # These are the heart of the framework. Think of an assertion as a + # statement of expected outcome, i.e. "I assert that x should be equal + # to y". If, when the assertion is executed, it turns out to be + # correct, nothing happens, and life is good. If, on the other hand, + # your assertion turns out to be false, an error is propagated with + # pertinent information so that you can go back and make your + # assertion succeed, and, once again, life is good. For an explanation + # of the current assertions, see Test::Unit::Assertions. + # + # + # == Test Method & Test Fixture + # + # Obviously, these assertions have to be called within a context that + # knows about them and can do something meaningful with their + # pass/fail value. Also, it's handy to collect a bunch of related + # tests, each test represented by a method, into a common test class + # that knows how to run them. The tests will be in a separate class + # from the code they're testing for a couple of reasons. First of all, + # it allows your code to stay uncluttered with test code, making it + # easier to maintain. Second, it allows the tests to be stripped out + # for deployment, since they're really there for you, the developer, + # and your users don't need them. Third, and most importantly, it + # allows you to set up a common test fixture for your tests to run + # against. + # + # What's a test fixture? Well, tests do not live in a vacuum; rather, + # they're run against the code they are testing. Often, a collection + # of tests will run against a common set of data, also called a + # fixture. If they're all bundled into the same test class, they can + # all share the setting up and tearing down of that data, eliminating + # unnecessary duplication and making it much easier to add related + # tests. + # + # Test::Unit::TestCase wraps up a collection of test methods together + # and allows you to easily set up and tear down the same test fixture + # for each test. This is done by overriding #setup and/or #teardown, + # which will be called before and after each test method that is + # run. The TestCase also knows how to collect the results of your + # assertions into a Test::Unit::TestResult, which can then be reported + # back to you... but I'm getting ahead of myself. To write a test, + # follow these steps: + # + # * Make sure Test::Unit is in your library path. + # * require 'test/unit' in your test script. + # * Create a class that subclasses Test::Unit::TestCase. + # * Add a method that begins with "test" to your class. + # * Make assertions in your test method. + # * Optionally define #setup and/or #teardown to set up and/or tear + # down your common test fixture. + # * You can now run your test as you would any other Ruby + # script... try it and see! + # + # A really simple test might look like this (#setup and #teardown are + # commented out to indicate that they are completely optional): + # + # require 'test/unit' + # + # class TC_MyTest < Test::Unit::TestCase + # # def setup + # # end + # + # # def teardown + # # end + # + # def test_fail + # assert(false, 'Assertion was false.') + # end + # end + # + # + # == Test Runners + # + # So, now you have this great test class, but you still need a way to + # run it and view any failures that occur during the run. This is + # where Test::Unit::UI::Console::TestRunner (and others, such as + # Test::Unit::UI::GTK::TestRunner) comes into play. The console test + # runner is automatically invoked for you if you require 'test/unit' + # and simply run the file. To use another runner, or to manually + # invoke a runner, simply call its run class method and pass in an + # object that responds to the suite message with a + # Test::Unit::TestSuite. This can be as simple as passing in your + # TestCase class (which has a class suite method). It might look + # something like this: + # + # require 'test/unit/ui/console/testrunner' + # Test::Unit::UI::Console::TestRunner.run(TC_MyTest) + # + # + # == Test Suite + # + # As more and more unit tests accumulate for a given project, it + # becomes a real drag running them one at a time, and it also + # introduces the potential to overlook a failing test because you + # forget to run it. Suddenly it becomes very handy that the + # TestRunners can take any object that returns a Test::Unit::TestSuite + # in response to a suite method. The TestSuite can, in turn, contain + # other TestSuites or individual tests (typically created by a + # TestCase). In other words, you can easily wrap up a group of + # TestCases and TestSuites like this: + # + # require 'test/unit/testsuite' + # require 'tc_myfirsttests' + # require 'tc_moretestsbyme' + # require 'ts_anothersetoftests' + # + # class TS_MyTests + # def self.suite + # suite = Test::Unit::TestSuite.new + # suite << TC_MyFirstTests.suite + # suite << TC_MoreTestsByMe.suite + # suite << TS_AnotherSetOfTests.suite + # return suite + # end + # end + # Test::Unit::UI::Console::TestRunner.run(TS_MyTests) + # + # Now, this is a bit cumbersome, so Test::Unit does a little bit more + # for you, by wrapping these up automatically when you require + # 'test/unit'. What does this mean? It means you could write the above + # test case like this instead: + # + # require 'test/unit' + # require 'tc_myfirsttests' + # require 'tc_moretestsbyme' + # require 'ts_anothersetoftests' + # + # Test::Unit is smart enough to find all the test cases existing in + # the ObjectSpace and wrap them up into a suite for you. It then runs + # the dynamic suite using the console TestRunner. + # + # + # == Questions? + # + # I'd really like to get feedback from all levels of Ruby + # practitioners about typos, grammatical errors, unclear statements, + # missing points, etc., in this document (or any other). + # + + module Unit + # If set to false Test::Unit will not automatically run at exit. + def self.run=(flag) + @run = flag + end + + # Automatically run tests at exit? + def self.run? + @run ||= false + end + end +end + +at_exit do + unless $! || Test::Unit.run? + exit Test::Unit::AutoRunner.run + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/assertionfailederror.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/assertionfailederror.rb new file mode 100644 index 00000000..a21e4b58 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/assertionfailederror.rb @@ -0,0 +1,14 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + + # Thrown by Test::Unit::Assertions when an assertion fails. + class AssertionFailedError < StandardError + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/assertions.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/assertions.rb new file mode 100644 index 00000000..aa97799d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/assertions.rb @@ -0,0 +1,622 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertionfailederror' +require 'test/unit/util/backtracefilter' + +module Test + module Unit + + ## + # Test::Unit::Assertions contains the standard Test::Unit assertions. + # Assertions is included in Test::Unit::TestCase. + # + # To include it in your own code and use its functionality, you simply + # need to rescue Test::Unit::AssertionFailedError. Additionally you may + # override add_assertion to get notified whenever an assertion is made. + # + # Notes: + # * The message to each assertion, if given, will be propagated with the + # failure. + # * It is easy to add your own assertions based on assert_block(). + # + # = Example Custom Assertion + # + # def deny(boolean, message = nil) + # message = build_message message, ' is not false or nil.', boolean + # assert_block message do + # not boolean + # end + # end + + module Assertions + + ## + # The assertion upon which all other assertions are based. Passes if the + # block yields true. + # + # Example: + # assert_block "Couldn't do the thing" do + # do_the_thing + # end + + public + def assert_block(message="assert_block failed.") # :yields: + _wrap_assertion do + if (! yield) + raise AssertionFailedError.new(message.to_s) + end + end + end + + ## + # Asserts that +boolean+ is not false or nil. + # + # Example: + # assert [1, 2].include?(5) + + public + def assert(boolean, message=nil) + _wrap_assertion do + assert_block("assert should not be called with a block.") { !block_given? } + assert_block(build_message(message, " is not true.", boolean)) { boolean } + end + end + + ## + # Passes if +expected+ == +actual. + # + # Note that the ordering of arguments is important, since a helpful + # error message is generated when this one fails that tells you the + # values of expected and actual. + # + # Example: + # assert_equal 'MY STRING', 'my string'.upcase + + public + def assert_equal(expected, actual, message=nil) + full_message = build_message(message, < expected but was +. +EOT + assert_block(full_message) { expected == actual } + end + + private + def _check_exception_class(args) # :nodoc: + args.partition do |klass| + next if klass.instance_of?(Module) + assert(Exception >= klass, "Should expect a class of exception, #{klass}") + true + end + end + + private + def _expected_exception?(actual_exception, exceptions, modules) # :nodoc: + exceptions.include?(actual_exception.class) or + modules.any? {|mod| actual_exception.is_a?(mod)} + end + + ## + # Passes if the block raises one of the given exceptions. + # + # Example: + # assert_raise RuntimeError, LoadError do + # raise 'Boom!!!' + # end + + public + def assert_raise(*args) + _wrap_assertion do + if Module === args.last + message = "" + else + message = args.pop + end + exceptions, modules = _check_exception_class(args) + expected = args.size == 1 ? args.first : args + actual_exception = nil + full_message = build_message(message, " exception expected but none was thrown.", expected) + assert_block(full_message) do + begin + yield + rescue Exception => actual_exception + break + end + false + end + full_message = build_message(message, " exception expected but was\n?", expected, actual_exception) + assert_block(full_message) {_expected_exception?(actual_exception, exceptions, modules)} + actual_exception + end + end + + ## + # Alias of assert_raise. + # + # Will be deprecated in 1.9, and removed in 2.0. + + public + def assert_raises(*args, &block) + assert_raise(*args, &block) + end + + ## + # Passes if +object+ .instance_of? +klass+ + # + # Example: + # assert_instance_of String, 'foo' + + public + def assert_instance_of(klass, object, message="") + _wrap_assertion do + assert_equal(Class, klass.class, "assert_instance_of takes a Class as its first argument") + full_message = build_message(message, < expected to be an instance of + but was +. +EOT + assert_block(full_message){object.instance_of?(klass)} + end + end + + ## + # Passes if +object+ is nil. + # + # Example: + # assert_nil [1, 2].uniq! + + public + def assert_nil(object, message="") + assert_equal(nil, object, message) + end + + ## + # Passes if +object+ .kind_of? +klass+ + # + # Example: + # assert_kind_of Object, 'foo' + + public + def assert_kind_of(klass, object, message="") + _wrap_assertion do + assert(klass.kind_of?(Module), "The first parameter to assert_kind_of should be a kind_of Module.") + full_message = build_message(message, "\nexpected to be kind_of\\?\n but was\n.", object, klass, object.class) + assert_block(full_message){object.kind_of?(klass)} + end + end + + ## + # Passes if +object+ .respond_to? +method+ + # + # Example: + # assert_respond_to 'bugbear', :slice + + public + def assert_respond_to(object, method, message="") + _wrap_assertion do + full_message = build_message(nil, "\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to\\?(:to_str).", method) + + assert_block(full_message) do + method.kind_of?(Symbol) || method.respond_to?(:to_str) + end + full_message = build_message(message, < +of type +expected to respond_to\\?. +EOT + assert_block(full_message) { object.respond_to?(method) } + end + end + + ## + # Passes if +string+ =~ +pattern+. + # + # Example: + # assert_match(/\d+/, 'five, 6, seven') + + public + def assert_match(pattern, string, message="") + _wrap_assertion do + pattern = case(pattern) + when String + Regexp.new(Regexp.escape(pattern)) + else + pattern + end + full_message = build_message(message, " expected to be =~\n.", string, pattern) + assert_block(full_message) { string =~ pattern } + end + end + + ## + # Passes if +actual+ .equal? +expected+ (i.e. they are the same + # instance). + # + # Example: + # o = Object.new + # assert_same o, o + + public + def assert_same(expected, actual, message="") + full_message = build_message(message, < +with id expected to be equal\\? to + +with id . +EOT + assert_block(full_message) { actual.equal?(expected) } + end + + ## + # Compares the +object1+ with +object2+ using +operator+. + # + # Passes if object1.__send__(operator, object2) is true. + # + # Example: + # assert_operator 5, :>=, 4 + + public + def assert_operator(object1, operator, object2, message="") + _wrap_assertion do + full_message = build_message(nil, "\ngiven as the operator for #assert_operator must be a Symbol or #respond_to\\?(:to_str).", operator) + assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)} + full_message = build_message(message, < expected to be +? +. +EOT + assert_block(full_message) { object1.__send__(operator, object2) } + end + end + + ## + # Passes if block does not raise an exception. + # + # Example: + # assert_nothing_raised do + # [1, 2].uniq + # end + + public + def assert_nothing_raised(*args) + _wrap_assertion do + if Module === args.last + message = "" + else + message = args.pop + end + exceptions, modules = _check_exception_class(args) + begin + yield + rescue Exception => e + if ((args.empty? && !e.instance_of?(AssertionFailedError)) || + _expected_exception?(e, exceptions, modules)) + assert_block(build_message(message, "Exception raised:\n?", e)){false} + else + raise + end + end + nil + end + end + + ## + # Flunk always fails. + # + # Example: + # flunk 'Not done testing yet.' + + public + def flunk(message="Flunked") + assert_block(build_message(message)){false} + end + + ## + # Passes if ! +actual+ .equal? +expected+ + # + # Example: + # assert_not_same Object.new, Object.new + + public + def assert_not_same(expected, actual, message="") + full_message = build_message(message, < +with id expected to not be equal\\? to + +with id . +EOT + assert_block(full_message) { !actual.equal?(expected) } + end + + ## + # Passes if +expected+ != +actual+ + # + # Example: + # assert_not_equal 'some string', 5 + + public + def assert_not_equal(expected, actual, message="") + full_message = build_message(message, " expected to be != to\n.", expected, actual) + assert_block(full_message) { expected != actual } + end + + ## + # Passes if ! +object+ .nil? + # + # Example: + # assert_not_nil '1 two 3'.sub!(/two/, '2') + + public + def assert_not_nil(object, message="") + full_message = build_message(message, " expected to not be nil.", object) + assert_block(full_message){!object.nil?} + end + + ## + # Passes if +regexp+ !~ +string+ + # + # Example: + # assert_no_match(/two/, 'one 2 three') + + public + def assert_no_match(regexp, string, message="") + _wrap_assertion do + assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.") + full_message = build_message(message, " expected to not match\n.", regexp, string) + assert_block(full_message) { regexp !~ string } + end + end + + UncaughtThrow = {NameError => /^uncaught throw \`(.+)\'$/, + ThreadError => /^uncaught throw \`(.+)\' in thread /} #` + + ## + # Passes if the block throws +expected_symbol+ + # + # Example: + # assert_throws :done do + # throw :done + # end + + public + def assert_throws(expected_symbol, message="", &proc) + _wrap_assertion do + assert_instance_of(Symbol, expected_symbol, "assert_throws expects the symbol that should be thrown for its first argument") + assert_block("Should have passed a block to assert_throws."){block_given?} + caught = true + begin + catch(expected_symbol) do + proc.call + caught = false + end + full_message = build_message(message, " should have been thrown.", expected_symbol) + assert_block(full_message){caught} + rescue NameError, ThreadError => error + if UncaughtThrow[error.class] !~ error.message + raise error + end + full_message = build_message(message, " expected to be thrown but\n was thrown.", expected_symbol, $1.intern) + flunk(full_message) + end + end + end + + ## + # Passes if block does not throw anything. + # + # Example: + # assert_nothing_thrown do + # [1, 2].uniq + # end + + public + def assert_nothing_thrown(message="", &proc) + _wrap_assertion do + assert(block_given?, "Should have passed a block to assert_nothing_thrown") + begin + proc.call + rescue NameError, ThreadError => error + if UncaughtThrow[error.class] !~ error.message + raise error + end + full_message = build_message(message, " was thrown when nothing was expected", $1.intern) + flunk(full_message) + end + assert(true, "Expected nothing to be thrown") + end + end + + ## + # Passes if +expected_float+ and +actual_float+ are equal + # within +delta+ tolerance. + # + # Example: + # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001 + + public + def assert_in_delta(expected_float, actual_float, delta, message="") + _wrap_assertion do + {expected_float => "first float", actual_float => "second float", delta => "delta"}.each do |float, name| + assert_respond_to(float, :to_f, "The arguments must respond to to_f; the #{name} did not") + end + assert_operator(delta, :>=, 0.0, "The delta should not be negative") + full_message = build_message(message, < and + expected to be within + of each other. +EOT + assert_block(full_message) { (expected_float.to_f - actual_float.to_f).abs <= delta.to_f } + end + end + + ## + # Passes if the method send returns a true value. + # + # +send_array+ is composed of: + # * A receiver + # * A method + # * Arguments to the method + # + # Example: + # assert_send [[1, 2], :include?, 4] + + public + def assert_send(send_array, message="") + _wrap_assertion do + assert_instance_of(Array, send_array, "assert_send requires an array of send information") + assert(send_array.size >= 2, "assert_send requires at least a receiver and a message name") + full_message = build_message(message, < expected to respond to + with a true value. +EOT + assert_block(full_message) { send_array[0].__send__(send_array[1], *send_array[2..-1]) } + end + end + + ## + # Builds a failure message. +head+ is added before the +template+ and + # +arguments+ replaces the '?'s positionally in the template. + + public + def build_message(head, template=nil, *arguments) + template &&= template.chomp + return AssertionMessage.new(head, template, arguments) + end + + private + def _wrap_assertion + @_assertion_wrapped ||= false + unless (@_assertion_wrapped) + @_assertion_wrapped = true + begin + add_assertion + return yield + ensure + @_assertion_wrapped = false + end + else + return yield + end + end + + ## + # Called whenever an assertion is made. Define this in classes that + # include Test::Unit::Assertions to record assertion counts. + + private + def add_assertion + end + + ## + # Select whether or not to use the pretty-printer. If this option is set + # to false before any assertions are made, pp.rb will not be required. + + public + def self.use_pp=(value) + AssertionMessage.use_pp = value + end + + # :stopdoc: + + class AssertionMessage + @use_pp = true + class << self + attr_accessor :use_pp + end + + class Literal + def initialize(value) + @value = value + end + + def inspect + @value.to_s + end + end + + class Template + def self.create(string) + parts = (string ? string.scan(/(?=[^\\])\?|(?:\\\?|[^\?])+/m) : []) + self.new(parts) + end + + attr_reader :count + + def initialize(parts) + @parts = parts + @count = parts.find_all{|e| e == '?'}.size + end + + def result(parameters) + raise "The number of parameters does not match the number of substitutions." if(parameters.size != count) + params = parameters.dup + @parts.collect{|e| e == '?' ? params.shift : e.gsub(/\\\?/m, '?')}.join('') + end + end + + def self.literal(value) + Literal.new(value) + end + + include Util::BacktraceFilter + + def initialize(head, template_string, parameters) + @head = head + @template_string = template_string + @parameters = parameters + end + + def convert(object) + case object + when Exception + < +Message: <#{convert(object.message)}> +---Backtrace--- +#{filter_backtrace(object.backtrace).join("\n")} +--------------- +EOM + else + if(self.class.use_pp) + begin + require 'pp' + rescue LoadError + self.class.use_pp = false + return object.inspect + end unless(defined?(PP)) + PP.pp(object, '').chomp + else + object.inspect + end + end + end + + def template + @template ||= Template.create(@template_string) + end + + def add_period(string) + (string =~ /\.\Z/ ? string : string + '.') + end + + def to_s + message_parts = [] + if (@head) + head = @head.to_s + unless(head.empty?) + message_parts << add_period(head) + end + end + tail = template.result(@parameters.collect{|e| convert(e)}) + message_parts << tail unless(tail.empty?) + message_parts.join("\n") + end + end + + # :startdoc: + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/autorunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/autorunner.rb new file mode 100644 index 00000000..86c9b129 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/autorunner.rb @@ -0,0 +1,220 @@ +require 'test/unit' +require 'test/unit/ui/testrunnerutilities' +require 'optparse' + +module Test + module Unit + class AutoRunner + def self.run(force_standalone=false, default_dir=nil, argv=ARGV, &block) + r = new(force_standalone || standalone?, &block) + r.base = default_dir + r.process_args(argv) + r.run + end + + def self.standalone? + return false unless("-e" == $0) + ObjectSpace.each_object(Class) do |klass| + return false if(klass < TestCase) + end + true + end + + RUNNERS = { + :console => proc do |r| + require 'test/unit/ui/console/testrunner' + Test::Unit::UI::Console::TestRunner + end, + :gtk => proc do |r| + require 'test/unit/ui/gtk/testrunner' + Test::Unit::UI::GTK::TestRunner + end, + :gtk2 => proc do |r| + require 'test/unit/ui/gtk2/testrunner' + Test::Unit::UI::GTK2::TestRunner + end, + :fox => proc do |r| + require 'test/unit/ui/fox/testrunner' + Test::Unit::UI::Fox::TestRunner + end, + :tk => proc do |r| + require 'test/unit/ui/tk/testrunner' + Test::Unit::UI::Tk::TestRunner + end, + } + + OUTPUT_LEVELS = [ + [:silent, UI::SILENT], + [:progress, UI::PROGRESS_ONLY], + [:normal, UI::NORMAL], + [:verbose, UI::VERBOSE], + ] + + COLLECTORS = { + :objectspace => proc do |r| + require 'test/unit/collector/objectspace' + c = Collector::ObjectSpace.new + c.filter = r.filters + c.collect($0.sub(/\.rb\Z/, '')) + end, + :dir => proc do |r| + require 'test/unit/collector/dir' + c = Collector::Dir.new + c.filter = r.filters + c.pattern.concat(r.pattern) if(r.pattern) + c.exclude.concat(r.exclude) if(r.exclude) + c.base = r.base + $:.push(r.base) if r.base + c.collect(*(r.to_run.empty? ? ['.'] : r.to_run)) + end, + } + + attr_reader :suite + attr_accessor :output_level, :filters, :to_run, :pattern, :exclude, :base, :workdir + attr_writer :runner, :collector + + def initialize(standalone) + Unit.run = true + @standalone = standalone + @runner = RUNNERS[:console] + @collector = COLLECTORS[(standalone ? :dir : :objectspace)] + @filters = [] + @to_run = [] + @output_level = UI::NORMAL + @workdir = nil + yield(self) if(block_given?) + end + + def process_args(args = ARGV) + begin + options.order!(args) {|arg| @to_run << arg} + rescue OptionParser::ParseError => e + puts e + puts options + $! = nil + abort + else + @filters << proc{false} unless(@filters.empty?) + end + not @to_run.empty? + end + + def options + @options ||= OptionParser.new do |o| + o.banner = "Test::Unit automatic runner." + o.banner << "\nUsage: #{$0} [options] [-- untouched arguments]" + + o.on + o.on('-r', '--runner=RUNNER', RUNNERS, + "Use the given RUNNER.", + "(" + keyword_display(RUNNERS) + ")") do |r| + @runner = r + end + + if(@standalone) + o.on('-b', '--basedir=DIR', "Base directory of test suites.") do |b| + @base = b + end + + o.on('-w', '--workdir=DIR', "Working directory to run tests.") do |w| + @workdir = w + end + + o.on('-a', '--add=TORUN', Array, + "Add TORUN to the list of things to run;", + "can be a file or a directory.") do |a| + @to_run.concat(a) + end + + @pattern = [] + o.on('-p', '--pattern=PATTERN', Regexp, + "Match files to collect against PATTERN.") do |e| + @pattern << e + end + + @exclude = [] + o.on('-x', '--exclude=PATTERN', Regexp, + "Ignore files to collect against PATTERN.") do |e| + @exclude << e + end + end + + o.on('-n', '--name=NAME', String, + "Runs tests matching NAME.", + "(patterns may be used).") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + case n + when Regexp + @filters << proc{|t| n =~ t.method_name ? true : nil} + else + @filters << proc{|t| n == t.method_name ? true : nil} + end + end + + o.on('-t', '--testcase=TESTCASE', String, + "Runs tests in TestCases matching TESTCASE.", + "(patterns may be used).") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + case n + when Regexp + @filters << proc{|t| n =~ t.class.name ? true : nil} + else + @filters << proc{|t| n == t.class.name ? true : nil} + end + end + + o.on('-I', "--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]", + "Appends directory list to $LOAD_PATH.") do |dirs| + $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR)) + end + + o.on('-v', '--verbose=[LEVEL]', OUTPUT_LEVELS, + "Set the output level (default is verbose).", + "(" + keyword_display(OUTPUT_LEVELS) + ")") do |l| + @output_level = l || UI::VERBOSE + end + + o.on('--', + "Stop processing options so that the", + "remaining options will be passed to the", + "test."){o.terminate} + + o.on('-h', '--help', 'Display this help.'){puts o; exit} + + o.on_tail + o.on_tail('Deprecated options:') + + o.on_tail('--console', 'Console runner (use --runner).') do + warn("Deprecated option (--console).") + @runner = RUNNERS[:console] + end + + o.on_tail('--gtk', 'GTK runner (use --runner).') do + warn("Deprecated option (--gtk).") + @runner = RUNNERS[:gtk] + end + + o.on_tail('--fox', 'Fox runner (use --runner).') do + warn("Deprecated option (--fox).") + @runner = RUNNERS[:fox] + end + + o.on_tail + end + end + + def keyword_display(array) + list = array.collect {|e, *| e.to_s} + Array === array or list.sort! + list.collect {|e| e.sub(/^(.)([A-Za-z]+)(?=\w*$)/, '\\1[\\2]')}.join(", ") + end + + def run + @suite = @collector[self] + result = @runner[self] or return false + Dir.chdir(@workdir) if @workdir + result.run(@suite, @output_level).passed? + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector.rb new file mode 100644 index 00000000..9e9e6541 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector.rb @@ -0,0 +1,43 @@ +module Test + module Unit + module Collector + def initialize + @filters = [] + end + + def filter=(filters) + @filters = case(filters) + when Proc + [filters] + when Array + filters + end + end + + def add_suite(destination, suite) + to_delete = suite.tests.find_all{|t| !include?(t)} + to_delete.each{|t| suite.delete(t)} + destination << suite unless(suite.size == 0) + end + + def include?(test) + return true if(@filters.empty?) + @filters.each do |filter| + result = filter[test] + if(result.nil?) + next + elsif(!result) + return false + else + return true + end + end + true + end + + def sort(suites) + suites.sort_by{|s| s.name} + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector/dir.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector/dir.rb new file mode 100644 index 00000000..97c8d284 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector/dir.rb @@ -0,0 +1,107 @@ +require 'test/unit/testsuite' +require 'test/unit/collector' + +module Test + module Unit + module Collector + class Dir + include Collector + + attr_reader :pattern, :exclude + attr_accessor :base + + def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil) + super() + @dir = dir + @file = file + @object_space = object_space + @req = req + @pattern = [/\btest_.*\.rb\Z/m] + @exclude = [] + end + + def collect(*from) + basedir = @base + $:.push(basedir) if basedir + if(from.empty?) + recursive_collect('.', find_test_cases) + elsif(from.size == 1) + recursive_collect(from.first, find_test_cases) + else + suites = [] + from.each do |f| + suite = recursive_collect(f, find_test_cases) + suites << suite unless(suite.tests.empty?) + end + suite = TestSuite.new("[#{from.join(', ')}]") + sort(suites).each{|s| suite << s} + suite + end + ensure + $:.delete_at($:.rindex(basedir)) if basedir + end + + def find_test_cases(ignore=[]) + cases = [] + @object_space.each_object(Class) do |c| + cases << c if(c < TestCase && !ignore.include?(c)) + end + ignore.concat(cases) + cases + end + + def recursive_collect(name, already_gathered) + sub_suites = [] + path = realdir(name) + if @file.directory?(path) + dir_name = name unless name == '.' + @dir.entries(path).each do |e| + next if(e == '.' || e == '..') + e_name = dir_name ? @file.join(dir_name, e) : e + if @file.directory?(realdir(e_name)) + next if /\ACVS\z/ =~ e + sub_suite = recursive_collect(e_name, already_gathered) + sub_suites << sub_suite unless(sub_suite.empty?) + else + next if /~\z/ =~ e_name or /\A\.\#/ =~ e + if @pattern and !@pattern.empty? + next unless @pattern.any? {|pat| pat =~ e_name} + end + if @exclude and !@exclude.empty? + next if @exclude.any? {|pat| pat =~ e_name} + end + collect_file(e_name, sub_suites, already_gathered) + end + end + else + collect_file(name, sub_suites, already_gathered) + end + suite = TestSuite.new(@file.basename(name)) + sort(sub_suites).each{|s| suite << s} + suite + end + + def collect_file(name, suites, already_gathered) + dir = @file.dirname(@file.expand_path(name, @base)) + $:.unshift(dir) + if(@req) + @req.require(name) + else + require(name) + end + find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)} + ensure + $:.delete_at($:.rindex(dir)) if(dir) + end + + def realdir(path) + if @base + @file.join(@base, path) + else + path + end + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector/objectspace.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector/objectspace.rb new file mode 100644 index 00000000..d1127a98 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/collector/objectspace.rb @@ -0,0 +1,34 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/collector' + +module Test + module Unit + module Collector + class ObjectSpace + include Collector + + NAME = 'collected from the ObjectSpace' + + def initialize(source=::ObjectSpace) + super() + @source = source + end + + def collect(name=NAME) + suite = TestSuite.new(name) + sub_suites = [] + @source.each_object(Class) do |klass| + if(Test::Unit::TestCase > klass) + add_suite(sub_suites, klass.suite) + end + end + sort(sub_suites).each{|s| suite << s} + suite + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/error.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/error.rb new file mode 100644 index 00000000..43a813f7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/error.rb @@ -0,0 +1,56 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/util/backtracefilter' + +module Test + module Unit + + # Encapsulates an error in a test. Created by + # Test::Unit::TestCase when it rescues an exception thrown + # during the processing of a test. + class Error + include Util::BacktraceFilter + + attr_reader(:test_name, :exception) + + SINGLE_CHARACTER = 'E' + + # Creates a new Error with the given test_name and + # exception. + def initialize(test_name, exception) + @test_name = test_name + @exception = exception + end + + # Returns a single character representation of an error. + def single_character_display + SINGLE_CHARACTER + end + + # Returns the message associated with the error. + def message + "#{@exception.class.name}: #{@exception.message}" + end + + # Returns a brief version of the error description. + def short_display + "#@test_name: #{message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + backtrace = filter_backtrace(@exception.backtrace).join("\n ") + "Error:\n#@test_name:\n#{message}\n #{backtrace}" + end + + # Overridden to return long_display. + def to_s + long_display + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/failure.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/failure.rb new file mode 100644 index 00000000..832c9985 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/failure.rb @@ -0,0 +1,51 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + + # Encapsulates a test failure. Created by Test::Unit::TestCase + # when an assertion fails. + class Failure + attr_reader :test_name, :location, :message + + SINGLE_CHARACTER = 'F' + + # Creates a new Failure with the given location and + # message. + def initialize(test_name, location, message) + @test_name = test_name + @location = location + @message = message + end + + # Returns a single character representation of a failure. + def single_character_display + SINGLE_CHARACTER + end + + # Returns a brief version of the error description. + def short_display + "#@test_name: #{@message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + location_display = if(location.size == 1) + location[0].sub(/\A(.+:\d+).*/, ' [\\1]') + else + "\n [#{location.join("\n ")}]" + end + "Failure:\n#@test_name#{location_display}:\n#@message" + end + + # Overridden to return long_display. + def to_s + long_display + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testcase.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testcase.rb new file mode 100644 index 00000000..f53b460c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testcase.rb @@ -0,0 +1,160 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertions' +require 'test/unit/failure' +require 'test/unit/error' +require 'test/unit/testsuite' +require 'test/unit/assertionfailederror' +require 'test/unit/util/backtracefilter' + +module Test + module Unit + + # Ties everything together. If you subclass and add your own + # test methods, it takes care of making them into tests and + # wrapping those tests into a suite. It also does the + # nitty-gritty of actually running an individual test and + # collecting its results into a Test::Unit::TestResult object. + class TestCase + include Assertions + include Util::BacktraceFilter + + attr_reader :method_name + + STARTED = name + "::STARTED" + FINISHED = name + "::FINISHED" + + ## + # These exceptions are not caught by #run. + + PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt, + SystemExit] + + # Creates a new instance of the fixture for running the + # test represented by test_method_name. + def initialize(test_method_name) + unless(respond_to?(test_method_name) and + (method(test_method_name).arity == 0 || + method(test_method_name).arity == -1)) + throw :invalid_test + end + @method_name = test_method_name + @test_passed = true + end + + # Rolls up all of the test* methods in the fixture into + # one suite, creating a new instance of the fixture for + # each method. + def self.suite + method_names = public_instance_methods(true) + tests = method_names.delete_if {|method_name| method_name !~ /^test./} + suite = TestSuite.new(name) + tests.sort.each do + |test| + catch(:invalid_test) do + suite << new(test) + end + end + if (suite.empty?) + catch(:invalid_test) do + suite << new("default_test") + end + end + return suite + end + + # Runs the individual test method represented by this + # instance of the fixture, collecting statistics, failures + # and errors in result. + def run(result) + yield(STARTED, name) + @_result = result + begin + setup + __send__(@method_name) + rescue AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue Exception + raise if PASSTHROUGH_EXCEPTIONS.include? $!.class + add_error($!) + ensure + begin + teardown + rescue AssertionFailedError => e + add_failure(e.message, e.backtrace) + rescue Exception + raise if PASSTHROUGH_EXCEPTIONS.include? $!.class + add_error($!) + end + end + result.add_run + yield(FINISHED, name) + end + + # Called before every test method runs. Can be used + # to set up fixture information. + def setup + end + + # Called after every test method runs. Can be used to tear + # down fixture information. + def teardown + end + + def default_test + flunk("No tests were specified") + end + + # Returns whether this individual test passed or + # not. Primarily for use in teardown so that artifacts + # can be left behind if the test fails. + def passed? + return @test_passed + end + private :passed? + + def size + 1 + end + + def add_assertion + @_result.add_assertion + end + private :add_assertion + + def add_failure(message, all_locations=caller()) + @test_passed = false + @_result.add_failure(Failure.new(name, filter_backtrace(all_locations), message)) + end + private :add_failure + + def add_error(exception) + @test_passed = false + @_result.add_error(Error.new(name, exception)) + end + private :add_error + + # Returns a human-readable name for the specific test that + # this instance of TestCase represents. + def name + "#{@method_name}(#{self.class.name})" + end + + # Overridden to return #name. + def to_s + name + end + + # It's handy to be able to compare TestCase instances. + def ==(other) + return false unless(other.kind_of?(self.class)) + return false unless(@method_name == other.method_name) + self.class == other.class + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testresult.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testresult.rb new file mode 100644 index 00000000..e3a472ef --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testresult.rb @@ -0,0 +1,80 @@ +#-- +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/util/observable' + +module Test + module Unit + + # Collects Test::Unit::Failure and Test::Unit::Error so that + # they can be displayed to the user. To this end, observers + # can be added to it, allowing the dynamic updating of, say, a + # UI. + class TestResult + include Util::Observable + + CHANGED = "CHANGED" + FAULT = "FAULT" + + attr_reader(:run_count, :assertion_count) + + # Constructs a new, empty TestResult. + def initialize + @run_count, @assertion_count = 0, 0 + @failures, @errors = Array.new, Array.new + end + + # Records a test run. + def add_run + @run_count += 1 + notify_listeners(CHANGED, self) + end + + # Records a Test::Unit::Failure. + def add_failure(failure) + @failures << failure + notify_listeners(FAULT, failure) + notify_listeners(CHANGED, self) + end + + # Records a Test::Unit::Error. + def add_error(error) + @errors << error + notify_listeners(FAULT, error) + notify_listeners(CHANGED, self) + end + + # Records an individual assertion. + def add_assertion + @assertion_count += 1 + notify_listeners(CHANGED, self) + end + + # Returns a string contain the recorded runs, assertions, + # failures and errors in this TestResult. + def to_s + "#{run_count} tests, #{assertion_count} assertions, #{failure_count} failures, #{error_count} errors" + end + + # Returns whether or not this TestResult represents + # successful completion. + def passed? + return @failures.empty? && @errors.empty? + end + + # Returns the number of failures this TestResult has + # recorded. + def failure_count + return @failures.size + end + + # Returns the number of errors this TestResult has + # recorded. + def error_count + return @errors.size + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testsuite.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testsuite.rb new file mode 100644 index 00000000..6fea976c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/testsuite.rb @@ -0,0 +1,76 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + + # A collection of tests which can be #run. + # + # Note: It is easy to confuse a TestSuite instance with + # something that has a static suite method; I know because _I_ + # have trouble keeping them straight. Think of something that + # has a suite method as simply providing a way to get a + # meaningful TestSuite instance. + class TestSuite + attr_reader :name, :tests + + STARTED = name + "::STARTED" + FINISHED = name + "::FINISHED" + + # Creates a new TestSuite with the given name. + def initialize(name="Unnamed TestSuite") + @name = name + @tests = [] + end + + # Runs the tests and/or suites contained in this + # TestSuite. + def run(result, &progress_block) + yield(STARTED, name) + @tests.each do |test| + test.run(result, &progress_block) + end + yield(FINISHED, name) + end + + # Adds the test to the suite. + def <<(test) + @tests << test + self + end + + def delete(test) + @tests.delete(test) + end + + # Retuns the rolled up number of tests in this suite; + # i.e. if the suite contains other suites, it counts the + # tests within those suites, not the suites themselves. + def size + total_size = 0 + @tests.each { |test| total_size += test.size } + total_size + end + + def empty? + tests.empty? + end + + # Overridden to return the name given the suite at + # creation. + def to_s + @name + end + + # It's handy to be able to compare TestSuite instances. + def ==(other) + return false unless(other.kind_of?(self.class)) + return false unless(@name == other.name) + @tests == other.tests + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/console/testrunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/console/testrunner.rb new file mode 100644 index 00000000..6b600e31 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/console/testrunner.rb @@ -0,0 +1,127 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/ui/testrunnermediator' +require 'test/unit/ui/testrunnerutilities' + +module Test + module Unit + module UI + module Console + + # Runs a Test::Unit::TestSuite on the console. + class TestRunner + extend TestRunnerUtilities + + # Creates a new TestRunner for running the passed + # suite. If quiet_mode is true, the output while + # running is limited to progress dots, errors and + # failures, and the final result. io specifies + # where runner output should go to; defaults to + # STDOUT. + def initialize(suite, output_level=NORMAL, io=STDOUT) + if (suite.respond_to?(:suite)) + @suite = suite.suite + else + @suite = suite + end + @output_level = output_level + @io = io + @already_outputted = false + @faults = [] + end + + # Begins the test run. + def start + setup_mediator + attach_to_mediator + return start_mediator + end + + private + def setup_mediator + @mediator = create_mediator(@suite) + suite_name = @suite.to_s + if ( @suite.kind_of?(Module) ) + suite_name = @suite.name + end + output("Loaded suite #{suite_name}") + end + + def create_mediator(suite) + return TestRunnerMediator.new(suite) + end + + def attach_to_mediator + @mediator.add_listener(TestResult::FAULT, &method(:add_fault)) + @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) + @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) + @mediator.add_listener(TestCase::STARTED, &method(:test_started)) + @mediator.add_listener(TestCase::FINISHED, &method(:test_finished)) + end + + def start_mediator + return @mediator.run_suite + end + + def add_fault(fault) + @faults << fault + output_single(fault.single_character_display, PROGRESS_ONLY) + @already_outputted = true + end + + def started(result) + @result = result + output("Started") + end + + def finished(elapsed_time) + nl + output("Finished in #{elapsed_time} seconds.") + @faults.each_with_index do |fault, index| + nl + output("%3d) %s" % [index + 1, fault.long_display]) + end + nl + output(@result) + end + + def test_started(name) + output_single(name + ": ", VERBOSE) + end + + def test_finished(name) + output_single(".", PROGRESS_ONLY) unless (@already_outputted) + nl(VERBOSE) + @already_outputted = false + end + + def nl(level=NORMAL) + output("", level) + end + + def output(something, level=NORMAL) + @io.puts(something) if (output?(level)) + @io.flush + end + + def output_single(something, level=NORMAL) + @io.write(something) if (output?(level)) + @io.flush + end + + def output?(level) + level <= @output_level + end + end + end + end + end +end + +if __FILE__ == $0 + Test::Unit::UI::Console::TestRunner.start_command_line_test +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/fox/testrunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/fox/testrunner.rb new file mode 100644 index 00000000..a23a4505 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/fox/testrunner.rb @@ -0,0 +1,268 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'fox' +require 'test/unit/ui/testrunnermediator' +require 'test/unit/ui/testrunnerutilities' + +include Fox + +module Test + module Unit + module UI + module Fox + + # Runs a Test::Unit::TestSuite in a Fox UI. Obviously, + # this one requires you to have Fox + # (http://www.fox-toolkit.org/fox.html) and the Ruby + # Fox extension (http://fxruby.sourceforge.net/) + # installed. + class TestRunner + + extend TestRunnerUtilities + + RED_STYLE = FXRGBA(0xFF,0,0,0xFF) #0xFF000000 + GREEN_STYLE = FXRGBA(0,0xFF,0,0xFF) #0x00FF0000 + + # Creates a new TestRunner for running the passed + # suite. + def initialize(suite, output_level = NORMAL) + if (suite.respond_to?(:suite)) + @suite = suite.suite + else + @suite = suite + end + + @result = nil + @red = false + end + + # Begins the test run. + def start + setup_ui + setup_mediator + attach_to_mediator + start_ui + @result + end + + def setup_mediator + @mediator = TestRunnerMediator.new(@suite) + suite_name = @suite.to_s + if ( @suite.kind_of?(Module) ) + suite_name = @suite.name + end + @suite_name_entry.text = suite_name + end + + def attach_to_mediator + @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui)) + @mediator.add_listener(TestResult::FAULT, &method(:add_fault)) + @mediator.add_listener(TestResult::CHANGED, &method(:result_changed)) + @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) + @mediator.add_listener(TestCase::STARTED, &method(:test_started)) + @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) + end + + def start_ui + @application.create + @window.show(PLACEMENT_SCREEN) + @application.addTimeout(1) do + @mediator.run_suite + end + @application.run + end + + def stop + @application.exit(0) + end + + def reset_ui(count) + @test_progress_bar.barColor = GREEN_STYLE + @test_progress_bar.total = count + @test_progress_bar.progress = 0 + @red = false + + @test_count_label.text = "0" + @assertion_count_label.text = "0" + @failure_count_label.text = "0" + @error_count_label.text = "0" + + @fault_list.clearItems + end + + def add_fault(fault) + if ( ! @red ) + @test_progress_bar.barColor = RED_STYLE + @red = true + end + item = FaultListItem.new(fault) + @fault_list.appendItem(item) + end + + def show_fault(fault) + raw_show_fault(fault.long_display) + end + + def raw_show_fault(string) + @detail_text.setText(string) + end + + def clear_fault + raw_show_fault("") + end + + def result_changed(result) + @test_progress_bar.progress = result.run_count + + @test_count_label.text = result.run_count.to_s + @assertion_count_label.text = result.assertion_count.to_s + @failure_count_label.text = result.failure_count.to_s + @error_count_label.text = result.error_count.to_s + + # repaint now! + @info_panel.repaint + @application.flush + end + + def started(result) + @result = result + output_status("Started...") + end + + def test_started(test_name) + output_status("Running #{test_name}...") + end + + def finished(elapsed_time) + output_status("Finished in #{elapsed_time} seconds") + end + + def output_status(string) + @status_entry.text = string + @status_entry.repaint + end + + def setup_ui + @application = create_application + create_tooltip(@application) + + @window = create_window(@application) + + @status_entry = create_entry(@window) + + main_panel = create_main_panel(@window) + + suite_panel = create_suite_panel(main_panel) + create_label(suite_panel, "Suite:") + @suite_name_entry = create_entry(suite_panel) + create_button(suite_panel, "&Run\tRun the current suite", proc { @mediator.run_suite }) + + @test_progress_bar = create_progress_bar(main_panel) + + @info_panel = create_info_panel(main_panel) + create_label(@info_panel, "Tests:") + @test_count_label = create_label(@info_panel, "0") + create_label(@info_panel, "Assertions:") + @assertion_count_label = create_label(@info_panel, "0") + create_label(@info_panel, "Failures:") + @failure_count_label = create_label(@info_panel, "0") + create_label(@info_panel, "Errors:") + @error_count_label = create_label(@info_panel, "0") + + list_panel = create_list_panel(main_panel) + @fault_list = create_fault_list(list_panel) + + detail_panel = create_detail_panel(main_panel) + @detail_text = create_text(detail_panel) + end + + def create_application + app = FXApp.new("TestRunner", "Test::Unit") + app.init([]) + app + end + + def create_window(app) + FXMainWindow.new(app, "Test::Unit TestRunner", nil, nil, DECOR_ALL, 0, 0, 450) + end + + def create_tooltip(app) + FXTooltip.new(app) + end + + def create_main_panel(parent) + panel = FXVerticalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y) + panel.vSpacing = 10 + panel + end + + def create_suite_panel(parent) + FXHorizontalFrame.new(parent, LAYOUT_SIDE_LEFT | LAYOUT_FILL_X) + end + + def create_button(parent, text, action) + FXButton.new(parent, text).connect(SEL_COMMAND, &action) + end + + def create_progress_bar(parent) + FXProgressBar.new(parent, nil, 0, PROGRESSBAR_NORMAL | LAYOUT_FILL_X) + end + + def create_info_panel(parent) + FXMatrix.new(parent, 1, MATRIX_BY_ROWS | LAYOUT_FILL_X) + end + + def create_label(parent, text) + FXLabel.new(parent, text, nil, JUSTIFY_CENTER_X | LAYOUT_FILL_COLUMN) + end + + def create_list_panel(parent) + FXHorizontalFrame.new(parent, LAYOUT_FILL_X | FRAME_SUNKEN | FRAME_THICK) + end + + def create_fault_list(parent) + list = FXList.new(parent, 10, nil, 0, LIST_SINGLESELECT | LAYOUT_FILL_X) #, 0, 0, 0, 150) + list.connect(SEL_COMMAND) do |sender, sel, ptr| + if sender.retrieveItem(sender.currentItem).selected? + show_fault(sender.retrieveItem(sender.currentItem).fault) + else + clear_fault + end + end + list + end + + def create_detail_panel(parent) + FXHorizontalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK) + end + + def create_text(parent) + FXText.new(parent, nil, 0, TEXT_READONLY | LAYOUT_FILL_X | LAYOUT_FILL_Y) + end + + def create_entry(parent) + entry = FXTextField.new(parent, 30, nil, 0, TEXTFIELD_NORMAL | LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X) + entry.disable + entry + end + end + + class FaultListItem < FXListItem + attr_reader(:fault) + def initialize(fault) + super(fault.short_display) + @fault = fault + end + end + end + end + end +end + +if __FILE__ == $0 + Test::Unit::UI::Fox::TestRunner.start_command_line_test +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/gtk/testrunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/gtk/testrunner.rb new file mode 100644 index 00000000..994328dc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/gtk/testrunner.rb @@ -0,0 +1,416 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'gtk' +require 'test/unit/ui/testrunnermediator' +require 'test/unit/ui/testrunnerutilities' + +module Test + module Unit + module UI + module GTK + + # Runs a Test::Unit::TestSuite in a Gtk UI. Obviously, + # this one requires you to have Gtk + # (http://www.gtk.org/) and the Ruby Gtk extension + # (http://ruby-gnome.sourceforge.net/) installed. + class TestRunner + extend TestRunnerUtilities + + # Creates a new TestRunner for running the passed + # suite. + def initialize(suite, output_level = NORMAL) + if (suite.respond_to?(:suite)) + @suite = suite.suite + else + @suite = suite + end + @result = nil + + @runner = Thread.current + @restart_signal = Class.new(Exception) + @viewer = Thread.start do + @runner.join rescue @runner.run + Gtk.main + end + @viewer.join rescue nil # wait deadlock to handshake + end + + # Begins the test run. + def start + setup_mediator + setup_ui + attach_to_mediator + start_ui + @result + end + + private + def setup_mediator + @mediator = TestRunnerMediator.new(@suite) + suite_name = @suite.to_s + if ( @suite.kind_of?(Module) ) + suite_name = @suite.name + end + suite_name_entry.set_text(suite_name) + end + + def attach_to_mediator + run_button.signal_connect("clicked", nil, &method(:run_test)) + @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui)) + @mediator.add_listener(TestResult::FAULT, &method(:add_fault)) + @mediator.add_listener(TestResult::CHANGED, &method(:result_changed)) + @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) + @mediator.add_listener(TestCase::STARTED, &method(:test_started)) + @mediator.add_listener(TestCase::FINISHED, &method(:test_finished)) + @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) + end + + def run_test(*) + @runner.raise(@restart_signal) + end + + def start_ui + @viewer.run + running = false + begin + loop do + if (running ^= true) + run_button.child.text = "Stop" + @mediator.run_suite + else + run_button.child.text = "Run" + @viewer.join + break + end + end + rescue @restart_signal + retry + rescue + end + end + + def stop(*) + Gtk.main_quit + end + + def reset_ui(count) + test_progress_bar.set_style(green_style) + test_progress_bar.configure(0, 0, count) + @red = false + + run_count_label.set_text("0") + assertion_count_label.set_text("0") + failure_count_label.set_text("0") + error_count_label.set_text("0") + + fault_list.remove_items(fault_list.children) + end + + def add_fault(fault) + if ( ! @red ) + test_progress_bar.set_style(red_style) + @red = true + end + item = FaultListItem.new(fault) + item.show + fault_list.append_items([item]) + end + + def show_fault(fault) + raw_show_fault(fault.long_display) + end + + def raw_show_fault(string) + fault_detail_label.set_text(string) + outer_detail_sub_panel.queue_resize + end + + def clear_fault + raw_show_fault("") + end + + def result_changed(result) + run_count_label.set_text(result.run_count.to_s) + assertion_count_label.set_text(result.assertion_count.to_s) + failure_count_label.set_text(result.failure_count.to_s) + error_count_label.set_text(result.error_count.to_s) + end + + def started(result) + @result = result + output_status("Started...") + end + + def test_started(test_name) + output_status("Running #{test_name}...") + end + + def test_finished(test_name) + test_progress_bar.set_value(test_progress_bar.get_value + 1) + end + + def finished(elapsed_time) + output_status("Finished in #{elapsed_time} seconds") + end + + def output_status(string) + status_entry.set_text(string) + end + + def setup_ui + main_window.signal_connect("destroy", nil, &method(:stop)) + main_window.show_all + fault_list.signal_connect("select-child", nil) { + | list, item, data | + show_fault(item.fault) + } + fault_list.signal_connect("unselect-child", nil) { + clear_fault + } + @red = false + end + + def main_window + lazy_initialize(:main_window) { + @main_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL) + @main_window.set_title("Test::Unit TestRunner") + @main_window.set_usize(800, 600) + @main_window.set_uposition(20, 20) + @main_window.set_policy(true, true, false) + @main_window.add(main_panel) + } + end + + def main_panel + lazy_initialize(:main_panel) { + @main_panel = Gtk::VBox.new(false, 0) + @main_panel.pack_start(suite_panel, false, false, 0) + @main_panel.pack_start(progress_panel, false, false, 0) + @main_panel.pack_start(info_panel, false, false, 0) + @main_panel.pack_start(list_panel, false, false, 0) + @main_panel.pack_start(detail_panel, true, true, 0) + @main_panel.pack_start(status_panel, false, false, 0) + } + end + + def suite_panel + lazy_initialize(:suite_panel) { + @suite_panel = Gtk::HBox.new(false, 10) + @suite_panel.border_width(10) + @suite_panel.pack_start(Gtk::Label.new("Suite:"), false, false, 0) + @suite_panel.pack_start(suite_name_entry, true, true, 0) + @suite_panel.pack_start(run_button, false, false, 0) + } + end + + def suite_name_entry + lazy_initialize(:suite_name_entry) { + @suite_name_entry = Gtk::Entry.new + @suite_name_entry.set_editable(false) + } + end + + def run_button + lazy_initialize(:run_button) { + @run_button = Gtk::Button.new("Run") + } + end + + def progress_panel + lazy_initialize(:progress_panel) { + @progress_panel = Gtk::HBox.new(false, 10) + @progress_panel.border_width(10) + @progress_panel.pack_start(test_progress_bar, true, true, 0) + } + end + + def test_progress_bar + lazy_initialize(:test_progress_bar) { + @test_progress_bar = EnhancedProgressBar.new + @test_progress_bar.set_usize(@test_progress_bar.allocation.width, + info_panel.size_request.height) + @test_progress_bar.set_style(green_style) + } + end + + def green_style + lazy_initialize(:green_style) { + @green_style = Gtk::Style.new + @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000) + } + end + + def red_style + lazy_initialize(:red_style) { + @red_style = Gtk::Style.new + @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000) + } + end + + def info_panel + lazy_initialize(:info_panel) { + @info_panel = Gtk::HBox.new(false, 0) + @info_panel.border_width(10) + @info_panel.pack_start(Gtk::Label.new("Runs:"), false, false, 0) + @info_panel.pack_start(run_count_label, true, false, 0) + @info_panel.pack_start(Gtk::Label.new("Assertions:"), false, false, 0) + @info_panel.pack_start(assertion_count_label, true, false, 0) + @info_panel.pack_start(Gtk::Label.new("Failures:"), false, false, 0) + @info_panel.pack_start(failure_count_label, true, false, 0) + @info_panel.pack_start(Gtk::Label.new("Errors:"), false, false, 0) + @info_panel.pack_start(error_count_label, true, false, 0) + } + end + + def run_count_label + lazy_initialize(:run_count_label) { + @run_count_label = Gtk::Label.new("0") + @run_count_label.set_justify(Gtk::JUSTIFY_LEFT) + } + end + + def assertion_count_label + lazy_initialize(:assertion_count_label) { + @assertion_count_label = Gtk::Label.new("0") + @assertion_count_label.set_justify(Gtk::JUSTIFY_LEFT) + } + end + + def failure_count_label + lazy_initialize(:failure_count_label) { + @failure_count_label = Gtk::Label.new("0") + @failure_count_label.set_justify(Gtk::JUSTIFY_LEFT) + } + end + + def error_count_label + lazy_initialize(:error_count_label) { + @error_count_label = Gtk::Label.new("0") + @error_count_label.set_justify(Gtk::JUSTIFY_LEFT) + } + end + + def list_panel + lazy_initialize(:list_panel) { + @list_panel = Gtk::HBox.new + @list_panel.border_width(10) + @list_panel.pack_start(list_scrolled_window, true, true, 0) + } + end + + def list_scrolled_window + lazy_initialize(:list_scrolled_window) { + @list_scrolled_window = Gtk::ScrolledWindow.new + @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + @list_scrolled_window.set_usize(@list_scrolled_window.allocation.width, 150) + @list_scrolled_window.add_with_viewport(fault_list) + } + end + + def fault_list + lazy_initialize(:fault_list) { + @fault_list = Gtk::List.new + } + end + + def detail_panel + lazy_initialize(:detail_panel) { + @detail_panel = Gtk::HBox.new + @detail_panel.border_width(10) + @detail_panel.pack_start(detail_scrolled_window, true, true, 0) + } + end + + def detail_scrolled_window + lazy_initialize(:detail_scrolled_window) { + @detail_scrolled_window = Gtk::ScrolledWindow.new + @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + @detail_scrolled_window.set_usize(400, @detail_scrolled_window.allocation.height) + @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel) + } + end + + def outer_detail_sub_panel + lazy_initialize(:outer_detail_sub_panel) { + @outer_detail_sub_panel = Gtk::VBox.new + @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0) + } + end + + def inner_detail_sub_panel + lazy_initialize(:inner_detail_sub_panel) { + @inner_detail_sub_panel = Gtk::HBox.new + @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0) + } + end + + def fault_detail_label + lazy_initialize(:fault_detail_label) { + @fault_detail_label = EnhancedLabel.new("") + style = Gtk::Style.new + font = Gdk::Font.font_load("-*-Courier New-medium-r-normal--*-120-*-*-*-*-*-*") + begin + style.set_font(font) + rescue ArgumentError; end + @fault_detail_label.set_style(style) + @fault_detail_label.set_justify(Gtk::JUSTIFY_LEFT) + @fault_detail_label.set_line_wrap(false) + } + end + + def status_panel + lazy_initialize(:status_panel) { + @status_panel = Gtk::HBox.new + @status_panel.border_width(10) + @status_panel.pack_start(status_entry, true, true, 0) + } + end + + def status_entry + lazy_initialize(:status_entry) { + @status_entry = Gtk::Entry.new + @status_entry.set_editable(false) + } + end + + def lazy_initialize(symbol) + if (!instance_eval("defined?(@#{symbol.to_s})")) + yield + end + return instance_eval("@" + symbol.to_s) + end + end + + class EnhancedProgressBar < Gtk::ProgressBar + def set_style(style) + super + hide + show + end + end + + class EnhancedLabel < Gtk::Label + def set_text(text) + super(text.gsub(/\n\t/, "\n" + (" " * 4))) + end + end + + class FaultListItem < Gtk::ListItem + attr_reader(:fault) + def initialize(fault) + super(fault.short_display) + @fault = fault + end + end + end + end + end +end + +if __FILE__ == $0 + Test::Unit::UI::GTK::TestRunner.start_command_line_test +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/gtk2/testrunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/gtk2/testrunner.rb new file mode 100644 index 00000000..b05549c0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/gtk2/testrunner.rb @@ -0,0 +1,465 @@ +#-- +# +# Author:: Kenta MURATA. +# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved. +# License:: Ruby license. + +require "gtk2" +require "test/unit/ui/testrunnermediator" +require "test/unit/ui/testrunnerutilities" + +module Test + module Unit + module UI + module GTK2 + + Gtk.init + + class EnhancedLabel < Gtk::Label + def set_text(text) + super(text.gsub(/\n\t/, "\n ")) + end + end + + class FaultList < Gtk::TreeView + def initialize + @faults = [] + @model = Gtk::ListStore.new(String, String) + super(@model) + column = Gtk::TreeViewColumn.new + column.visible = false + append_column(column) + renderer = Gtk::CellRendererText.new + column = Gtk::TreeViewColumn.new("Failures", renderer, {:text => 1}) + append_column(column) + selection.mode = Gtk::SELECTION_SINGLE + set_rules_hint(true) + set_headers_visible(false) + end # def initialize + + def add_fault(fault) + @faults.push(fault) + iter = @model.append + iter.set_value(0, (@faults.length - 1).to_s) + iter.set_value(1, fault.short_display) + end # def add_fault(fault) + + def get_fault(iter) + @faults[iter.get_value(0).to_i] + end # def get_fault + + def clear + model.clear + end # def clear + end + + class TestRunner + extend TestRunnerUtilities + + def lazy_initialize(symbol) + if !instance_eval("defined?(@#{symbol})") then + yield + end + return instance_eval("@#{symbol}") + end + private :lazy_initialize + + def status_entry + lazy_initialize(:status_entry) do + @status_entry = Gtk::Entry.new + @status_entry.editable = false + end + end + private :status_entry + + def status_panel + lazy_initialize(:status_panel) do + @status_panel = Gtk::HBox.new + @status_panel.border_width = 10 + @status_panel.pack_start(status_entry, true, true, 0) + end + end + private :status_panel + + def fault_detail_label + lazy_initialize(:fault_detail_label) do + @fault_detail_label = EnhancedLabel.new("") +# style = Gtk::Style.new +# font = Gdk::Font. +# font_load("-*-Courier 10 Pitch-medium-r-normal--*-120-*-*-*-*-*-*") +# style.set_font(font) +# @fault_detail_label.style = style + @fault_detail_label.justify = Gtk::JUSTIFY_LEFT + @fault_detail_label.wrap = false + end + end + private :fault_detail_label + + def inner_detail_sub_panel + lazy_initialize(:inner_detail_sub_panel) do + @inner_detail_sub_panel = Gtk::HBox.new + @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0) + end + end + private :inner_detail_sub_panel + + def outer_detail_sub_panel + lazy_initialize(:outer_detail_sub_panel) do + @outer_detail_sub_panel = Gtk::VBox.new + @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0) + end + end + private :outer_detail_sub_panel + + def detail_scrolled_window + lazy_initialize(:detail_scrolled_window) do + @detail_scrolled_window = Gtk::ScrolledWindow.new + @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + @detail_scrolled_window. + set_size_request(400, @detail_scrolled_window.allocation.height) + @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel) + end + end + private :detail_scrolled_window + + def detail_panel + lazy_initialize(:detail_panel) do + @detail_panel = Gtk::HBox.new + @detail_panel.border_width = 10 + @detail_panel.pack_start(detail_scrolled_window, true, true, 0) + end + end + private :detail_panel + + def fault_list + lazy_initialize(:fault_list) do + @fault_list = FaultList.new + end + end + private :fault_list + + def list_scrolled_window + lazy_initialize(:list_scrolled_window) do + @list_scrolled_window = Gtk::ScrolledWindow.new + @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + @list_scrolled_window. + set_size_request(@list_scrolled_window.allocation.width, 150) + @list_scrolled_window.add_with_viewport(fault_list) + end + end + private :list_scrolled_window + + def list_panel + lazy_initialize(:list_panel) do + @list_panel = Gtk::HBox.new + @list_panel.border_width = 10 + @list_panel.pack_start(list_scrolled_window, true, true, 0) + end + end + private :list_panel + + def error_count_label + lazy_initialize(:error_count_label) do + @error_count_label = Gtk::Label.new("0") + @error_count_label.justify = Gtk::JUSTIFY_LEFT + end + end + private :error_count_label + + def failure_count_label + lazy_initialize(:failure_count_label) do + @failure_count_label = Gtk::Label.new("0") + @failure_count_label.justify = Gtk::JUSTIFY_LEFT + end + end + private :failure_count_label + + def assertion_count_label + lazy_initialize(:assertion_count_label) do + @assertion_count_label = Gtk::Label.new("0") + @assertion_count_label.justify = Gtk::JUSTIFY_LEFT + end + end + private :assertion_count_label + + def run_count_label + lazy_initialize(:run_count_label) do + @run_count_label = Gtk::Label.new("0") + @run_count_label.justify = Gtk::JUSTIFY_LEFT + end + end + private :run_count_label + + def info_panel + lazy_initialize(:info_panel) do + @info_panel = Gtk::HBox.new(false, 0) + @info_panel.border_width = 10 + @info_panel.pack_start(Gtk::Label.new("Runs:"), false, false, 0) + @info_panel.pack_start(run_count_label, true, false, 0) + @info_panel.pack_start(Gtk::Label.new("Assertions:"), false, false, 0) + @info_panel.pack_start(assertion_count_label, true, false, 0) + @info_panel.pack_start(Gtk::Label.new("Failures:"), false, false, 0) + @info_panel.pack_start(failure_count_label, true, false, 0) + @info_panel.pack_start(Gtk::Label.new("Errors:"), false, false, 0) + @info_panel.pack_start(error_count_label, true, false, 0) + end + end # def info_panel + private :info_panel + + def green_style + lazy_initialize(:green_style) do + @green_style = Gtk::Style.new + @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000) + end + end # def green_style + private :green_style + + def red_style + lazy_initialize(:red_style) do + @red_style = Gtk::Style.new + @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000) + end + end # def red_style + private :red_style + + def test_progress_bar + lazy_initialize(:test_progress_bar) { + @test_progress_bar = Gtk::ProgressBar.new + @test_progress_bar.fraction = 0.0 + @test_progress_bar. + set_size_request(@test_progress_bar.allocation.width, + info_panel.size_request[1]) + @test_progress_bar.style = green_style + } + end # def test_progress_bar + private :test_progress_bar + + def progress_panel + lazy_initialize(:progress_panel) do + @progress_panel = Gtk::HBox.new(false, 10) + @progress_panel.border_width = 10 + @progress_panel.pack_start(test_progress_bar, true, true, 0) + end + end # def progress_panel + + def run_button + lazy_initialize(:run_button) do + @run_button = Gtk::Button.new("Run") + end + end # def run_button + + def suite_name_entry + lazy_initialize(:suite_name_entry) do + @suite_name_entry = Gtk::Entry.new + @suite_name_entry.editable = false + end + end # def suite_name_entry + private :suite_name_entry + + def suite_panel + lazy_initialize(:suite_panel) do + @suite_panel = Gtk::HBox.new(false, 10) + @suite_panel.border_width = 10 + @suite_panel.pack_start(Gtk::Label.new("Suite:"), false, false, 0) + @suite_panel.pack_start(suite_name_entry, true, true, 0) + @suite_panel.pack_start(run_button, false, false, 0) + end + end # def suite_panel + private :suite_panel + + def main_panel + lazy_initialize(:main_panel) do + @main_panel = Gtk::VBox.new(false, 0) + @main_panel.pack_start(suite_panel, false, false, 0) + @main_panel.pack_start(progress_panel, false, false, 0) + @main_panel.pack_start(info_panel, false, false, 0) + @main_panel.pack_start(list_panel, false, false, 0) + @main_panel.pack_start(detail_panel, true, true, 0) + @main_panel.pack_start(status_panel, false, false, 0) + end + end # def main_panel + private :main_panel + + def main_window + lazy_initialize(:main_window) do + @main_window = Gtk::Window.new(Gtk::Window::TOPLEVEL) + @main_window.set_title("Test::Unit TestRunner") + @main_window.set_default_size(800, 600) + @main_window.set_resizable(true) + @main_window.add(main_panel) + end + end # def main_window + private :main_window + + def setup_ui + main_window.signal_connect("destroy", nil) { stop } + main_window.show_all + fault_list.selection.signal_connect("changed", nil) do + |selection, data| + if selection.selected then + show_fault(fault_list.get_fault(selection.selected)) + else + clear_fault + end + end + end # def setup_ui + private :setup_ui + + def output_status(string) + status_entry.set_text(string) + end # def output_status(string) + private :output_status + + def finished(elapsed_time) + test_progress_bar.fraction = 1.0 + output_status("Finished in #{elapsed_time} seconds") + end # def finished(elapsed_time) + private :finished + + def test_started(test_name) + output_status("Running #{test_name}...") + end # def test_started(test_name) + private :test_started + + def started(result) + @result = result + output_status("Started...") + end # def started(result) + private :started + + def test_finished(result) + test_progress_bar.fraction += 1.0 / @count + end # def test_finished(result) + + def result_changed(result) + run_count_label.label = result.run_count.to_s + assertion_count_label.label = result.assertion_count.to_s + failure_count_label.label = result.failure_count.to_s + error_count_label.label = result.error_count.to_s + end # def result_changed(result) + private :result_changed + + def clear_fault + raw_show_fault("") + end # def clear_fault + private :clear_fault + + def raw_show_fault(string) + fault_detail_label.set_text(string) + outer_detail_sub_panel.queue_resize + end # def raw_show_fault(string) + private :raw_show_fault + + def show_fault(fault) + raw_show_fault(fault.long_display) + end # def show_fault(fault) + private :show_fault + + def add_fault(fault) + if not @red then + test_progress_bar.style = red_style + @red = true + end + fault_list.add_fault(fault) + end # def add_fault(fault) + private :add_fault + + def reset_ui(count) + test_progress_bar.style = green_style + test_progress_bar.fraction = 0.0 + @count = count + 1 + @red = false + + run_count_label.set_text("0") + assertion_count_label.set_text("0") + failure_count_label.set_text("0") + error_count_label.set_text("0") + + fault_list.clear + end # def reset_ui(count) + private :reset_ui + + def stop + Gtk.main_quit + end # def stop + private :stop + + def run_test + @runner.raise(@restart_signal) + end + private :run_test + + def start_ui + @viewer.run + running = false + begin + loop do + if (running ^= true) + run_button.child.text = "Stop" + @mediator.run_suite + else + run_button.child.text = "Run" + @viewer.join + break + end + end + rescue @restart_signal + retry + rescue + end + end # def start_ui + private :start_ui + + def attach_to_mediator + run_button.signal_connect("clicked", nil) { run_test } + @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui)) + @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) + @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) + @mediator.add_listener(TestResult::FAULT, &method(:add_fault)) + @mediator.add_listener(TestResult::CHANGED, &method(:result_changed)) + @mediator.add_listener(TestCase::STARTED, &method(:test_started)) + @mediator.add_listener(TestCase::FINISHED, &method(:test_finished)) + end # def attach_to_mediator + private :attach_to_mediator + + def setup_mediator + @mediator = TestRunnerMediator.new(@suite) + suite_name = @suite.to_s + if @suite.kind_of?(Module) then + suite_name = @suite.name + end + suite_name_entry.set_text(suite_name) + end # def setup_mediator + private :setup_mediator + + def start + setup_mediator + setup_ui + attach_to_mediator + start_ui + @result + end # def start + + def initialize(suite, output_level = NORMAL) + if suite.respond_to?(:suite) then + @suite = suite.suite + else + @suite = suite + end + @result = nil + + @runner = Thread.current + @restart_signal = Class.new(Exception) + @viewer = Thread.start do + @runner.join rescue @runner.run + Gtk.main + end + @viewer.join rescue nil # wait deadlock to handshake + end # def initialize(suite) + + end # class TestRunner + + end # module GTK2 + end # module UI + end # module Unit +end # module Test diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb new file mode 100644 index 00000000..d34510d1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb @@ -0,0 +1,68 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit' +require 'test/unit/util/observable' +require 'test/unit/testresult' + +module Test + module Unit + module UI + + # Provides an interface to write any given UI against, + # hopefully making it easy to write new UIs. + class TestRunnerMediator + RESET = name + "::RESET" + STARTED = name + "::STARTED" + FINISHED = name + "::FINISHED" + + include Util::Observable + + # Creates a new TestRunnerMediator initialized to run + # the passed suite. + def initialize(suite) + @suite = suite + end + + # Runs the suite the TestRunnerMediator was created + # with. + def run_suite + Unit.run = true + begin_time = Time.now + notify_listeners(RESET, @suite.size) + result = create_result + notify_listeners(STARTED, result) + result_listener = result.add_listener(TestResult::CHANGED) do |updated_result| + notify_listeners(TestResult::CHANGED, updated_result) + end + + fault_listener = result.add_listener(TestResult::FAULT) do |fault| + notify_listeners(TestResult::FAULT, fault) + end + + @suite.run(result) do |channel, value| + notify_listeners(channel, value) + end + + result.remove_listener(TestResult::FAULT, fault_listener) + result.remove_listener(TestResult::CHANGED, result_listener) + end_time = Time.now + elapsed_time = end_time - begin_time + notify_listeners(FINISHED, elapsed_time) #"Finished in #{elapsed_time} seconds.") + return result + end + + private + # A factory method to create the result the mediator + # should run with. Can be overridden by subclasses if + # one wants to use a different result. + def create_result + return TestResult.new + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb new file mode 100644 index 00000000..70b885bd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb @@ -0,0 +1,46 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + module UI + + SILENT = 0 + PROGRESS_ONLY = 1 + NORMAL = 2 + VERBOSE = 3 + + # Provides some utilities common to most, if not all, + # TestRunners. + # + #-- + # + # Perhaps there ought to be a TestRunner superclass? There + # seems to be a decent amount of shared code between test + # runners. + + module TestRunnerUtilities + + # Creates a new TestRunner and runs the suite. + def run(suite, output_level=NORMAL) + return new(suite, output_level).start + end + + # Takes care of the ARGV parsing and suite + # determination necessary for running one of the + # TestRunners from the command line. + def start_command_line_test + if ARGV.empty? + puts "You should supply the name of a test suite file to the runner" + exit + end + require ARGV[0].gsub(/.+::/, '') + new(eval(ARGV[0])).start + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/tk/testrunner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/tk/testrunner.rb new file mode 100644 index 00000000..4d05f2fb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/ui/tk/testrunner.rb @@ -0,0 +1,260 @@ +#-- +# +# Original Author:: Nathaniel Talbott. +# Author:: Kazuhiro NISHIYAMA. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# Copyright:: Copyright (c) 2003 Kazuhiro NISHIYAMA. All rights reserved. +# License:: Ruby license. + +require 'tk' +require 'test/unit/ui/testrunnermediator' +require 'test/unit/ui/testrunnerutilities' + +module Test + module Unit + module UI + module Tk + + # Runs a Test::Unit::TestSuite in a Tk UI. Obviously, + # this one requires you to have Tk + # and the Ruby Tk extension installed. + class TestRunner + extend TestRunnerUtilities + + # Creates a new TestRunner for running the passed + # suite. + def initialize(suite, output_level = NORMAL) + if (suite.respond_to?(:suite)) + @suite = suite.suite + else + @suite = suite + end + @result = nil + + @red = false + @fault_detail_list = [] + @runner = Thread.current + @restart_signal = Class.new(Exception) + @viewer = Thread.start do + @runner.join rescue @runner.run + ::Tk.mainloop + end + @viewer.join rescue nil # wait deadlock to handshake + end + + # Begins the test run. + def start + setup_ui + setup_mediator + attach_to_mediator + start_ui + @result + end + + private + def setup_mediator + @mediator = TestRunnerMediator.new(@suite) + suite_name = @suite.to_s + if ( @suite.kind_of?(Module) ) + suite_name = @suite.name + end + @suite_name_entry.value = suite_name + end + + def attach_to_mediator + @run_button.command(method(:run_test)) + @fault_list.bind('ButtonPress-1', proc{|y| + fault = @fault_detail_list[@fault_list.nearest(y)] + if fault + show_fault(fault) + end + }, '%y') + @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui)) + @mediator.add_listener(TestResult::FAULT, &method(:add_fault)) + @mediator.add_listener(TestResult::CHANGED, &method(:result_changed)) + @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started)) + @mediator.add_listener(TestCase::STARTED, &method(:test_started)) + @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished)) + end + + def run_test + @runner.raise(@restart_signal) + end + + def start_ui + @viewer.run + running = false + begin + loop do + if (running ^= true) + @run_button.configure('text'=>'Stop') + @mediator.run_suite + else + @run_button.configure('text'=>'Run') + @viewer.join + break + end + end + rescue @restart_signal + retry + rescue + end + end + + def stop + ::Tk.exit + end + + def reset_ui(count) + @test_total_count = count.to_f + @test_progress_bar.configure('background'=>'green') + @test_progress_bar.place('relwidth'=>(count.zero? ? 0 : 0/count)) + @red = false + + @test_count_label.value = 0 + @assertion_count_label.value = 0 + @failure_count_label.value = 0 + @error_count_label.value = 0 + + @fault_list.delete(0, 'end') + @fault_detail_list = [] + clear_fault + end + + def add_fault(fault) + if ( ! @red ) + @test_progress_bar.configure('background'=>'red') + @red = true + end + @fault_detail_list.push fault + @fault_list.insert('end', fault.short_display) + end + + def show_fault(fault) + raw_show_fault(fault.long_display) + end + + def raw_show_fault(string) + @detail_text.value = string + end + + def clear_fault + raw_show_fault("") + end + + def result_changed(result) + @test_count_label.value = result.run_count + @test_progress_bar.place('relwidth'=>result.run_count/@test_total_count) + @assertion_count_label.value = result.assertion_count + @failure_count_label.value = result.failure_count + @error_count_label.value = result.error_count + end + + def started(result) + @result = result + output_status("Started...") + end + + def test_started(test_name) + output_status("Running #{test_name}...") + end + + def finished(elapsed_time) + output_status("Finished in #{elapsed_time} seconds") + end + + def output_status(string) + @status_entry.value = string + end + + def setup_ui + @status_entry = TkVariable.new + l = TkLabel.new(nil, 'textvariable'=>@status_entry, 'relief'=>'sunken') + l.pack('side'=>'bottom', 'fill'=>'x') + + suite_frame = TkFrame.new.pack('fill'=>'x') + + @run_button = TkButton.new(suite_frame, 'text'=>'Run') + @run_button.pack('side'=>'right') + + TkLabel.new(suite_frame, 'text'=>'Suite:').pack('side'=>'left') + @suite_name_entry = TkVariable.new + l = TkLabel.new(suite_frame, 'textvariable'=>@suite_name_entry, 'relief'=>'sunken') + l.pack('side'=>'left', 'fill'=>'x', 'expand'=>true) + + f = TkFrame.new(nil, 'relief'=>'sunken', 'borderwidth'=>3, 'height'=>20).pack('fill'=>'x', 'padx'=>1) + @test_progress_bar = TkFrame.new(f, 'background'=>'green').place('anchor'=>'nw', 'relwidth'=>0.0, 'relheight'=>1.0) + + info_frame = TkFrame.new.pack('fill'=>'x') + @test_count_label = create_count_label(info_frame, 'Tests:') + @assertion_count_label = create_count_label(info_frame, 'Assertions:') + @failure_count_label = create_count_label(info_frame, 'Failures:') + @error_count_label = create_count_label(info_frame, 'Errors:') + + if (::Tk.info('command', TkPanedWindow::TkCommandNames[0]) != "") + # use panedwindow + paned_frame = TkPanedWindow.new("orient"=>"vertical").pack('fill'=>'both', 'expand'=>true) + + fault_list_frame = TkFrame.new(paned_frame) + detail_frame = TkFrame.new(paned_frame) + + paned_frame.add(fault_list_frame, detail_frame) + else + # no panedwindow + paned_frame = nil + fault_list_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true) + detail_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true) + end + + TkGrid.rowconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0) + TkGrid.columnconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0) + + fault_scrollbar_y = TkScrollbar.new(fault_list_frame) + fault_scrollbar_x = TkScrollbar.new(fault_list_frame) + @fault_list = TkListbox.new(fault_list_frame) + @fault_list.yscrollbar(fault_scrollbar_y) + @fault_list.xscrollbar(fault_scrollbar_x) + + TkGrid.rowconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0) + TkGrid.columnconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0) + + ::Tk.grid(@fault_list, fault_scrollbar_y, 'sticky'=>'news') + ::Tk.grid(fault_scrollbar_x, 'sticky'=>'news') + + detail_scrollbar_y = TkScrollbar.new(detail_frame) + detail_scrollbar_x = TkScrollbar.new(detail_frame) + @detail_text = TkText.new(detail_frame, 'height'=>10, 'wrap'=>'none') { + bindtags(bindtags - [TkText]) + } + @detail_text.yscrollbar(detail_scrollbar_y) + @detail_text.xscrollbar(detail_scrollbar_x) + + ::Tk.grid(@detail_text, detail_scrollbar_y, 'sticky'=>'news') + ::Tk.grid(detail_scrollbar_x, 'sticky'=>'news') + + # rubber-style pane + if paned_frame + ::Tk.update + @height = paned_frame.winfo_height + paned_frame.bind('Configure', proc{|h| + paned_frame.sash_place(0, 0, paned_frame.sash_coord(0)[1] * h / @height) + @height = h + }, '%h') + end + end + + def create_count_label(parent, label) + TkLabel.new(parent, 'text'=>label).pack('side'=>'left', 'expand'=>true) + v = TkVariable.new(0) + TkLabel.new(parent, 'textvariable'=>v).pack('side'=>'left', 'expand'=>true) + v + end + end + end + end + end +end + +if __FILE__ == $0 + Test::Unit::UI::Tk::TestRunner.start_command_line_test +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/backtracefilter.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/backtracefilter.rb new file mode 100644 index 00000000..7ebec2df --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/backtracefilter.rb @@ -0,0 +1,40 @@ +module Test + module Unit + module Util + module BacktraceFilter + TESTUNIT_FILE_SEPARATORS = %r{[\\/:]} + TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3] + TESTUNIT_RB_FILE = /\.rb\Z/ + + def filter_backtrace(backtrace, prefix=nil) + return ["No backtrace"] unless(backtrace) + split_p = if(prefix) + prefix.split(TESTUNIT_FILE_SEPARATORS) + else + TESTUNIT_PREFIX + end + match = proc do |e| + split_e = e.split(TESTUNIT_FILE_SEPARATORS)[0, split_p.size] + next false unless(split_e[0..-2] == split_p[0..-2]) + split_e[-1].sub(TESTUNIT_RB_FILE, '') == split_p[-1] + end + return backtrace unless(backtrace.detect(&match)) + found_prefix = false + new_backtrace = backtrace.reverse.reject do |e| + if(match[e]) + found_prefix = true + true + elsif(found_prefix) + false + else + true + end + end.reverse + new_backtrace = (new_backtrace.empty? ? backtrace : new_backtrace) + new_backtrace = new_backtrace.reject(&match) + new_backtrace.empty? ? backtrace : new_backtrace + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/observable.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/observable.rb new file mode 100644 index 00000000..3567d342 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/observable.rb @@ -0,0 +1,90 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/util/procwrapper' + +module Test + module Unit + module Util + + # This is a utility class that allows anything mixing + # it in to notify a set of listeners about interesting + # events. + module Observable + # We use this for defaults since nil might mean something + NOTHING = "NOTHING/#{__id__}" + + # Adds the passed proc as a listener on the + # channel indicated by channel_name. listener_key + # is used to remove the listener later; if none is + # specified, the proc itself is used. + # + # Whatever is used as the listener_key is + # returned, making it very easy to use the proc + # itself as the listener_key: + # + # listener = add_listener("Channel") { ... } + # remove_listener("Channel", listener) + def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value + unless(block_given?) + raise ArgumentError.new("No callback was passed as a listener") + end + + key = listener_key + if (listener_key == NOTHING) + listener_key = listener + key = ProcWrapper.new(listener) + end + + channels[channel_name] ||= {} + channels[channel_name][key] = listener + return listener_key + end + + # Removes the listener indicated by listener_key + # from the channel indicated by + # channel_name. Returns the registered proc, or + # nil if none was found. + def remove_listener(channel_name, listener_key) + channel = channels[channel_name] + return nil unless (channel) + key = listener_key + if (listener_key.instance_of?(Proc)) + key = ProcWrapper.new(listener_key) + end + if (channel.has_key?(key)) + return channel.delete(key) + end + return nil + end + + # Calls all the procs registered on the channel + # indicated by channel_name. If value is + # specified, it is passed in to the procs, + # otherwise they are called with no arguments. + # + #-- + # + # Perhaps this should be private? Would it ever + # make sense for an external class to call this + # method directly? + def notify_listeners(channel_name, *arguments) + channel = channels[channel_name] + return 0 unless (channel) + listeners = channel.values + listeners.each { |listener| listener.call(*arguments) } + return listeners.size + end + + private + def channels + @channels ||= {} + return @channels + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/procwrapper.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/procwrapper.rb new file mode 100644 index 00000000..ad725218 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/test/unit/util/procwrapper.rb @@ -0,0 +1,48 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + module Util + + # Allows the storage of a Proc passed through '&' in a + # hash. + # + # Note: this may be inefficient, since the hash being + # used is not necessarily very good. In Observable, + # efficiency is not too important, since the hash is + # only accessed when adding and removing listeners, + # not when notifying. + + class ProcWrapper + + # Creates a new wrapper for a_proc. + def initialize(a_proc) + @a_proc = a_proc + @hash = a_proc.inspect.sub(/^(#<#{a_proc.class}:)/){''}.sub(/(>)$/){''}.hex + end + + def hash + return @hash + end + + def ==(other) + case(other) + when ProcWrapper + return @a_proc == other.to_proc + else + return super + end + end + alias :eql? :== + + def to_proc + return @a_proc + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/thread.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/thread.rb new file mode 100644 index 00000000..6c533aba --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/thread.rb @@ -0,0 +1,5 @@ +unless defined? Thread + fail "Thread not available for this ruby interpreter" +end + +require 'thread.so' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/thwait.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/thwait.rb new file mode 100644 index 00000000..95d294a8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/thwait.rb @@ -0,0 +1,169 @@ +# +# thwait.rb - thread synchronization class +# $Release Version: 0.9 $ +# $Revision: 1.3 $ +# $Date: 1998/06/26 03:19:34 $ +# by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.) +# +# -- +# feature: +# provides synchronization for multiple threads. +# +# class methods: +# * ThreadsWait.all_waits(thread1,...) +# waits until all of specified threads are terminated. +# if a block is supplied for the method, evaluates it for +# each thread termination. +# * th = ThreadsWait.new(thread1,...) +# creates synchronization object, specifying thread(s) to wait. +# +# methods: +# * th.threads +# list threads to be synchronized +# * th.empty? +# is there any thread to be synchronized. +# * th.finished? +# is there already terminated thread. +# * th.join(thread1,...) +# wait for specified thread(s). +# * th.join_nowait(threa1,...) +# specifies thread(s) to wait. non-blocking. +# * th.next_wait +# waits until any of specified threads is terminated. +# * th.all_waits +# waits until all of specified threads are terminated. +# if a block is supplied for the method, evaluates it for +# each thread termination. +# + +require "thread.rb" +require "e2mmap.rb" + +# +# This class watches for termination of multiple threads. Basic functionality +# (wait until specified threads have terminated) can be accessed through the +# class method ThreadsWait::all_waits. Finer control can be gained using +# instance methods. +# +# Example: +# +# ThreadsWait.all_wait(thr1, thr2, ...) do |t| +# STDERR.puts "Thread #{t} has terminated." +# end +# +class ThreadsWait + RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-' + + Exception2MessageMapper.extend_to(binding) + def_exception("ErrNoWaitingThread", "No threads for waiting.") + def_exception("ErrNoFinishedThread", "No finished threads.") + + # + # Waits until all specified threads have terminated. If a block is provided, + # it is executed for each thread termination. + # + def ThreadsWait.all_waits(*threads) # :yield: thread + tw = ThreadsWait.new(*threads) + if block_given? + tw.all_waits do |th| + yield th + end + else + tw.all_waits + end + end + + # + # Creates a ThreadsWait object, specifying the threads to wait on. + # Non-blocking. + # + def initialize(*threads) + @threads = [] + @wait_queue = Queue.new + join_nowait(*threads) unless threads.empty? + end + + # Returns the array of threads in the wait queue. + attr :threads + + # + # Returns +true+ if there are no threads to be synchronized. + # + def empty? + @threads.empty? + end + + # + # Returns +true+ if any thread has terminated. + # + def finished? + !@wait_queue.empty? + end + + # + # Waits for specified threads to terminate. + # + def join(*threads) + join_nowait(*threads) + next_wait + end + + # + # Specifies the threads that this object will wait for, but does not actually + # wait. + # + def join_nowait(*threads) + threads.flatten! + @threads.concat threads + for th in threads + Thread.start(th) do |t| + begin + t.join + ensure + @wait_queue.push t + end + end + end + end + + # + # Waits until any of the specified threads has terminated, and returns the one + # that does. + # + # If there is no thread to wait, raises +ErrNoWaitingThread+. If +nonblock+ + # is true, and there is no terminated thread, raises +ErrNoFinishedThread+. + # + def next_wait(nonblock = nil) + ThreadsWait.fail ErrNoWaitingThread if @threads.empty? + begin + @threads.delete(th = @wait_queue.pop(nonblock)) + th + rescue ThreadError + ThreadsWait.fail ErrNoFinishedThread + end + end + + # + # Waits until all of the specified threads are terminated. If a block is + # supplied for the method, it is executed for each thread termination. + # + # Raises exceptions in the same manner as +next_wait+. + # + def all_waits + until @threads.empty? + th = next_wait + yield th if block_given? + end + end +end + +ThWait = ThreadsWait + + +# Documentation comments: +# - Source of documentation is evenly split between Nutshell, existing +# comments, and my own rephrasing. +# - I'm not particularly confident that the comments are all exactly correct. +# - The history, etc., up the top appears in the RDoc output. Perhaps it would +# be better to direct that not to appear, and put something else there +# instead. diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/time.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/time.rb new file mode 100644 index 00000000..dbc25f41 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/time.rb @@ -0,0 +1,797 @@ + +# +# == Introduction +# +# This library extends the Time class: +# * conversion between date string and time object. +# * date-time defined by RFC 2822 +# * HTTP-date defined by RFC 2616 +# * dateTime defined by XML Schema Part 2: Datatypes (ISO 8601) +# * various formats handled by Date._parse (string to time only) +# +# == Design Issues +# +# === Specialized interface +# +# This library provides methods dedicated to special purposes: +# * RFC 2822, RFC 2616 and XML Schema. +# * They makes usual life easier. +# +# === Doesn't depend on strftime +# +# This library doesn't use +strftime+. Especially #rfc2822 doesn't depend +# on +strftime+ because: +# +# * %a and %b are locale sensitive +# +# Since they are locale sensitive, they may be replaced to +# invalid weekday/month name in some locales. +# Since ruby-1.6 doesn't invoke setlocale by default, +# the problem doesn't arise until some external library invokes setlocale. +# Ruby/GTK is the example of such library. +# +# * %z is not portable +# +# %z is required to generate zone in date-time of RFC 2822 +# but it is not portable. +# +# == Revision Information +# +# $Id$ +# + +require 'parsedate' + +# +# Implements the extensions to the Time class that are described in the +# documentation for the time.rb library. +# +class Time + class << Time + + ZoneOffset = { + 'UTC' => 0, + # ISO 8601 + 'Z' => 0, + # RFC 822 + 'UT' => 0, 'GMT' => 0, + 'EST' => -5, 'EDT' => -4, + 'CST' => -6, 'CDT' => -5, + 'MST' => -7, 'MDT' => -6, + 'PST' => -8, 'PDT' => -7, + # Following definition of military zones is original one. + # See RFC 1123 and RFC 2822 for the error in RFC 822. + 'A' => +1, 'B' => +2, 'C' => +3, 'D' => +4, 'E' => +5, 'F' => +6, + 'G' => +7, 'H' => +8, 'I' => +9, 'K' => +10, 'L' => +11, 'M' => +12, + 'N' => -1, 'O' => -2, 'P' => -3, 'Q' => -4, 'R' => -5, 'S' => -6, + 'T' => -7, 'U' => -8, 'V' => -9, 'W' => -10, 'X' => -11, 'Y' => -12, + } + def zone_offset(zone, year=Time.now.year) + off = nil + zone = zone.upcase + if /\A([+-])(\d\d):?(\d\d)\z/ =~ zone + off = ($1 == '-' ? -1 : 1) * ($2.to_i * 60 + $3.to_i) * 60 + elsif /\A[+-]\d\d\z/ =~ zone + off = zone.to_i * 3600 + elsif ZoneOffset.include?(zone) + off = ZoneOffset[zone] * 3600 + elsif ((t = Time.local(year, 1, 1)).zone.upcase == zone rescue false) + off = t.utc_offset + elsif ((t = Time.local(year, 7, 1)).zone.upcase == zone rescue false) + off = t.utc_offset + end + off + end + + def zone_utc?(zone) + # * +0000 means localtime. [RFC 2822] + # * GMT is a localtime abbreviation in Europe/London, etc. + if /\A(?:-00:00|-0000|-00|UTC|Z|UT)\z/i =~ zone + true + else + false + end + end + private :zone_utc? + + LeapYearMonthDays = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + CommonYearMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + def month_days(y, m) + if ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0) + LeapYearMonthDays[m-1] + else + CommonYearMonthDays[m-1] + end + end + private :month_days + + def apply_offset(year, mon, day, hour, min, sec, off) + if off < 0 + off = -off + off, o = off.divmod(60) + if o != 0 then sec += o; o, sec = sec.divmod(60); off += o end + off, o = off.divmod(60) + if o != 0 then min += o; o, min = min.divmod(60); off += o end + off, o = off.divmod(24) + if o != 0 then hour += o; o, hour = hour.divmod(24); off += o end + if off != 0 + day += off + if month_days(year, mon) < day + mon += 1 + if 12 < mon + mon = 1 + year += 1 + end + day = 1 + end + end + elsif 0 < off + off, o = off.divmod(60) + if o != 0 then sec -= o; o, sec = sec.divmod(60); off -= o end + off, o = off.divmod(60) + if o != 0 then min -= o; o, min = min.divmod(60); off -= o end + off, o = off.divmod(24) + if o != 0 then hour -= o; o, hour = hour.divmod(24); off -= o end + if off != 0 then + day -= off + if day < 1 + mon -= 1 + if mon < 1 + year -= 1 + mon = 12 + end + day = month_days(year, mon) + end + end + end + return year, mon, day, hour, min, sec + end + private :apply_offset + + def make_time(year, mon, day, hour, min, sec, sec_fraction, zone, now) + usec = nil + usec = (sec_fraction * 1000000).to_i if sec_fraction + if now + begin + break if year; year = now.year + break if mon; mon = now.mon + break if day; day = now.day + break if hour; hour = now.hour + break if min; min = now.min + break if sec; sec = now.sec + break if sec_fraction; usec = now.tv_usec + end until true + end + + year ||= 1970 + mon ||= 1 + day ||= 1 + hour ||= 0 + min ||= 0 + sec ||= 0 + usec ||= 0 + + off = nil + off = zone_offset(zone, year) if zone + + if off + year, mon, day, hour, min, sec = + apply_offset(year, mon, day, hour, min, sec, off) + t = Time.utc(year, mon, day, hour, min, sec, usec) + t.localtime if !zone_utc?(zone) + t + else + self.local(year, mon, day, hour, min, sec, usec) + end + end + private :make_time + + # + # Parses +date+ using Date._parse and converts it to a Time object. + # + # If a block is given, the year described in +date+ is converted by the + # block. For example: + # + # Time.parse(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y} + # + # If the upper components of the given time are broken or missing, they are + # supplied with those of +now+. For the lower components, the minimum + # values (1 or 0) are assumed if broken or missing. For example: + # + # # Suppose it is "Thu Nov 29 14:33:20 GMT 2001" now and + # # your timezone is GMT: + # Time.parse("16:30") #=> Thu Nov 29 16:30:00 GMT 2001 + # Time.parse("7/23") #=> Mon Jul 23 00:00:00 GMT 2001 + # Time.parse("Aug 31") #=> Fri Aug 31 00:00:00 GMT 2001 + # + # Since there are numerous conflicts among locally defined timezone + # abbreviations all over the world, this method is not made to + # understand all of them. For example, the abbreviation "CST" is + # used variously as: + # + # -06:00 in America/Chicago, + # -05:00 in America/Havana, + # +08:00 in Asia/Harbin, + # +09:30 in Australia/Darwin, + # +10:30 in Australia/Adelaide, + # etc. + # + # Based on the fact, this method only understands the timezone + # abbreviations described in RFC 822 and the system timezone, in the + # order named. (i.e. a definition in RFC 822 overrides the system + # timezone definition.) The system timezone is taken from + # Time.local(year, 1, 1).zone and + # Time.local(year, 7, 1).zone. + # If the extracted timezone abbreviation does not match any of them, + # it is ignored and the given time is regarded as a local time. + # + # ArgumentError is raised if Date._parse cannot extract information from + # +date+ or Time class cannot represent specified date. + # + # This method can be used as fail-safe for other parsing methods as: + # + # Time.rfc2822(date) rescue Time.parse(date) + # Time.httpdate(date) rescue Time.parse(date) + # Time.xmlschema(date) rescue Time.parse(date) + # + # A failure for Time.parse should be checked, though. + # + def parse(date, now=Time.now) + d = Date._parse(date, false) + year = d[:year] + year = yield(year) if year && block_given? + make_time(year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now) + end + + MonthValue = { + 'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6, + 'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' =>10, 'NOV' =>11, 'DEC' =>12 + } + + # + # Parses +date+ as date-time defined by RFC 2822 and converts it to a Time + # object. The format is identical to the date format defined by RFC 822 and + # updated by RFC 1123. + # + # ArgumentError is raised if +date+ is not compliant with RFC 2822 + # or Time class cannot represent specified date. + # + # See #rfc2822 for more information on this format. + # + def rfc2822(date) + if /\A\s* + (?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*,\s*)? + (\d{1,2})\s+ + (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+ + (\d{2,})\s+ + (\d{2})\s* + :\s*(\d{2})\s* + (?::\s*(\d{2}))?\s+ + ([+-]\d{4}| + UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date + # Since RFC 2822 permit comments, the regexp has no right anchor. + day = $1.to_i + mon = MonthValue[$2.upcase] + year = $3.to_i + hour = $4.to_i + min = $5.to_i + sec = $6 ? $6.to_i : 0 + zone = $7 + + # following year completion is compliant with RFC 2822. + year = if year < 50 + 2000 + year + elsif year < 1000 + 1900 + year + else + year + end + + year, mon, day, hour, min, sec = + apply_offset(year, mon, day, hour, min, sec, zone_offset(zone)) + t = self.utc(year, mon, day, hour, min, sec) + t.localtime if !zone_utc?(zone) + t + else + raise ArgumentError.new("not RFC 2822 compliant date: #{date.inspect}") + end + end + alias rfc822 rfc2822 + + # + # Parses +date+ as HTTP-date defined by RFC 2616 and converts it to a Time + # object. + # + # ArgumentError is raised if +date+ is not compliant with RFC 2616 or Time + # class cannot represent specified date. + # + # See #httpdate for more information on this format. + # + def httpdate(date) + if /\A\s* + (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\x20 + (\d{2})\x20 + (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20 + (\d{4})\x20 + (\d{2}):(\d{2}):(\d{2})\x20 + GMT + \s*\z/ix =~ date + self.rfc2822(date) + elsif /\A\s* + (?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\x20 + (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d)\x20 + (\d\d):(\d\d):(\d\d)\x20 + GMT + \s*\z/ix =~ date + self.parse(date) + elsif /\A\s* + (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\x20 + (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20 + (\d\d|\x20\d)\x20 + (\d\d):(\d\d):(\d\d)\x20 + (\d{4}) + \s*\z/ix =~ date + self.utc($6.to_i, MonthValue[$1.upcase], $2.to_i, + $3.to_i, $4.to_i, $5.to_i) + else + raise ArgumentError.new("not RFC 2616 compliant date: #{date.inspect}") + end + end + + # + # Parses +date+ as dateTime defined by XML Schema and converts it to a Time + # object. The format is restricted version of the format defined by ISO + # 8601. + # + # ArgumentError is raised if +date+ is not compliant with the format or Time + # class cannot represent specified date. + # + # See #xmlschema for more information on this format. + # + def xmlschema(date) + if /\A\s* + (-?\d+)-(\d\d)-(\d\d) + T + (\d\d):(\d\d):(\d\d) + (\.\d*)? + (Z|[+-]\d\d:\d\d)? + \s*\z/ix =~ date + year = $1.to_i + mon = $2.to_i + day = $3.to_i + hour = $4.to_i + min = $5.to_i + sec = $6.to_i + usec = 0 + usec = $7.to_f * 1000000 if $7 + if $8 + zone = $8 + year, mon, day, hour, min, sec = + apply_offset(year, mon, day, hour, min, sec, zone_offset(zone)) + Time.utc(year, mon, day, hour, min, sec, usec) + else + Time.local(year, mon, day, hour, min, sec, usec) + end + else + raise ArgumentError.new("invalid date: #{date.inspect}") + end + end + alias iso8601 xmlschema + end # class << self + + # + # Returns a string which represents the time as date-time defined by RFC 2822: + # + # day-of-week, DD month-name CCYY hh:mm:ss zone + # + # where zone is [+-]hhmm. + # + # If +self+ is a UTC time, -0000 is used as zone. + # + def rfc2822 + sprintf('%s, %02d %s %d %02d:%02d:%02d ', + RFC2822_DAY_NAME[wday], + day, RFC2822_MONTH_NAME[mon-1], year, + hour, min, sec) + + if utc? + '-0000' + else + off = utc_offset + sign = off < 0 ? '-' : '+' + sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60)) + end + end + alias rfc822 rfc2822 + + RFC2822_DAY_NAME = [ + 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' + ] + RFC2822_MONTH_NAME = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ] + + # + # Returns a string which represents the time as rfc1123-date of HTTP-date + # defined by RFC 2616: + # + # day-of-week, DD month-name CCYY hh:mm:ss GMT + # + # Note that the result is always UTC (GMT). + # + def httpdate + t = dup.utc + sprintf('%s, %02d %s %d %02d:%02d:%02d GMT', + RFC2822_DAY_NAME[t.wday], + t.day, RFC2822_MONTH_NAME[t.mon-1], t.year, + t.hour, t.min, t.sec) + end + + # + # Returns a string which represents the time as dateTime defined by XML + # Schema: + # + # CCYY-MM-DDThh:mm:ssTZD + # CCYY-MM-DDThh:mm:ss.sssTZD + # + # where TZD is Z or [+-]hh:mm. + # + # If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise. + # + # +fractional_seconds+ specifies a number of digits of fractional seconds. + # Its default value is 0. + # + def xmlschema(fraction_digits=0) + sprintf('%d-%02d-%02dT%02d:%02d:%02d', + year, mon, day, hour, min, sec) + + if fraction_digits == 0 + '' + elsif fraction_digits <= 6 + '.' + sprintf('%06d', usec)[0, fraction_digits] + else + '.' + sprintf('%06d', usec) + '0' * (fraction_digits - 6) + end + + if utc? + 'Z' + else + off = utc_offset + sign = off < 0 ? '-' : '+' + sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60)) + end + end + alias iso8601 xmlschema +end + +if __FILE__ == $0 + require 'test/unit' + + class TimeExtentionTest < Test::Unit::TestCase # :nodoc: + def test_rfc822 + assert_equal(Time.utc(1976, 8, 26, 14, 30) + 4 * 3600, + Time.rfc2822("26 Aug 76 14:30 EDT")) + assert_equal(Time.utc(1976, 8, 27, 9, 32) + 7 * 3600, + Time.rfc2822("27 Aug 76 09:32 PDT")) + end + + def test_rfc2822 + assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600, + Time.rfc2822("Fri, 21 Nov 1997 09:55:06 -0600")) + assert_equal(Time.utc(2003, 7, 1, 10, 52, 37) - 2 * 3600, + Time.rfc2822("Tue, 1 Jul 2003 10:52:37 +0200")) + assert_equal(Time.utc(1997, 11, 21, 10, 1, 10) + 6 * 3600, + Time.rfc2822("Fri, 21 Nov 1997 10:01:10 -0600")) + assert_equal(Time.utc(1997, 11, 21, 11, 0, 0) + 6 * 3600, + Time.rfc2822("Fri, 21 Nov 1997 11:00:00 -0600")) + assert_equal(Time.utc(1997, 11, 24, 14, 22, 1) + 8 * 3600, + Time.rfc2822("Mon, 24 Nov 1997 14:22:01 -0800")) + begin + Time.at(-1) + rescue ArgumentError + # ignore + else + assert_equal(Time.utc(1969, 2, 13, 23, 32, 54) + 3 * 3600 + 30 * 60, + Time.rfc2822("Thu, 13 Feb 1969 23:32:54 -0330")) + assert_equal(Time.utc(1969, 2, 13, 23, 32, 0) + 3 * 3600 + 30 * 60, + Time.rfc2822(" Thu, + 13 + Feb + 1969 + 23:32 + -0330 (Newfoundland Time)")) + end + assert_equal(Time.utc(1997, 11, 21, 9, 55, 6), + Time.rfc2822("21 Nov 97 09:55:06 GMT")) + assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600, + Time.rfc2822("Fri, 21 Nov 1997 09 : 55 : 06 -0600")) + assert_raise(ArgumentError) { + # inner comment is not supported. + Time.rfc2822("Fri, 21 Nov 1997 09(comment): 55 : 06 -0600") + } + end + + def test_rfc2616 + t = Time.utc(1994, 11, 6, 8, 49, 37) + assert_equal(t, Time.httpdate("Sun, 06 Nov 1994 08:49:37 GMT")) + assert_equal(t, Time.httpdate("Sunday, 06-Nov-94 08:49:37 GMT")) + assert_equal(t, Time.httpdate("Sun Nov 6 08:49:37 1994")) + assert_equal(Time.utc(1995, 11, 15, 6, 25, 24), + Time.httpdate("Wed, 15 Nov 1995 06:25:24 GMT")) + assert_equal(Time.utc(1995, 11, 15, 4, 58, 8), + Time.httpdate("Wed, 15 Nov 1995 04:58:08 GMT")) + assert_equal(Time.utc(1994, 11, 15, 8, 12, 31), + Time.httpdate("Tue, 15 Nov 1994 08:12:31 GMT")) + assert_equal(Time.utc(1994, 12, 1, 16, 0, 0), + Time.httpdate("Thu, 01 Dec 1994 16:00:00 GMT")) + assert_equal(Time.utc(1994, 10, 29, 19, 43, 31), + Time.httpdate("Sat, 29 Oct 1994 19:43:31 GMT")) + assert_equal(Time.utc(1994, 11, 15, 12, 45, 26), + Time.httpdate("Tue, 15 Nov 1994 12:45:26 GMT")) + assert_equal(Time.utc(1999, 12, 31, 23, 59, 59), + Time.httpdate("Fri, 31 Dec 1999 23:59:59 GMT")) + end + + def test_rfc3339 + t = Time.utc(1985, 4, 12, 23, 20, 50, 520000) + s = "1985-04-12T23:20:50.52Z" + assert_equal(t, Time.iso8601(s)) + assert_equal(s, t.iso8601(2)) + + t = Time.utc(1996, 12, 20, 0, 39, 57) + s = "1996-12-19T16:39:57-08:00" + assert_equal(t, Time.iso8601(s)) + # There is no way to generate time string with arbitrary timezone. + s = "1996-12-20T00:39:57Z" + assert_equal(t, Time.iso8601(s)) + assert_equal(s, t.iso8601) + + t = Time.utc(1990, 12, 31, 23, 59, 60) + s = "1990-12-31T23:59:60Z" + assert_equal(t, Time.iso8601(s)) + # leap second is representable only if timezone file has it. + s = "1990-12-31T15:59:60-08:00" + assert_equal(t, Time.iso8601(s)) + + begin + Time.at(-1) + rescue ArgumentError + # ignore + else + t = Time.utc(1937, 1, 1, 11, 40, 27, 870000) + s = "1937-01-01T12:00:27.87+00:20" + assert_equal(t, Time.iso8601(s)) + end + end + + # http://www.w3.org/TR/xmlschema-2/ + def test_xmlschema + assert_equal(Time.utc(1999, 5, 31, 13, 20, 0) + 5 * 3600, + Time.xmlschema("1999-05-31T13:20:00-05:00")) + assert_equal(Time.local(2000, 1, 20, 12, 0, 0), + Time.xmlschema("2000-01-20T12:00:00")) + assert_equal(Time.utc(2000, 1, 20, 12, 0, 0), + Time.xmlschema("2000-01-20T12:00:00Z")) + assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) - 12 * 3600, + Time.xmlschema("2000-01-20T12:00:00+12:00")) + assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) + 13 * 3600, + Time.xmlschema("2000-01-20T12:00:00-13:00")) + assert_equal(Time.utc(2000, 3, 4, 23, 0, 0) - 3 * 3600, + Time.xmlschema("2000-03-04T23:00:00+03:00")) + assert_equal(Time.utc(2000, 3, 4, 20, 0, 0), + Time.xmlschema("2000-03-04T20:00:00Z")) + assert_equal(Time.local(2000, 1, 15, 0, 0, 0), + Time.xmlschema("2000-01-15T00:00:00")) + assert_equal(Time.local(2000, 2, 15, 0, 0, 0), + Time.xmlschema("2000-02-15T00:00:00")) + assert_equal(Time.local(2000, 1, 15, 12, 0, 0), + Time.xmlschema("2000-01-15T12:00:00")) + assert_equal(Time.utc(2000, 1, 16, 12, 0, 0), + Time.xmlschema("2000-01-16T12:00:00Z")) + assert_equal(Time.local(2000, 1, 1, 12, 0, 0), + Time.xmlschema("2000-01-01T12:00:00")) + assert_equal(Time.utc(1999, 12, 31, 23, 0, 0), + Time.xmlschema("1999-12-31T23:00:00Z")) + assert_equal(Time.local(2000, 1, 16, 12, 0, 0), + Time.xmlschema("2000-01-16T12:00:00")) + assert_equal(Time.local(2000, 1, 16, 0, 0, 0), + Time.xmlschema("2000-01-16T00:00:00")) + assert_equal(Time.utc(2000, 1, 12, 12, 13, 14), + Time.xmlschema("2000-01-12T12:13:14Z")) + assert_equal(Time.utc(2001, 4, 17, 19, 23, 17, 300000), + Time.xmlschema("2001-04-17T19:23:17.3Z")) + end + + def test_encode_xmlschema + t = Time.utc(2001, 4, 17, 19, 23, 17, 300000) + assert_equal("2001-04-17T19:23:17Z", t.xmlschema) + assert_equal("2001-04-17T19:23:17.3Z", t.xmlschema(1)) + assert_equal("2001-04-17T19:23:17.300000Z", t.xmlschema(6)) + assert_equal("2001-04-17T19:23:17.3000000Z", t.xmlschema(7)) + + t = Time.utc(2001, 4, 17, 19, 23, 17, 123456) + assert_equal("2001-04-17T19:23:17.1234560Z", t.xmlschema(7)) + assert_equal("2001-04-17T19:23:17.123456Z", t.xmlschema(6)) + assert_equal("2001-04-17T19:23:17.12345Z", t.xmlschema(5)) + assert_equal("2001-04-17T19:23:17.1Z", t.xmlschema(1)) + + begin + Time.at(-1) + rescue ArgumentError + # ignore + else + t = Time.utc(1960, 12, 31, 23, 0, 0, 123456) + assert_equal("1960-12-31T23:00:00.123456Z", t.xmlschema(6)) + end + end + + def test_completion + now = Time.local(2001,11,29,21,26,35) + assert_equal(Time.local( 2001,11,29,21,12), + Time.parse("2001/11/29 21:12", now)) + assert_equal(Time.local( 2001,11,29), + Time.parse("2001/11/29", now)) + assert_equal(Time.local( 2001,11,29), + Time.parse( "11/29", now)) + #assert_equal(Time.local(2001,11,1), Time.parse("Nov", now)) + assert_equal(Time.local( 2001,11,29,10,22), + Time.parse( "10:22", now)) + end + + def test_invalid + # They were actually used in some web sites. + assert_raise(ArgumentError) { Time.httpdate("1 Dec 2001 10:23:57 GMT") } + assert_raise(ArgumentError) { Time.httpdate("Sat, 1 Dec 2001 10:25:42 GMT") } + assert_raise(ArgumentError) { Time.httpdate("Sat, 1-Dec-2001 10:53:55 GMT") } + assert_raise(ArgumentError) { Time.httpdate("Saturday, 01-Dec-2001 10:15:34 GMT") } + assert_raise(ArgumentError) { Time.httpdate("Saturday, 01-Dec-101 11:10:07 GMT") } + assert_raise(ArgumentError) { Time.httpdate("Fri, 30 Nov 2001 21:30:00 JST") } + + # They were actually used in some mails. + assert_raise(ArgumentError) { Time.rfc2822("01-5-20") } + assert_raise(ArgumentError) { Time.rfc2822("7/21/00") } + assert_raise(ArgumentError) { Time.rfc2822("2001-8-28") } + assert_raise(ArgumentError) { Time.rfc2822("00-5-6 1:13:06") } + assert_raise(ArgumentError) { Time.rfc2822("2001-9-27 9:36:49") } + assert_raise(ArgumentError) { Time.rfc2822("2000-12-13 11:01:11") } + assert_raise(ArgumentError) { Time.rfc2822("2001/10/17 04:29:55") } + assert_raise(ArgumentError) { Time.rfc2822("9/4/2001 9:23:19 PM") } + assert_raise(ArgumentError) { Time.rfc2822("01 Nov 2001 09:04:31") } + assert_raise(ArgumentError) { Time.rfc2822("13 Feb 2001 16:4 GMT") } + assert_raise(ArgumentError) { Time.rfc2822("01 Oct 00 5:41:19 PM") } + assert_raise(ArgumentError) { Time.rfc2822("2 Jul 00 00:51:37 JST") } + assert_raise(ArgumentError) { Time.rfc2822("01 11 2001 06:55:57 -0500") } + assert_raise(ArgumentError) { Time.rfc2822("18 \343\366\356\341\370 2000") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, Oct 2001 18:53:32") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 2 Nov 2001 03:47:54") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 27 Jul 2001 11.14.14 +0200") } + assert_raise(ArgumentError) { Time.rfc2822("Thu, 2 Nov 2000 04:13:53 -600") } + assert_raise(ArgumentError) { Time.rfc2822("Wed, 5 Apr 2000 22:57:09 JST") } + assert_raise(ArgumentError) { Time.rfc2822("Mon, 11 Sep 2000 19:47:33 00000") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 28 Apr 2000 20:40:47 +-900") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 19 Jan 2001 8:15:36 AM -0500") } + assert_raise(ArgumentError) { Time.rfc2822("Thursday, Sep 27 2001 7:42:35 AM EST") } + assert_raise(ArgumentError) { Time.rfc2822("3/11/2001 1:31:57 PM Pacific Daylight Time") } + assert_raise(ArgumentError) { Time.rfc2822("Mi, 28 Mrz 2001 11:51:36") } + assert_raise(ArgumentError) { Time.rfc2822("P, 30 sept 2001 23:03:14") } + assert_raise(ArgumentError) { Time.rfc2822("fr, 11 aug 2000 18:39:22") } + assert_raise(ArgumentError) { Time.rfc2822("Fr, 21 Sep 2001 17:44:03 -1000") } + assert_raise(ArgumentError) { Time.rfc2822("Mo, 18 Jun 2001 19:21:40 -1000") } + assert_raise(ArgumentError) { Time.rfc2822("l\366, 12 aug 2000 18:53:20") } + assert_raise(ArgumentError) { Time.rfc2822("l\366, 26 maj 2001 00:15:58") } + assert_raise(ArgumentError) { Time.rfc2822("Dom, 30 Sep 2001 17:36:30") } + assert_raise(ArgumentError) { Time.rfc2822("%&, 31 %2/ 2000 15:44:47 -0500") } + assert_raise(ArgumentError) { Time.rfc2822("dom, 26 ago 2001 03:57:07 -0300") } + assert_raise(ArgumentError) { Time.rfc2822("ter, 04 set 2001 16:27:58 -0300") } + assert_raise(ArgumentError) { Time.rfc2822("Wen, 3 oct 2001 23:17:49 -0400") } + assert_raise(ArgumentError) { Time.rfc2822("Wen, 3 oct 2001 23:17:49 -0400") } + assert_raise(ArgumentError) { Time.rfc2822("ele, 11 h: 2000 12:42:15 -0500") } + assert_raise(ArgumentError) { Time.rfc2822("Tue, 14 Aug 2001 3:55:3 +0200") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 25 Aug 2000 9:3:48 +0800") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 1 Dec 2000 0:57:50 EST") } + assert_raise(ArgumentError) { Time.rfc2822("Mon, 7 May 2001 9:39:51 +0200") } + assert_raise(ArgumentError) { Time.rfc2822("Wed, 1 Aug 2001 16:9:15 +0200") } + assert_raise(ArgumentError) { Time.rfc2822("Wed, 23 Aug 2000 9:17:36 +0800") } + assert_raise(ArgumentError) { Time.rfc2822("Fri, 11 Aug 2000 10:4:42 +0800") } + assert_raise(ArgumentError) { Time.rfc2822("Sat, 15 Sep 2001 13:22:2 +0300") } + assert_raise(ArgumentError) { Time.rfc2822("Wed,16 \276\305\324\302 2001 20:06:25 +0800") } + assert_raise(ArgumentError) { Time.rfc2822("Wed,7 \312\256\322\273\324\302 2001 23:47:22 +0800") } + assert_raise(ArgumentError) { Time.rfc2822("=?iso-8859-1?Q?(=C5=DA),?= 10 2 2001 23:32:26 +0900 (JST)") } + assert_raise(ArgumentError) { Time.rfc2822("\307\341\314\343\332\311, 30 \344\346\335\343\310\321 2001 10:01:06") } + assert_raise(ArgumentError) { Time.rfc2822("=?iso-8859-1?Q?(=BF=E5),?= 12 =?iso-8859-1?Q?9=B7=EE?= 2001 14:52:41\n+0900 (JST)") } + end + + def test_zone_0000 + assert_equal(true, Time.parse("2000-01-01T00:00:00Z").utc?) + assert_equal(true, Time.parse("2000-01-01T00:00:00-00:00").utc?) + assert_equal(false, Time.parse("2000-01-01T00:00:00+00:00").utc?) + assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 GMT").utc?) + assert_equal(true, Time.parse("Sat, 01 Jan 2000 00:00:00 -0000").utc?) + assert_equal(false, Time.parse("Sat, 01 Jan 2000 00:00:00 +0000").utc?) + assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 GMT").utc?) + assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 -0000").utc?) + assert_equal(false, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 +0000").utc?) + assert_equal(true, Time.rfc2822("Sat, 01 Jan 2000 00:00:00 UTC").utc?) + end + + def test_parse_leap_second + t = Time.utc(1998,12,31,23,59,59) + assert_equal(t, Time.parse("Thu Dec 31 23:59:59 UTC 1998")) + assert_equal(t, Time.parse("Fri Dec 31 23:59:59 -0000 1998"));t.localtime + assert_equal(t, Time.parse("Fri Jan 1 08:59:59 +0900 1999")) + assert_equal(t, Time.parse("Fri Jan 1 00:59:59 +0100 1999")) + assert_equal(t, Time.parse("Fri Dec 31 23:59:59 +0000 1998")) + assert_equal(t, Time.parse("Fri Dec 31 22:59:59 -0100 1998"));t.utc + t += 1 + assert_equal(t, Time.parse("Thu Dec 31 23:59:60 UTC 1998")) + assert_equal(t, Time.parse("Fri Dec 31 23:59:60 -0000 1998"));t.localtime + assert_equal(t, Time.parse("Fri Jan 1 08:59:60 +0900 1999")) + assert_equal(t, Time.parse("Fri Jan 1 00:59:60 +0100 1999")) + assert_equal(t, Time.parse("Fri Dec 31 23:59:60 +0000 1998")) + assert_equal(t, Time.parse("Fri Dec 31 22:59:60 -0100 1998"));t.utc + t += 1 if t.sec == 60 + assert_equal(t, Time.parse("Thu Jan 1 00:00:00 UTC 1999")) + assert_equal(t, Time.parse("Fri Jan 1 00:00:00 -0000 1999"));t.localtime + assert_equal(t, Time.parse("Fri Jan 1 09:00:00 +0900 1999")) + assert_equal(t, Time.parse("Fri Jan 1 01:00:00 +0100 1999")) + assert_equal(t, Time.parse("Fri Jan 1 00:00:00 +0000 1999")) + assert_equal(t, Time.parse("Fri Dec 31 23:00:00 -0100 1998")) + end + + def test_rfc2822_leap_second + t = Time.utc(1998,12,31,23,59,59) + assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:59 UTC")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 -0000"));t.localtime + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 08:59:59 +0900")) + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:59:59 +0100")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:59 +0000")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:59 -0100"));t.utc + t += 1 + assert_equal(t, Time.rfc2822("Thu, 31 Dec 1998 23:59:60 UTC")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 -0000"));t.localtime + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 08:59:60 +0900")) + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:59:60 +0100")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:59:60 +0000")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 22:59:60 -0100"));t.utc + t += 1 if t.sec == 60 + assert_equal(t, Time.rfc2822("Thu, 1 Jan 1999 00:00:00 UTC")) + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 -0000"));t.localtime + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 09:00:00 +0900")) + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 01:00:00 +0100")) + assert_equal(t, Time.rfc2822("Fri, 1 Jan 1999 00:00:00 +0000")) + assert_equal(t, Time.rfc2822("Fri, 31 Dec 1998 23:00:00 -0100")) + end + + def test_xmlschema_leap_second + t = Time.utc(1998,12,31,23,59,59) + assert_equal(t, Time.xmlschema("1998-12-31T23:59:59Z")) + assert_equal(t, Time.xmlschema("1998-12-31T23:59:59-00:00"));t.localtime + assert_equal(t, Time.xmlschema("1999-01-01T08:59:59+09:00")) + assert_equal(t, Time.xmlschema("1999-01-01T00:59:59+01:00")) + assert_equal(t, Time.xmlschema("1998-12-31T23:59:59+00:00")) + assert_equal(t, Time.xmlschema("1998-12-31T22:59:59-01:00"));t.utc + t += 1 + assert_equal(t, Time.xmlschema("1998-12-31T23:59:60Z")) + assert_equal(t, Time.xmlschema("1998-12-31T23:59:60-00:00"));t.localtime + assert_equal(t, Time.xmlschema("1999-01-01T08:59:60+09:00")) + assert_equal(t, Time.xmlschema("1999-01-01T00:59:60+01:00")) + assert_equal(t, Time.xmlschema("1998-12-31T23:59:60+00:00")) + assert_equal(t, Time.xmlschema("1998-12-31T22:59:60-01:00"));t.utc + t += 1 if t.sec == 60 + assert_equal(t, Time.xmlschema("1999-01-01T00:00:00Z")) + assert_equal(t, Time.xmlschema("1999-01-01T00:00:00-00:00"));t.localtime + assert_equal(t, Time.xmlschema("1999-01-01T09:00:00+09:00")) + assert_equal(t, Time.xmlschema("1999-01-01T01:00:00+01:00")) + assert_equal(t, Time.xmlschema("1999-01-01T00:00:00+00:00")) + assert_equal(t, Time.xmlschema("1998-12-31T23:00:00-01:00")) + end + + def test_ruby_talk_152866 + t = Time::xmlschema('2005-08-30T22:48:00-07:00') + assert_equal(31, t.day) + assert_equal(8, t.mon) + end + + def test_parse_fraction + assert_equal(500000, Time.parse("2000-01-01T00:00:00.5+00:00").tv_usec) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/timeout.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/timeout.rb new file mode 100644 index 00000000..5a99c280 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/timeout.rb @@ -0,0 +1,122 @@ +#-- +# = timeout.rb +# +# execution timeout +# +# = Copyright +# +# Copyright:: (C) 2000 Network Applied Communication Laboratory, Inc. +# Copyright:: (C) 2000 Information-technology Promotion Agency, Japan +# +#++ +# +# = Description +# +# A way of performing a potentially long-running operation in a thread, and +# terminating it's execution if it hasn't finished within fixed amount of +# time. +# +# Previous versions of timeout didn't use a module for namespace. This version +# provides both Timeout.timeout, and a backwards-compatible #timeout. +# +# = Synopsis +# +# require 'timeout' +# status = Timeout::timeout(5) { +# # Something that should be interrupted if it takes too much time... +# } +# + +module Timeout + + ## + # Raised by Timeout#timeout when the block times out. + + class Error < Interrupt + end + class ExitException < ::Exception # :nodoc: + end + + THIS_FILE = /\A#{Regexp.quote(__FILE__)}:/o + CALLER_OFFSET = ((c = caller[0]) && THIS_FILE =~ c) ? 1 : 0 + + ## + # Executes the method's block. If the block execution terminates before +sec+ + # seconds has passed, it returns true. If not, it terminates the execution + # and raises +exception+ (which defaults to Timeout::Error). + # + # Note that this is both a method of module Timeout, so you can 'include + # Timeout' into your classes so they have a #timeout method, as well as a + # module method, so you can call it directly as Timeout.timeout(). + + def timeout(sec, klass = nil) + return yield if sec == nil or sec.zero? + raise ThreadError, "timeout within critical session" if Thread.critical + exception = klass || Class.new(ExitException) + begin + x = Thread.current + y = Thread.start { + sleep sec + x.raise exception, "execution expired" if x.alive? + } + yield sec + # return true + rescue exception => e + rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o + (bt = e.backtrace).reject! {|m| rej =~ m} + level = -caller(CALLER_OFFSET).size + while THIS_FILE =~ bt[level] + bt.delete_at(level) + level += 1 + end + raise if klass # if exception class is specified, it + # would be expected outside. + raise Error, e.message, e.backtrace + ensure + y.kill if y and y.alive? + end + end + + module_function :timeout + +end + +## +# Identical to: +# +# Timeout::timeout(n, e, &block). +# +# Defined for backwards compatibility with earlier versions of timeout.rb, see +# Timeout#timeout. + +def timeout(n, e = nil, &block) # :nodoc: + Timeout::timeout(n, e, &block) +end + +## +# Another name for Timeout::Error, defined for backwards compatibility with +# earlier versions of timeout.rb. + +TimeoutError = Timeout::Error # :nodoc: + +if __FILE__ == $0 + p timeout(5) { + 45 + } + p timeout(5, TimeoutError) { + 45 + } + p timeout(nil) { + 54 + } + p timeout(0) { + 54 + } + p timeout(5) { + loop { + p 10 + sleep 1 + } + } +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tmpdir.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tmpdir.rb new file mode 100644 index 00000000..9f518abc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tmpdir.rb @@ -0,0 +1,52 @@ +# +# tmpdir - retrieve temporary directory path +# +# $Id: tmpdir.rb 17799 2008-07-02 09:22:26Z shyouhei $ +# + +class Dir + + @@systmpdir = '/tmp' + + begin + require 'Win32API' + CSIDL_LOCAL_APPDATA = 0x001c + max_pathlen = 260 + windir = ' '*(max_pathlen+1) + begin + getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L') + raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0 + windir = File.expand_path(windir.rstrip) + rescue RuntimeError + begin + getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L') + rescue RuntimeError + getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L') + end + len = getdir.call(windir, windir.size) + windir = File.expand_path(windir[0, len]) + end + temp = File.join(windir.untaint, 'temp') + @@systmpdir = temp if File.directory?(temp) and File.writable?(temp) + rescue LoadError + end + + ## + # Returns the operating system's temporary file path. + + def Dir::tmpdir + tmp = '.' + if $SAFE > 0 + tmp = @@systmpdir + else + for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], + ENV['USERPROFILE'], @@systmpdir, '/tmp'] + if dir and File.directory?(dir) and File.writable?(dir) + tmp = dir + break + end + end + File.expand_path(tmp) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tracer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tracer.rb new file mode 100644 index 00000000..71aa49c3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tracer.rb @@ -0,0 +1,167 @@ +# +# tracer.rb - +# $Release Version: 0.2$ +# $Revision: 1.8 $ +# $Date: 1998/05/19 03:42:49 $ +# by Keiju ISHITSUKA(Nippon Rational Inc.) +# +# -- +# +# +# + +# +# tracer main class +# +class Tracer + @RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-' + + @stdout = STDOUT + @verbose = false + class << self + attr :verbose, true + alias verbose? verbose + attr :stdout, true + end + + EVENT_SYMBOL = { + "line" => "-", + "call" => ">", + "return" => "<", + "class" => "C", + "end" => "E", + "c-call" => ">", + "c-return" => "<", + } + + def initialize + @threads = Hash.new + if defined? Thread.main + @threads[Thread.main.object_id] = 0 + else + @threads[Thread.current.object_id] = 0 + end + + @get_line_procs = {} + + @filters = [] + end + + def stdout + Tracer.stdout + end + + def on + if block_given? + on + begin + yield + ensure + off + end + else + set_trace_func method(:trace_func).to_proc + stdout.print "Trace on\n" if Tracer.verbose? + end + end + + def off + set_trace_func nil + stdout.print "Trace off\n" if Tracer.verbose? + end + + def add_filter(p = proc) + @filters.push p + end + + def set_get_line_procs(file, p = proc) + @get_line_procs[file] = p + end + + def get_line(file, line) + if p = @get_line_procs[file] + return p.call(line) + end + + unless list = SCRIPT_LINES__[file] + begin + f = open(file) + begin + SCRIPT_LINES__[file] = list = f.readlines + ensure + f.close + end + rescue + SCRIPT_LINES__[file] = list = [] + end + end + + if l = list[line - 1] + l + else + "-\n" + end + end + + def get_thread_no + if no = @threads[Thread.current.object_id] + no + else + @threads[Thread.current.object_id] = @threads.size + end + end + + def trace_func(event, file, line, id, binding, klass, *) + return if file == __FILE__ + + for p in @filters + return unless p.call event, file, line, id, binding, klass + end + + saved_crit = Thread.critical + Thread.critical = true + stdout.printf("#%d:%s:%d:%s:%s: %s", + get_thread_no, + file, + line, + klass || '', + EVENT_SYMBOL[event], + get_line(file, line)) + Thread.critical = saved_crit + end + + Single = new + def Tracer.on + if block_given? + Single.on{yield} + else + Single.on + end + end + + def Tracer.off + Single.off + end + + def Tracer.set_get_line_procs(file_name, p = proc) + Single.set_get_line_procs(file_name, p) + end + + def Tracer.add_filter(p = proc) + Single.add_filter(p) + end + +end + +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ + +if $0 == __FILE__ + # direct call + + $0 = ARGV[0] + ARGV.shift + Tracer.on + require $0 +elsif caller(0).size == 1 + Tracer.on +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tsort.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tsort.rb new file mode 100644 index 00000000..a014e7f6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/tsort.rb @@ -0,0 +1,290 @@ +#!/usr/bin/env ruby +#-- +# tsort.rb - provides a module for topological sorting and strongly connected components. +#++ +# + +# +# TSort implements topological sorting using Tarjan's algorithm for +# strongly connected components. +# +# TSort is designed to be able to be used with any object which can be +# interpreted as a directed graph. +# +# TSort requires two methods to interpret an object as a graph, +# tsort_each_node and tsort_each_child. +# +# * tsort_each_node is used to iterate for all nodes over a graph. +# * tsort_each_child is used to iterate for child nodes of a given node. +# +# The equality of nodes are defined by eql? and hash since +# TSort uses Hash internally. +# +# == A Simple Example +# +# The following example demonstrates how to mix the TSort module into an +# existing class (in this case, Hash). Here, we're treating each key in +# the hash as a node in the graph, and so we simply alias the required +# #tsort_each_node method to Hash's #each_key method. For each key in the +# hash, the associated value is an array of the node's child nodes. This +# choice in turn leads to our implementation of the required #tsort_each_child +# method, which fetches the array of child nodes and then iterates over that +# array using the user-supplied block. +# +# require 'tsort' +# +# class Hash +# include TSort +# alias tsort_each_node each_key +# def tsort_each_child(node, &block) +# fetch(node).each(&block) +# end +# end +# +# {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort +# #=> [3, 2, 1, 4] +# +# {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components +# #=> [[4], [2, 3], [1]] +# +# == A More Realistic Example +# +# A very simple `make' like tool can be implemented as follows: +# +# require 'tsort' +# +# class Make +# def initialize +# @dep = {} +# @dep.default = [] +# end +# +# def rule(outputs, inputs=[], &block) +# triple = [outputs, inputs, block] +# outputs.each {|f| @dep[f] = [triple]} +# @dep[triple] = inputs +# end +# +# def build(target) +# each_strongly_connected_component_from(target) {|ns| +# if ns.length != 1 +# fs = ns.delete_if {|n| Array === n} +# raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}") +# end +# n = ns.first +# if Array === n +# outputs, inputs, block = n +# inputs_time = inputs.map {|f| File.mtime f}.max +# begin +# outputs_time = outputs.map {|f| File.mtime f}.min +# rescue Errno::ENOENT +# outputs_time = nil +# end +# if outputs_time == nil || +# inputs_time != nil && outputs_time <= inputs_time +# sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i +# block.call +# end +# end +# } +# end +# +# def tsort_each_child(node, &block) +# @dep[node].each(&block) +# end +# include TSort +# end +# +# def command(arg) +# print arg, "\n" +# system arg +# end +# +# m = Make.new +# m.rule(%w[t1]) { command 'date > t1' } +# m.rule(%w[t2]) { command 'date > t2' } +# m.rule(%w[t3]) { command 'date > t3' } +# m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' } +# m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' } +# m.build('t5') +# +# == Bugs +# +# * 'tsort.rb' is wrong name because this library uses +# Tarjan's algorithm for strongly connected components. +# Although 'strongly_connected_components.rb' is correct but too long. +# +# == References +# +# R. E. Tarjan, "Depth First Search and Linear Graph Algorithms", +# SIAM Journal on Computing, Vol. 1, No. 2, pp. 146-160, June 1972. +# + +module TSort + class Cyclic < StandardError + end + + # + # Returns a topologically sorted array of nodes. + # The array is sorted from children to parents, i.e. + # the first element has no child and the last node has no parent. + # + # If there is a cycle, TSort::Cyclic is raised. + # + def tsort + result = [] + tsort_each {|element| result << element} + result + end + + # + # The iterator version of the #tsort method. + # obj.tsort_each is similar to obj.tsort.each, but + # modification of _obj_ during the iteration may lead to unexpected results. + # + # #tsort_each returns +nil+. + # If there is a cycle, TSort::Cyclic is raised. + # + def tsort_each # :yields: node + each_strongly_connected_component {|component| + if component.size == 1 + yield component.first + else + raise Cyclic.new("topological sort failed: #{component.inspect}") + end + } + end + + # + # Returns strongly connected components as an array of arrays of nodes. + # The array is sorted from children to parents. + # Each elements of the array represents a strongly connected component. + # + def strongly_connected_components + result = [] + each_strongly_connected_component {|component| result << component} + result + end + + # + # The iterator version of the #strongly_connected_components method. + # obj.each_strongly_connected_component is similar to + # obj.strongly_connected_components.each, but + # modification of _obj_ during the iteration may lead to unexpected results. + # + # + # #each_strongly_connected_component returns +nil+. + # + def each_strongly_connected_component # :yields: nodes + id_map = {} + stack = [] + tsort_each_node {|node| + unless id_map.include? node + each_strongly_connected_component_from(node, id_map, stack) {|c| + yield c + } + end + } + nil + end + + # + # Iterates over strongly connected component in the subgraph reachable from + # _node_. + # + # Return value is unspecified. + # + # #each_strongly_connected_component_from doesn't call #tsort_each_node. + # + def each_strongly_connected_component_from(node, id_map={}, stack=[]) # :yields: nodes + minimum_id = node_id = id_map[node] = id_map.size + stack_length = stack.length + stack << node + + tsort_each_child(node) {|child| + if id_map.include? child + child_id = id_map[child] + minimum_id = child_id if child_id && child_id < minimum_id + else + sub_minimum_id = + each_strongly_connected_component_from(child, id_map, stack) {|c| + yield c + } + minimum_id = sub_minimum_id if sub_minimum_id < minimum_id + end + } + + if node_id == minimum_id + component = stack.slice!(stack_length .. -1) + component.each {|n| id_map[n] = nil} + yield component + end + + minimum_id + end + + # + # Should be implemented by a extended class. + # + # #tsort_each_node is used to iterate for all nodes over a graph. + # + def tsort_each_node # :yields: node + raise NotImplementedError.new + end + + # + # Should be implemented by a extended class. + # + # #tsort_each_child is used to iterate for child nodes of _node_. + # + def tsort_each_child(node) # :yields: child + raise NotImplementedError.new + end +end + +if __FILE__ == $0 + require 'test/unit' + + class TSortHash < Hash # :nodoc: + include TSort + alias tsort_each_node each_key + def tsort_each_child(node, &block) + fetch(node).each(&block) + end + end + + class TSortArray < Array # :nodoc: + include TSort + alias tsort_each_node each_index + def tsort_each_child(node, &block) + fetch(node).each(&block) + end + end + + class TSortTest < Test::Unit::TestCase # :nodoc: + def test_dag + h = TSortHash[{1=>[2, 3], 2=>[3], 3=>[]}] + assert_equal([3, 2, 1], h.tsort) + assert_equal([[3], [2], [1]], h.strongly_connected_components) + end + + def test_cycle + h = TSortHash[{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}] + assert_equal([[4], [2, 3], [1]], + h.strongly_connected_components.map {|nodes| nodes.sort}) + assert_raise(TSort::Cyclic) { h.tsort } + end + + def test_array + a = TSortArray[[1], [0], [0], [2]] + assert_equal([[0, 1], [2], [3]], + a.strongly_connected_components.map {|nodes| nodes.sort}) + + a = TSortArray[[], [0]] + assert_equal([[0], [1]], + a.strongly_connected_components.map {|nodes| nodes.sort}) + end + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/un.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/un.rb new file mode 100644 index 00000000..9bf6c131 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/un.rb @@ -0,0 +1,235 @@ +# +# = un.rb +# +# Copyright (c) 2003 WATANABE Hirofumi +# +# This program is free software. +# You can distribute/modify this program under the same terms of Ruby. +# +# == Utilities to replace common UNIX commands in Makefiles etc +# +# == SYNOPSIS +# +# ruby -run -e cp -- [OPTION] SOURCE DEST +# ruby -run -e ln -- [OPTION] TARGET LINK_NAME +# ruby -run -e mv -- [OPTION] SOURCE DEST +# ruby -run -e rm -- [OPTION] FILE +# ruby -run -e mkdir -- [OPTION] DIRS +# ruby -run -e rmdir -- [OPTION] DIRS +# ruby -run -e install -- [OPTION] SOURCE DEST +# ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE +# ruby -run -e touch -- [OPTION] FILE +# ruby -run -e help [COMMAND] + +require "fileutils" +require "optparse" + +module FileUtils +# @fileutils_label = "" + @fileutils_output = $stdout +end + +def setup(options = "") + ARGV.map! do |x| + case x + when /^-/ + x.delete "^-#{options}v" + when /[*?\[{]/ + Dir[x] + else + x + end + end + ARGV.flatten! + ARGV.delete_if{|x| x == "-"} + opt_hash = {} + OptionParser.new do |o| + options.scan(/.:?/) do |s| + o.on("-" + s.tr(":", " ")) do |val| + opt_hash[s.delete(":").intern] = val + end + end + o.on("-v") do opt_hash[:verbose] = true end + o.parse! + end + yield ARGV, opt_hash +end + +## +# Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY +# +# ruby -run -e cp -- [OPTION] SOURCE DEST +# +# -p preserve file attributes if possible +# -r copy recursively +# -v verbose +# + +def cp + setup("pr") do |argv, options| + cmd = "cp" + cmd += "_r" if options.delete :r + options[:preserve] = true if options.delete :p + dest = argv.pop + argv = argv[0] if argv.size == 1 + FileUtils.send cmd, argv, dest, options + end +end + +## +# Create a link to the specified TARGET with LINK_NAME. +# +# ruby -run -e ln -- [OPTION] TARGET LINK_NAME +# +# -s make symbolic links instead of hard links +# -f remove existing destination files +# -v verbose +# + +def ln + setup("sf") do |argv, options| + cmd = "ln" + cmd += "_s" if options.delete :s + options[:force] = true if options.delete :f + dest = argv.pop + argv = argv[0] if argv.size == 1 + FileUtils.send cmd, argv, dest, options + end +end + +## +# Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. +# +# ruby -run -e mv -- [OPTION] SOURCE DEST +# +# -v verbose +# + +def mv + setup do |argv, options| + dest = argv.pop + argv = argv[0] if argv.size == 1 + FileUtils.mv argv, dest, options + end +end + +## +# Remove the FILE +# +# ruby -run -e rm -- [OPTION] FILE +# +# -f ignore nonexistent files +# -r remove the contents of directories recursively +# -v verbose +# + +def rm + setup("fr") do |argv, options| + cmd = "rm" + cmd += "_r" if options.delete :r + options[:force] = true if options.delete :f + FileUtils.send cmd, argv, options + end +end + +## +# Create the DIR, if they do not already exist. +# +# ruby -run -e mkdir -- [OPTION] DIR +# +# -p no error if existing, make parent directories as needed +# -v verbose +# + +def mkdir + setup("p") do |argv, options| + cmd = "mkdir" + cmd += "_p" if options.delete :p + FileUtils.send cmd, argv, options + end +end + +## +# Remove the DIR. +# +# ruby -run -e rmdir -- [OPTION] DIR +# +# -v verbose +# + +def rmdir + setup do |argv, options| + FileUtils.rmdir argv, options + end +end + +## +# Copy SOURCE to DEST. +# +# ruby -run -e install -- [OPTION] SOURCE DEST +# +# -p apply access/modification times of SOURCE files to +# corresponding destination files +# -m set permission mode (as in chmod), instead of 0755 +# -v verbose +# + +def install + setup("pm:") do |argv, options| + options[:mode] = (mode = options.delete :m) ? mode.oct : 0755 + options[:preserve] = true if options.delete :p + dest = argv.pop + argv = argv[0] if argv.size == 1 + FileUtils.install argv, dest, options + end +end + +## +# Change the mode of each FILE to OCTAL-MODE. +# +# ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE +# +# -v verbose +# + +def chmod + setup do |argv, options| + mode = argv.shift.oct + FileUtils.chmod mode, argv, options + end +end + +## +# Update the access and modification times of each FILE to the current time. +# +# ruby -run -e touch -- [OPTION] FILE +# +# -v verbose +# + +def touch + setup do |argv, options| + FileUtils.touch argv, options + end +end + +## +# Display help message. +# +# ruby -run -e help [COMMAND] +# + +def help + setup do |argv,| + all = argv.empty? + open(__FILE__) do |me| + while me.gets("##\n") + if help = me.gets("\n\n") + if all or argv.delete help[/-e \w+/].sub(/-e /, "") + print help.gsub(/^# ?/, "") + end + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri.rb new file mode 100644 index 00000000..d06fb406 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri.rb @@ -0,0 +1,28 @@ +# +# URI support for Ruby +# +# Author:: Akira Yamada +# Documentation:: Akira Yamada , Dmitry V. Sabanin +# License:: +# Copyright (c) 2001 akira yamada +# You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: uri.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# +# See URI for documentation +# + +module URI + # :stopdoc: + VERSION_CODE = '000911'.freeze + VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze + # :startdoc: + +end + +require 'uri/common' +require 'uri/generic' +require 'uri/ftp' +require 'uri/http' +require 'uri/https' +require 'uri/ldap' +require 'uri/mailto' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/common.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/common.rb new file mode 100644 index 00000000..8b2ed96e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/common.rb @@ -0,0 +1,611 @@ +# = uri/common.rb +# +# Author:: Akira Yamada +# Revision:: $Id: common.rb 16982 2008-06-07 20:11:00Z shyouhei $ +# License:: +# You can redistribute it and/or modify it under the same term as Ruby. +# + +module URI + module REGEXP + # + # Patterns used to parse URI's + # + module PATTERN + # :stopdoc: + + # RFC 2396 (URI Generic Syntax) + # RFC 2732 (IPv6 Literal Addresses in URL's) + # RFC 2373 (IPv6 Addressing Architecture) + + # alpha = lowalpha | upalpha + ALPHA = "a-zA-Z" + # alphanum = alpha | digit + ALNUM = "#{ALPHA}\\d" + + # hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + # "a" | "b" | "c" | "d" | "e" | "f" + HEX = "a-fA-F\\d" + # escaped = "%" hex hex + ESCAPED = "%[#{HEX}]{2}" + # mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | + # "(" | ")" + # unreserved = alphanum | mark + UNRESERVED = "-_.!~*'()#{ALNUM}" + # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + # "$" | "," + # reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + # "$" | "," | "[" | "]" (RFC 2732) + RESERVED = ";/?:@&=+$,\\[\\]" + + # uric = reserved | unreserved | escaped + URIC = "(?:[#{UNRESERVED}#{RESERVED}]|#{ESCAPED})" + # uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | + # "&" | "=" | "+" | "$" | "," + URIC_NO_SLASH = "(?:[#{UNRESERVED};?:@&=+$,]|#{ESCAPED})" + # query = *uric + QUERY = "#{URIC}*" + # fragment = *uric + FRAGMENT = "#{URIC}*" + + # domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + DOMLABEL = "(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)" + # toplabel = alpha | alpha *( alphanum | "-" ) alphanum + TOPLABEL = "(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)" + # hostname = *( domainlabel "." ) toplabel [ "." ] + HOSTNAME = "(?:#{DOMLABEL}\\.)*#{TOPLABEL}\\.?" + + # RFC 2373, APPENDIX B: + # IPv6address = hexpart [ ":" IPv4address ] + # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT + # hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ] + # hexseq = hex4 *( ":" hex4) + # hex4 = 1*4HEXDIG + # + # XXX: This definition has a flaw. "::" + IPv4address must be + # allowed too. Here is a replacement. + # + # IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT + IPV4ADDR = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}" + # hex4 = 1*4HEXDIG + HEX4 = "[#{HEX}]{1,4}" + # lastpart = hex4 | IPv4address + LASTPART = "(?:#{HEX4}|#{IPV4ADDR})" + # hexseq1 = *( hex4 ":" ) hex4 + HEXSEQ1 = "(?:#{HEX4}:)*#{HEX4}" + # hexseq2 = *( hex4 ":" ) lastpart + HEXSEQ2 = "(?:#{HEX4}:)*#{LASTPART}" + # IPv6address = hexseq2 | [ hexseq1 ] "::" [ hexseq2 ] + IPV6ADDR = "(?:#{HEXSEQ2}|(?:#{HEXSEQ1})?::(?:#{HEXSEQ2})?)" + + # IPv6prefix = ( hexseq1 | [ hexseq1 ] "::" [ hexseq1 ] ) "/" 1*2DIGIT + # unused + + # ipv6reference = "[" IPv6address "]" (RFC 2732) + IPV6REF = "\\[#{IPV6ADDR}\\]" + + # host = hostname | IPv4address + # host = hostname | IPv4address | IPv6reference (RFC 2732) + HOST = "(?:#{HOSTNAME}|#{IPV4ADDR}|#{IPV6REF})" + # port = *digit + PORT = '\d*' + # hostport = host [ ":" port ] + HOSTPORT = "#{HOST}(?::#{PORT})?" + + # userinfo = *( unreserved | escaped | + # ";" | ":" | "&" | "=" | "+" | "$" | "," ) + USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})*" + + # pchar = unreserved | escaped | + # ":" | "@" | "&" | "=" | "+" | "$" | "," + PCHAR = "(?:[#{UNRESERVED}:@&=+$,]|#{ESCAPED})" + # param = *pchar + PARAM = "#{PCHAR}*" + # segment = *pchar *( ";" param ) + SEGMENT = "#{PCHAR}*(?:;#{PARAM})*" + # path_segments = segment *( "/" segment ) + PATH_SEGMENTS = "#{SEGMENT}(?:/#{SEGMENT})*" + + # server = [ [ userinfo "@" ] hostport ] + SERVER = "(?:#{USERINFO}@)?#{HOSTPORT}" + # reg_name = 1*( unreserved | escaped | "$" | "," | + # ";" | ":" | "@" | "&" | "=" | "+" ) + REG_NAME = "(?:[#{UNRESERVED}$,;:@&=+]|#{ESCAPED})+" + # authority = server | reg_name + AUTHORITY = "(?:#{SERVER}|#{REG_NAME})" + + # rel_segment = 1*( unreserved | escaped | + # ";" | "@" | "&" | "=" | "+" | "$" | "," ) + REL_SEGMENT = "(?:[#{UNRESERVED};@&=+$,]|#{ESCAPED})+" + + # scheme = alpha *( alpha | digit | "+" | "-" | "." ) + SCHEME = "[#{ALPHA}][-+.#{ALPHA}\\d]*" + + # abs_path = "/" path_segments + ABS_PATH = "/#{PATH_SEGMENTS}" + # rel_path = rel_segment [ abs_path ] + REL_PATH = "#{REL_SEGMENT}(?:#{ABS_PATH})?" + # net_path = "//" authority [ abs_path ] + NET_PATH = "//#{AUTHORITY}(?:#{ABS_PATH})?" + + # hier_part = ( net_path | abs_path ) [ "?" query ] + HIER_PART = "(?:#{NET_PATH}|#{ABS_PATH})(?:\\?(?:#{QUERY}))?" + # opaque_part = uric_no_slash *uric + OPAQUE_PART = "#{URIC_NO_SLASH}#{URIC}*" + + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + ABS_URI = "#{SCHEME}:(?:#{HIER_PART}|#{OPAQUE_PART})" + # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + REL_URI = "(?:#{NET_PATH}|#{ABS_PATH}|#{REL_PATH})(?:\\?#{QUERY})?" + + # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + URI_REF = "(?:#{ABS_URI}|#{REL_URI})?(?:##{FRAGMENT})?" + + # XXX: + X_ABS_URI = " + (#{PATTERN::SCHEME}): (?# 1: scheme) + (?: + (#{PATTERN::OPAQUE_PART}) (?# 2: opaque) + | + (?:(?: + //(?: + (?:(?:(#{PATTERN::USERINFO})@)? (?# 3: userinfo) + (?:(#{PATTERN::HOST})(?::(\\d*))?))?(?# 4: host, 5: port) + | + (#{PATTERN::REG_NAME}) (?# 6: registry) + ) + | + (?!//)) (?# XXX: '//' is the mark for hostport) + (#{PATTERN::ABS_PATH})? (?# 7: path) + )(?:\\?(#{PATTERN::QUERY}))? (?# 8: query) + ) + (?:\\#(#{PATTERN::FRAGMENT}))? (?# 9: fragment) + " + X_REL_URI = " + (?: + (?: + // + (?: + (?:(#{PATTERN::USERINFO})@)? (?# 1: userinfo) + (#{PATTERN::HOST})?(?::(\\d*))? (?# 2: host, 3: port) + | + (#{PATTERN::REG_NAME}) (?# 4: registry) + ) + ) + | + (#{PATTERN::REL_SEGMENT}) (?# 5: rel_segment) + )? + (#{PATTERN::ABS_PATH})? (?# 6: abs_path) + (?:\\?(#{PATTERN::QUERY}))? (?# 7: query) + (?:\\#(#{PATTERN::FRAGMENT}))? (?# 8: fragment) + " + # :startdoc: + end # PATTERN + + # :stopdoc: + + # for URI::split + ABS_URI = Regexp.new('^' + PATTERN::X_ABS_URI + '$', #' + Regexp::EXTENDED, 'N').freeze + REL_URI = Regexp.new('^' + PATTERN::X_REL_URI + '$', #' + Regexp::EXTENDED, 'N').freeze + + # for URI::extract + URI_REF = Regexp.new(PATTERN::URI_REF, false, 'N').freeze + ABS_URI_REF = Regexp.new(PATTERN::X_ABS_URI, Regexp::EXTENDED, 'N').freeze + REL_URI_REF = Regexp.new(PATTERN::X_REL_URI, Regexp::EXTENDED, 'N').freeze + + # for URI::escape/unescape + ESCAPED = Regexp.new(PATTERN::ESCAPED, false, 'N').freeze + UNSAFE = Regexp.new("[^#{PATTERN::UNRESERVED}#{PATTERN::RESERVED}]", + false, 'N').freeze + + # for Generic#initialize + SCHEME = Regexp.new("^#{PATTERN::SCHEME}$", false, 'N').freeze #" + USERINFO = Regexp.new("^#{PATTERN::USERINFO}$", false, 'N').freeze #" + HOST = Regexp.new("^#{PATTERN::HOST}$", false, 'N').freeze #" + PORT = Regexp.new("^#{PATTERN::PORT}$", false, 'N').freeze #" + OPAQUE = Regexp.new("^#{PATTERN::OPAQUE_PART}$", false, 'N').freeze #" + REGISTRY = Regexp.new("^#{PATTERN::REG_NAME}$", false, 'N').freeze #" + ABS_PATH = Regexp.new("^#{PATTERN::ABS_PATH}$", false, 'N').freeze #" + REL_PATH = Regexp.new("^#{PATTERN::REL_PATH}$", false, 'N').freeze #" + QUERY = Regexp.new("^#{PATTERN::QUERY}$", false, 'N').freeze #" + FRAGMENT = Regexp.new("^#{PATTERN::FRAGMENT}$", false, 'N').freeze #" + # :startdoc: + end # REGEXP + + module Util # :nodoc: + def make_components_hash(klass, array_hash) + tmp = {} + if array_hash.kind_of?(Array) && + array_hash.size == klass.component.size - 1 + klass.component[1..-1].each_index do |i| + begin + tmp[klass.component[i + 1]] = array_hash[i].clone + rescue TypeError + tmp[klass.component[i + 1]] = array_hash[i] + end + end + + elsif array_hash.kind_of?(Hash) + array_hash.each do |key, value| + begin + tmp[key] = value.clone + rescue TypeError + tmp[key] = value + end + end + else + raise ArgumentError, + "expected Array of or Hash of components of #{klass.to_s} (#{klass.component[1..-1].join(', ')})" + end + tmp[:scheme] = klass.to_s.sub(/\A.*::/, '').downcase + + return tmp + end + module_function :make_components_hash + end + + module Escape + include REGEXP + + # + # == Synopsis + # + # URI.escape(str [, unsafe]) + # + # == Args + # + # +str+:: + # String to replaces in. + # +unsafe+:: + # Regexp that matches all symbols that must be replaced with codes. + # By default uses REGEXP::UNSAFE. + # When this argument is a String, it represents a character set. + # + # == Description + # + # Escapes the string, replacing all unsafe characters with codes. + # + # == Usage + # + # require 'uri' + # + # enc_uri = URI.escape("http://example.com/?a=\11\15") + # p enc_uri + # # => "http://example.com/?a=%09%0D" + # + # p URI.unescape(enc_uri) + # # => "http://example.com/?a=\t\r" + # + # p URI.escape("@?@!", "!?") + # # => "@%3F@%21" + # + def escape(str, unsafe = UNSAFE) + unless unsafe.kind_of?(Regexp) + # perhaps unsafe is String object + unsafe = Regexp.new("[#{Regexp.quote(unsafe)}]", false, 'N') + end + str.gsub(unsafe) do |us| + tmp = '' + us.each_byte do |uc| + tmp << sprintf('%%%02X', uc) + end + tmp + end + end + alias encode escape + # + # == Synopsis + # + # URI.unescape(str) + # + # == Args + # + # +str+:: + # Unescapes the string. + # + # == Usage + # + # require 'uri' + # + # enc_uri = URI.escape("http://example.com/?a=\11\15") + # p enc_uri + # # => "http://example.com/?a=%09%0D" + # + # p URI.unescape(enc_uri) + # # => "http://example.com/?a=\t\r" + # + def unescape(str) + str.gsub(ESCAPED) do + $&[1,2].hex.chr + end + end + alias decode unescape + end + + include REGEXP + extend Escape + + @@schemes = {} + + # + # Base class for all URI exceptions. + # + class Error < StandardError; end + # + # Not a URI. + # + class InvalidURIError < Error; end + # + # Not a URI component. + # + class InvalidComponentError < Error; end + # + # URI is valid, bad usage is not. + # + class BadURIError < Error; end + + # + # == Synopsis + # + # URI::split(uri) + # + # == Args + # + # +uri+:: + # String with URI. + # + # == Description + # + # Splits the string on following parts and returns array with result: + # + # * Scheme + # * Userinfo + # * Host + # * Port + # * Registry + # * Path + # * Opaque + # * Query + # * Fragment + # + # == Usage + # + # require 'uri' + # + # p URI.split("http://www.ruby-lang.org/") + # # => ["http", nil, "www.ruby-lang.org", nil, nil, "/", nil, nil, nil] + # + def self.split(uri) + case uri + when '' + # null uri + + when ABS_URI + scheme, opaque, userinfo, host, port, + registry, path, query, fragment = $~[1..-1] + + # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + # opaque_part = uric_no_slash *uric + + # abs_path = "/" path_segments + # net_path = "//" authority [ abs_path ] + + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + + if !scheme + raise InvalidURIError, + "bad URI(absolute but no scheme): #{uri}" + end + if !opaque && (!path && (!host && !registry)) + raise InvalidURIError, + "bad URI(absolute but no path): #{uri}" + end + + when REL_URI + scheme = nil + opaque = nil + + userinfo, host, port, registry, + rel_segment, abs_path, query, fragment = $~[1..-1] + if rel_segment && abs_path + path = rel_segment + abs_path + elsif rel_segment + path = rel_segment + elsif abs_path + path = abs_path + end + + # URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] + + # relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] + + # net_path = "//" authority [ abs_path ] + # abs_path = "/" path_segments + # rel_path = rel_segment [ abs_path ] + + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + + else + raise InvalidURIError, "bad URI(is not URI?): #{uri}" + end + + path = '' if !path && !opaque # (see RFC2396 Section 5.2) + ret = [ + scheme, + userinfo, host, port, # X + registry, # X + path, # Y + opaque, # Y + query, + fragment + ] + return ret + end + + # + # == Synopsis + # + # URI::parse(uri_str) + # + # == Args + # + # +uri_str+:: + # String with URI. + # + # == Description + # + # Creates one of the URI's subclasses instance from the string. + # + # == Raises + # + # URI::InvalidURIError + # Raised if URI given is not a correct one. + # + # == Usage + # + # require 'uri' + # + # uri = URI.parse("http://www.ruby-lang.org/") + # p uri + # # => # + # p uri.scheme + # # => "http" + # p uri.host + # # => "www.ruby-lang.org" + # + def self.parse(uri) + scheme, userinfo, host, port, + registry, path, opaque, query, fragment = self.split(uri) + + if scheme && @@schemes.include?(scheme.upcase) + @@schemes[scheme.upcase].new(scheme, userinfo, host, port, + registry, path, opaque, query, + fragment) + else + Generic.new(scheme, userinfo, host, port, + registry, path, opaque, query, + fragment) + end + end + + # + # == Synopsis + # + # URI::join(str[, str, ...]) + # + # == Args + # + # +str+:: + # String(s) to work with + # + # == Description + # + # Joins URIs. + # + # == Usage + # + # require 'uri' + # + # p URI.join("http://localhost/","main.rbx") + # # => # + # + def self.join(*str) + u = self.parse(str[0]) + str[1 .. -1].each do |x| + u = u.merge(x) + end + u + end + + # + # == Synopsis + # + # URI::extract(str[, schemes][,&blk]) + # + # == Args + # + # +str+:: + # String to extract URIs from. + # +schemes+:: + # Limit URI matching to a specific schemes. + # + # == Description + # + # Extracts URIs from a string. If block given, iterates through all matched URIs. + # Returns nil if block given or array with matches. + # + # == Usage + # + # require "uri" + # + # URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.") + # # => ["http://foo.example.com/bla", "mailto:test@example.com"] + # + def self.extract(str, schemes = nil, &block) + if block_given? + str.scan(regexp(schemes)) { yield $& } + nil + else + result = [] + str.scan(regexp(schemes)) { result.push $& } + result + end + end + + # + # == Synopsis + # + # URI::regexp([match_schemes]) + # + # == Args + # + # +match_schemes+:: + # Array of schemes. If given, resulting regexp matches to URIs + # whose scheme is one of the match_schemes. + # + # == Description + # Returns a Regexp object which matches to URI-like strings. + # The Regexp object returned by this method includes arbitrary + # number of capture group (parentheses). Never rely on it's number. + # + # == Usage + # + # require 'uri' + # + # # extract first URI from html_string + # html_string.slice(URI.regexp) + # + # # remove ftp URIs + # html_string.sub(URI.regexp(['ftp']) + # + # # You should not rely on the number of parentheses + # html_string.scan(URI.regexp) do |*matches| + # p $& + # end + # + def self.regexp(schemes = nil) + unless schemes + ABS_URI_REF + else + /(?=#{Regexp.union(*schemes)}:)#{PATTERN::X_ABS_URI}/xn + end + end + +end + +module Kernel + # alias for URI.parse. + # + # This method is introduced at 1.8.2. + def URI(uri_str) # :doc: + URI.parse(uri_str) + end + module_function :URI +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/ftp.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/ftp.rb new file mode 100644 index 00000000..4a6ecb8f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/ftp.rb @@ -0,0 +1,148 @@ +# +# = uri/ftp.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: ftp.rb 11757 2007-02-15 11:36:28Z knu $ +# + +require 'uri/generic' + +module URI + + # + # RFC1738 section 3.2. + # + class FTP < Generic + DEFAULT_PORT = 21 + + COMPONENT = [ + :scheme, + :userinfo, :host, :port, + :path, :typecode + ].freeze + # + # Typecode is, "a", "i" or "d". + # As for "a" the text, as for "i" binary, + # as for "d" the directory is displayed. + # "A" with the text, as for "i" being binary, + # is because the respective data type was called ASCII and + # IMAGE with the protocol of FTP. + # + TYPECODE = ['a', 'i', 'd'].freeze + TYPECODE_PREFIX = ';type='.freeze + + def self.new2(user, password, host, port, path, + typecode = nil, arg_check = true) + typecode = nil if typecode.size == 0 + if typecode && !TYPECODE.include?(typecode) + raise ArgumentError, + "bad typecode is specified: #{typecode}" + end + + # do escape + + self.new('ftp', + [user, password], + host, port, nil, + typecode ? path + TYPECODE_PREFIX + typecode : path, + nil, nil, nil, arg_check) + end + + # + # == Description + # + # Creates a new URI::FTP object from components of URI::FTP with + # check. It is scheme, userinfo, host, port, path and typecode. It + # provided by an Array or a Hash. typecode is "a", "i" or "d". + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + + if tmp[:typecode] + if tmp[:typecode].size == 1 + tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode] + end + tmp[:path] << tmp[:typecode] + end + + return super(tmp) + end + + # + # == Description + # + # Create a new URI::FTP object from ``generic'' components with no + # check. + # + # == Usage + # + # require 'uri' + # p ftp = URI.parse("ftp://ftp.ruby-lang.org/pub/ruby/;type=d") + # # => # + # p ftp.typecode + # # => "d" + # + def initialize(*arg) + super(*arg) + @typecode = nil + tmp = @path.index(TYPECODE_PREFIX) + if tmp + typecode = @path[tmp + TYPECODE_PREFIX.size..-1] + self.set_path(@path[0..tmp - 1]) + + if arg[-1] + self.typecode = typecode + else + self.set_typecode(typecode) + end + end + end + attr_reader :typecode + + def check_typecode(v) + if TYPECODE.include?(v) + return true + else + raise InvalidComponentError, + "bad typecode(expected #{TYPECODE.join(', ')}): #{v}" + end + end + private :check_typecode + + def set_typecode(v) + @typecode = v + end + protected :set_typecode + + def typecode=(typecode) + check_typecode(typecode) + set_typecode(typecode) + typecode + end + + def merge(oth) # :nodoc: + tmp = super(oth) + if self != tmp + tmp.set_typecode(oth.typecode) + end + + return tmp + end + + def to_s + save_path = nil + if @typecode + save_path = @path + @path = @path + TYPECODE_PREFIX + @typecode + end + str = super + if @typecode + @path = save_path + end + + return str + end + end + @@schemes['FTP'] = FTP +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/generic.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/generic.rb new file mode 100644 index 00000000..9f0030d9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/generic.rb @@ -0,0 +1,1122 @@ +# +# = uri/generic.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: generic.rb 17096 2008-06-11 06:23:18Z shyouhei $ +# + +require 'uri/common' + +module URI + + # + # Base class for all URI classes. + # Implements generic URI syntax as per RFC 2396. + # + class Generic + include URI + include REGEXP + + DEFAULT_PORT = nil + + # + # Returns default port + # + def self.default_port + self::DEFAULT_PORT + end + + def default_port + self.class.default_port + end + + COMPONENT = [ + :scheme, + :userinfo, :host, :port, :registry, + :path, :opaque, + :query, + :fragment + ].freeze + + # + # Components of the URI in the order. + # + def self.component + self::COMPONENT + end + + USE_REGISTRY = false + + # + # DOC: FIXME! + # + def self.use_registry + self::USE_REGISTRY + end + + # + # == Synopsis + # + # See #new + # + # == Description + # + # At first, tries to create a new URI::Generic instance using + # URI::Generic::build. But, if exception URI::InvalidComponentError is raised, + # then it URI::Escape.escape all URI components and tries again. + # + # + def self.build2(args) + begin + return self.build(args) + rescue InvalidComponentError + if args.kind_of?(Array) + return self.build(args.collect{|x| + if x + URI.escape(x) + else + x + end + }) + elsif args.kind_of?(Hash) + tmp = {} + args.each do |key, value| + tmp[key] = if value + URI.escape(value) + else + value + end + end + return self.build(tmp) + end + end + end + + # + # == Synopsis + # + # See #new + # + # == Description + # + # Creates a new URI::Generic instance from components of URI::Generic + # with check. Components are: scheme, userinfo, host, port, registry, path, + # opaque, query and fragment. You can provide arguments either by an Array or a Hash. + # See #new for hash keys to use or for order of array items. + # + def self.build(args) + if args.kind_of?(Array) && + args.size == ::URI::Generic::COMPONENT.size + tmp = args + elsif args.kind_of?(Hash) + tmp = ::URI::Generic::COMPONENT.collect do |c| + if args.include?(c) + args[c] + else + nil + end + end + else + raise ArgumentError, + "expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})" + end + + tmp << true + return self.new(*tmp) + end + # + # == Args + # + # +scheme+:: + # Protocol scheme, i.e. 'http','ftp','mailto' and so on. + # +userinfo+:: + # User name and password, i.e. 'sdmitry:bla' + # +host+:: + # Server host name + # +port+:: + # Server port + # +registry+:: + # DOC: FIXME! + # +path+:: + # Path on server + # +opaque+:: + # DOC: FIXME! + # +query+:: + # Query data + # +fragment+:: + # A part of URI after '#' sign + # +arg_check+:: + # Check arguments [false by default] + # + # == Description + # + # Creates a new URI::Generic instance from ``generic'' components without check. + # + def initialize(scheme, + userinfo, host, port, registry, + path, opaque, + query, + fragment, + arg_check = false) + @scheme = nil + @user = nil + @password = nil + @host = nil + @port = nil + @path = nil + @query = nil + @opaque = nil + @registry = nil + @fragment = nil + + if arg_check + self.scheme = scheme + self.userinfo = userinfo + self.host = host + self.port = port + self.path = path + self.query = query + self.opaque = opaque + self.registry = registry + self.fragment = fragment + else + self.set_scheme(scheme) + self.set_userinfo(userinfo) + self.set_host(host) + self.set_port(port) + self.set_path(path) + self.set_query(query) + self.set_opaque(opaque) + self.set_registry(registry) + self.set_fragment(fragment) + end + if @registry && !self.class.use_registry + raise InvalidURIError, + "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)" + end + + @scheme.freeze if @scheme + self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2) + self.set_port(self.default_port) if self.default_port && !@port + end + attr_reader :scheme + attr_reader :host + attr_reader :port + attr_reader :registry + attr_reader :path + attr_reader :query + attr_reader :opaque + attr_reader :fragment + + # replace self by other URI object + def replace!(oth) + if self.class != oth.class + raise ArgumentError, "expected #{self.class} object" + end + + component.each do |c| + self.__send__("#{c}=", oth.__send__(c)) + end + end + private :replace! + + def component + self.class.component + end + + def check_scheme(v) + if v && SCHEME !~ v + raise InvalidComponentError, + "bad component(expected scheme component): #{v}" + end + + return true + end + private :check_scheme + + def set_scheme(v) + @scheme = v + end + protected :set_scheme + + def scheme=(v) + check_scheme(v) + set_scheme(v) + v + end + + def check_userinfo(user, password = nil) + if !password + user, password = split_userinfo(user) + end + check_user(user) + check_password(password, user) + + return true + end + private :check_userinfo + + def check_user(v) + if @registry || @opaque + raise InvalidURIError, + "can not set user with registry or opaque" + end + + return v unless v + + if USERINFO !~ v + raise InvalidComponentError, + "bad component(expected userinfo component or user component): #{v}" + end + + return true + end + private :check_user + + def check_password(v, user = @user) + if @registry || @opaque + raise InvalidURIError, + "can not set password with registry or opaque" + end + return v unless v + + if !user + raise InvalidURIError, + "password component depends user component" + end + + if USERINFO !~ v + raise InvalidComponentError, + "bad component(expected user component): #{v}" + end + + return true + end + private :check_password + + # + # Sets userinfo, argument is string like 'name:pass' + # + def userinfo=(userinfo) + if userinfo.nil? + return nil + end + check_userinfo(*userinfo) + set_userinfo(*userinfo) + # returns userinfo + end + + def user=(user) + check_user(user) + set_user(user) + # returns user + end + + def password=(password) + check_password(password) + set_password(password) + # returns password + end + + def set_userinfo(user, password = nil) + unless password + user, password = split_userinfo(user) + end + @user = user + @password = password if password + + [@user, @password] + end + protected :set_userinfo + + def set_user(v) + set_userinfo(v, @password) + v + end + protected :set_user + + def set_password(v) + @password = v + # returns v + end + protected :set_password + + def split_userinfo(ui) + return nil, nil unless ui + user, password = ui.split(/:/, 2) + + return user, password + end + private :split_userinfo + + def escape_userpass(v) + v = URI.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/ + end + private :escape_userpass + + def userinfo + if @user.nil? + nil + elsif @password.nil? + @user + else + @user + ':' + @password + end + end + + def user + @user + end + + def password + @password + end + + def check_host(v) + return v unless v + + if @registry || @opaque + raise InvalidURIError, + "can not set host with registry or opaque" + elsif HOST !~ v + raise InvalidComponentError, + "bad component(expected host component): #{v}" + end + + return true + end + private :check_host + + def set_host(v) + @host = v + end + protected :set_host + + def host=(v) + check_host(v) + set_host(v) + v + end + + def check_port(v) + return v unless v + + if @registry || @opaque + raise InvalidURIError, + "can not set port with registry or opaque" + elsif !v.kind_of?(Fixnum) && PORT !~ v + raise InvalidComponentError, + "bad component(expected port component): #{v}" + end + + return true + end + private :check_port + + def set_port(v) + unless !v || v.kind_of?(Fixnum) + if v.empty? + v = nil + else + v = v.to_i + end + end + @port = v + end + protected :set_port + + def port=(v) + check_port(v) + set_port(v) + port + end + + def check_registry(v) + return v unless v + + # raise if both server and registry are not nil, because: + # authority = server | reg_name + # server = [ [ userinfo "@" ] hostport ] + if @host || @port || @user # userinfo = @user + ':' + @password + raise InvalidURIError, + "can not set registry with host, port, or userinfo" + elsif v && REGISTRY !~ v + raise InvalidComponentError, + "bad component(expected registry component): #{v}" + end + + return true + end + private :check_registry + + def set_registry(v) + @registry = v + end + protected :set_registry + + def registry=(v) + check_registry(v) + set_registry(v) + v + end + + def check_path(v) + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if v && @opaque + raise InvalidURIError, + "path conflicts with opaque" + end + + if @scheme + if v && v != '' && ABS_PATH !~ v + raise InvalidComponentError, + "bad component(expected absolute path component): #{v}" + end + else + if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v + raise InvalidComponentError, + "bad component(expected relative path component): #{v}" + end + end + + return true + end + private :check_path + + def set_path(v) + @path = v + end + protected :set_path + + def path=(v) + check_path(v) + set_path(v) + v + end + + def check_query(v) + return v unless v + + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if @opaque + raise InvalidURIError, + "query conflicts with opaque" + end + + if v && v != '' && QUERY !~ v + raise InvalidComponentError, + "bad component(expected query component): #{v}" + end + + return true + end + private :check_query + + def set_query(v) + @query = v + end + protected :set_query + + def query=(v) + check_query(v) + set_query(v) + v + end + + def check_opaque(v) + return v unless v + + # raise if both hier and opaque are not nil, because: + # absoluteURI = scheme ":" ( hier_part | opaque_part ) + # hier_part = ( net_path | abs_path ) [ "?" query ] + if @host || @port || @user || @path # userinfo = @user + ':' + @password + raise InvalidURIError, + "can not set opaque with host, port, userinfo or path" + elsif v && OPAQUE !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + return true + end + private :check_opaque + + def set_opaque(v) + @opaque = v + end + protected :set_opaque + + def opaque=(v) + check_opaque(v) + set_opaque(v) + v + end + + def check_fragment(v) + return v unless v + + if v && v != '' && FRAGMENT !~ v + raise InvalidComponentError, + "bad component(expected fragment component): #{v}" + end + + return true + end + private :check_fragment + + def set_fragment(v) + @fragment = v + end + protected :set_fragment + + def fragment=(v) + check_fragment(v) + set_fragment(v) + v + end + + # + # Checks if URI has a path + # + def hierarchical? + if @path + true + else + false + end + end + + # + # Checks if URI is an absolute one + # + def absolute? + if @scheme + true + else + false + end + end + alias absolute absolute? + + # + # Checks if URI is relative + # + def relative? + !absolute? + end + + def split_path(path) + path.split(%r{/+}, -1) + end + private :split_path + + def merge_path(base, rel) + # RFC2396, Section 5.2, 5) + if rel[0] == ?/ #/ + # RFC2396, Section 5.2, 5) + return rel + + else + # RFC2396, Section 5.2, 6) + base_path = split_path(base) + rel_path = split_path(rel) + + # RFC2396, Section 5.2, 6), a) + base_path << '' if base_path.last == '..' + while i = base_path.index('..') + base_path.slice!(i - 1, 2) + end + if base_path.empty? + base_path = [''] # keep '/' for root directory + else + base_path.pop + end + + # RFC2396, Section 5.2, 6), c) + # RFC2396, Section 5.2, 6), d) + rel_path.push('') if rel_path.last == '.' || rel_path.last == '..' + rel_path.delete('.') + + # RFC2396, Section 5.2, 6), e) + tmp = [] + rel_path.each do |x| + if x == '..' && + !(tmp.empty? || tmp.last == '..') + tmp.pop + else + tmp << x + end + end + + add_trailer_slash = true + while x = tmp.shift + if x == '..' && base_path.size > 1 + # RFC2396, Section 4 + # a .. or . in an absolute path has no special meaning + base_path.pop + else + # if x == '..' + # valid absolute (but abnormal) path "/../..." + # else + # valid absolute path + # end + base_path << x + tmp.each {|t| base_path << t} + add_trailer_slash = false + break + end + end + base_path.push('') if add_trailer_slash + + return base_path.join('/') + end + end + private :merge_path + + # + # == Args + # + # +oth+:: + # URI or String + # + # == Description + # + # Destructive form of #merge + # + # == Usage + # + # require 'uri' + # + # uri = URI.parse("http://my.example.com") + # uri.merge!("/main.rbx?page=1") + # p uri + # # => # + # + def merge!(oth) + t = merge(oth) + if self == t + nil + else + replace!(t) + self + end + end + + # + # == Args + # + # +oth+:: + # URI or String + # + # == Description + # + # Merges two URI's. + # + # == Usage + # + # require 'uri' + # + # uri = URI.parse("http://my.example.com") + # p uri.merge("/main.rbx?page=1") + # # => # + # + def merge(oth) + begin + base, rel = merge0(oth) + rescue + raise $!.class, $!.message + end + + if base == rel + return base + end + + authority = rel.userinfo || rel.host || rel.port + + # RFC2396, Section 5.2, 2) + if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query + base.set_fragment(rel.fragment) if rel.fragment + return base + end + + base.set_query(nil) + base.set_fragment(nil) + + # RFC2396, Section 5.2, 4) + if !authority + base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path + else + # RFC2396, Section 5.2, 4) + base.set_path(rel.path) if rel.path + end + + # RFC2396, Section 5.2, 7) + base.set_userinfo(rel.userinfo) if rel.userinfo + base.set_host(rel.host) if rel.host + base.set_port(rel.port) if rel.port + base.set_query(rel.query) if rel.query + base.set_fragment(rel.fragment) if rel.fragment + + return base + end # merge + alias + merge + + # return base and rel. + # you can modify `base', but can not `rel'. + def merge0(oth) + case oth + when Generic + when String + oth = URI.parse(oth) + else + raise ArgumentError, + "bad argument(expected URI object or URI string)" + end + + if self.relative? && oth.relative? + raise BadURIError, + "both URI are relative" + end + + if self.absolute? && oth.absolute? + #raise BadURIError, + # "both URI are absolute" + # hmm... should return oth for usability? + return oth, oth + end + + if self.absolute? + return self.dup, oth + else + return oth, oth + end + end + private :merge0 + + def route_from_path(src, dst) + # RFC2396, Section 4.2 + return '' if src == dst + + src_path = split_path(src) + dst_path = split_path(dst) + + # hmm... dst has abnormal absolute path, + # like "/./", "/../", "/x/../", ... + if dst_path.include?('..') || + dst_path.include?('.') + return dst.dup + end + + src_path.pop + + # discard same parts + while dst_path.first == src_path.first + break if dst_path.empty? + + src_path.shift + dst_path.shift + end + + tmp = dst_path.join('/') + + # calculate + if src_path.empty? + if tmp.empty? + return './' + elsif dst_path.first.include?(':') # (see RFC2396 Section 5) + return './' + tmp + else + return tmp + end + end + + return '../' * src_path.size + tmp + end + private :route_from_path + + def route_from0(oth) + case oth + when Generic + when String + oth = URI.parse(oth) + else + raise ArgumentError, + "bad argument(expected URI object or URI string)" + end + + if self.relative? + raise BadURIError, + "relative URI: #{self}" + end + if oth.relative? + raise BadURIError, + "relative URI: #{oth}" + end + + if self.scheme != oth.scheme + return self, self.dup + end + rel = URI::Generic.new(nil, # it is relative URI + self.userinfo, self.host, self.port, + self.registry, self.path, self.opaque, + self.query, self.fragment) + + if rel.userinfo != oth.userinfo || + rel.host.to_s.downcase != oth.host.to_s.downcase || + rel.port != oth.port + if self.userinfo.nil? && self.host.nil? + return self, self.dup + end + rel.set_port(nil) if rel.port == oth.default_port + return rel, rel + end + rel.set_userinfo(nil) + rel.set_host(nil) + rel.set_port(nil) + + if rel.path && rel.path == oth.path + rel.set_path('') + rel.set_query(nil) if rel.query == oth.query + return rel, rel + elsif rel.opaque && rel.opaque == oth.opaque + rel.set_opaque('') + rel.set_query(nil) if rel.query == oth.query + return rel, rel + end + + # you can modify `rel', but can not `oth'. + return oth, rel + end + private :route_from0 + # + # == Args + # + # +oth+:: + # URI or String + # + # == Description + # + # Calculates relative path from oth to self + # + # == Usage + # + # require 'uri' + # + # uri = URI.parse('http://my.example.com/main.rbx?page=1') + # p uri.route_from('http://my.example.com') + # #=> # + # + def route_from(oth) + # you can modify `rel', but can not `oth'. + begin + oth, rel = route_from0(oth) + rescue + raise $!.class, $!.message + end + if oth == rel + return rel + end + + rel.set_path(route_from_path(oth.path, self.path)) + if rel.path == './' && self.query + # "./?foo" -> "?foo" + rel.set_path('') + end + + return rel + end + + alias - route_from + + # + # == Args + # + # +oth+:: + # URI or String + # + # == Description + # + # Calculates relative path to oth from self + # + # == Usage + # + # require 'uri' + # + # uri = URI.parse('http://my.example.com') + # p uri.route_to('http://my.example.com/main.rbx?page=1') + # #=> # + # + def route_to(oth) + case oth + when Generic + when String + oth = URI.parse(oth) + else + raise ArgumentError, + "bad argument(expected URI object or URI string)" + end + + oth.route_from(self) + end + + # + # Returns normalized URI + # + def normalize + uri = dup + uri.normalize! + uri + end + + # + # Destructive version of #normalize + # + def normalize! + if path && path == '' + set_path('/') + end + if host && host != host.downcase + set_host(self.host.downcase) + end + end + + def path_query + str = @path + if @query + str += '?' + @query + end + str + end + private :path_query + + # + # Constructs String from URI + # + def to_s + str = '' + if @scheme + str << @scheme + str << ':' + end + + if @opaque + str << @opaque + + else + if @registry + str << @registry + else + if @host + str << '//' + end + if self.userinfo + str << self.userinfo + str << '@' + end + if @host + str << @host + end + if @port && @port != self.default_port + str << ':' + str << @port.to_s + end + end + + str << path_query + end + + if @fragment + str << '#' + str << @fragment + end + + str + end + + # + # Compares to URI's + # + def ==(oth) + if self.class == oth.class + self.normalize.component_ary == oth.normalize.component_ary + else + false + end + end + + def hash + self.component_ary.hash + end + + def eql?(oth) + self.component_ary.eql?(oth.component_ary) + end + +=begin + +--- URI::Generic#===(oth) + +=end +# def ===(oth) +# raise NotImplementedError +# end + +=begin +=end + def component_ary + component.collect do |x| + self.send(x) + end + end + protected :component_ary + + # == Args + # + # +components+:: + # Multiple Symbol arguments defined in URI::HTTP + # + # == Description + # + # Selects specified components from URI + # + # == Usage + # + # require 'uri' + # + # uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx') + # p uri.select(:userinfo, :host, :path) + # # => ["myuser:mypass", "my.example.com", "/test.rbx"] + # + def select(*components) + components.collect do |c| + if component.include?(c) + self.send(c) + else + raise ArgumentError, + "expected of components of #{self.class} (#{self.class.component.join(', ')})" + end + end + end + + @@to_s = Kernel.instance_method(:to_s) + def inspect + @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"} + end + + def coerce(oth) + case oth + when String + oth = URI.parse(oth) + else + super + end + + return oth, self + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/http.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/http.rb new file mode 100644 index 00000000..dd2e792a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/http.rb @@ -0,0 +1,100 @@ +# +# = uri/http.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: http.rb 11747 2007-02-15 02:41:45Z knu $ +# + +require 'uri/generic' + +module URI + + # + # The syntax of HTTP URIs is defined in RFC1738 section 3.3. + # + # Note that the Ruby URI library allows HTTP URLs containing usernames and + # passwords. This is not legal as per the RFC, but used to be + # supported in Internet Explorer 5 and 6, before the MS04-004 security + # update. See . + # + class HTTP < Generic + DEFAULT_PORT = 80 + + COMPONENT = [ + :scheme, + :userinfo, :host, :port, + :path, + :query, + :fragment + ].freeze + + # + # == Description + # + # Create a new URI::HTTP object from components, with syntax checking. + # + # The components accepted are userinfo, host, port, path, query and + # fragment. + # + # The components should be provided either as an Array, or as a Hash + # with keys formed by preceding the component names with a colon. + # + # If an Array is used, the components must be passed in the order + # [userinfo, host, port, path, query, fragment]. + # + # Example: + # + # newuri = URI::HTTP.build({:host => 'www.example.com', + # :path> => '/foo/bar'}) + # + # newuri = URI::HTTP.build([nil, "www.example.com", nil, "/path", + # "query", 'fragment']) + # + # Currently, if passed userinfo components this method generates + # invalid HTTP URIs as per RFC 1738. + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + return super(tmp) + end + + # + # == Description + # + # Create a new URI::HTTP object from generic URI components as per + # RFC 2396. No HTTP-specific syntax checking (as per RFC 1738) is + # performed. + # + # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, + # +opaque+, +query+ and +fragment+, in that order. + # + # Example: + # + # uri = URI::HTTP.new(['http', nil, "www.example.com", nil, "/path", + # "query", 'fragment']) + # + def initialize(*arg) + super(*arg) + end + + # + # == Description + # + # Returns the full path for an HTTP request, as required by Net::HTTP::Get. + # + # If the URI contains a query, the full path is URI#path + '?' + URI#query. + # Otherwise, the path is simply URI#path. + # + def request_uri + r = path_query + if r[0] != ?/ + r = '/' + r + end + + r + end + end + + @@schemes['HTTP'] = HTTP +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/https.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/https.rb new file mode 100644 index 00000000..5043ae6a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/https.rb @@ -0,0 +1,20 @@ +# +# = uri/https.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: https.rb 11747 2007-02-15 02:41:45Z knu $ +# + +require 'uri/http' + +module URI + + # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather + # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs; + # see URI::HTTP. + class HTTPS < HTTP + DEFAULT_PORT = 443 + end + @@schemes['HTTPS'] = HTTPS +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/ldap.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/ldap.rb new file mode 100644 index 00000000..7c14ff88 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/ldap.rb @@ -0,0 +1,190 @@ +# +# = uri/ldap.rb +# +# Author:: +# Takaaki Tateishi +# Akira Yamada +# License:: +# URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada. +# You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: ldap.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# + +require 'uri/generic' + +module URI + + # + # LDAP URI SCHEMA (described in RFC2255) + # ldap:///[?[?[?[?]]]] + # + class LDAP < Generic + + DEFAULT_PORT = 389 + + COMPONENT = [ + :scheme, + :host, :port, + :dn, + :attributes, + :scope, + :filter, + :extensions, + ].freeze + + SCOPE = [ + SCOPE_ONE = 'one', + SCOPE_SUB = 'sub', + SCOPE_BASE = 'base', + ].freeze + + def self.build(args) + tmp = Util::make_components_hash(self, args) + + if tmp[:dn] + tmp[:path] = tmp[:dn] + end + + query = [] + [:extensions, :filter, :scope, :attributes].collect do |x| + next if !tmp[x] && query.size == 0 + query.unshift(tmp[x]) + end + + tmp[:query] = query.join('?') + + return super(tmp) + end + + def initialize(*arg) + super(*arg) + + if @fragment + raise InvalidURIError, 'bad LDAP URL' + end + + parse_dn + parse_query + end + + def parse_dn + @dn = @path[1..-1] + end + private :parse_dn + + def parse_query + @attributes = nil + @scope = nil + @filter = nil + @extensions = nil + + if @query + attrs, scope, filter, extensions = @query.split('?') + + @attributes = attrs if attrs && attrs.size > 0 + @scope = scope if scope && scope.size > 0 + @filter = filter if filter && filter.size > 0 + @extensions = extensions if extensions && extensions.size > 0 + end + end + private :parse_query + + def build_path_query + @path = '/' + @dn + + query = [] + [@extensions, @filter, @scope, @attributes].each do |x| + next if !x && query.size == 0 + query.unshift(x) + end + @query = query.join('?') + end + private :build_path_query + + def dn + @dn + end + + def set_dn(val) + @dn = val + build_path_query + @dn + end + protected :set_dn + + def dn=(val) + set_dn(val) + val + end + + def attributes + @attributes + end + + def set_attributes(val) + @attributes = val + build_path_query + @attributes + end + protected :set_attributes + + def attributes=(val) + set_attributes(val) + val + end + + def scope + @scope + end + + def set_scope(val) + @scope = val + build_path_query + @scope + end + protected :set_scope + + def scope=(val) + set_scope(val) + val + end + + def filter + @filter + end + + def set_filter(val) + @filter = val + build_path_query + @filter + end + protected :set_filter + + def filter=(val) + set_filter(val) + val + end + + def extensions + @extensions + end + + def set_extensions(val) + @extensions = val + build_path_query + @extensions + end + protected :set_extensions + + def extensions=(val) + set_extensions(val) + val + end + + def hierarchical? + false + end + end + + @@schemes['LDAP'] = LDAP +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/mailto.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/mailto.rb new file mode 100644 index 00000000..c8d3e3ea --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/uri/mailto.rb @@ -0,0 +1,266 @@ +# +# = uri/mailto.rb +# +# Author:: Akira Yamada +# License:: You can redistribute it and/or modify it under the same term as Ruby. +# Revision:: $Id: mailto.rb 11747 2007-02-15 02:41:45Z knu $ +# + +require 'uri/generic' + +module URI + + # + # RFC2368, The mailto URL scheme + # + class MailTo < Generic + include REGEXP + + DEFAULT_PORT = nil + + COMPONENT = [ :scheme, :to, :headers ].freeze + + # :stopdoc: + # "hname" and "hvalue" are encodings of an RFC 822 header name and + # value, respectively. As with "to", all URL reserved characters must + # be encoded. + # + # "#mailbox" is as specified in RFC 822 [RFC822]. This means that it + # consists of zero or more comma-separated mail addresses, possibly + # including "phrase" and "comment" components. Note that all URL + # reserved characters in "to" must be encoded: in particular, + # parentheses, commas, and the percent sign ("%"), which commonly occur + # in the "mailbox" syntax. + # + # Within mailto URLs, the characters "?", "=", "&" are reserved. + + # hname = *urlc + # hvalue = *urlc + # header = hname "=" hvalue + HEADER_PATTERN = "(?:[^?=&]*=[^?=&]*)".freeze + HEADER_REGEXP = Regexp.new(HEADER_PATTERN, 'N').freeze + # headers = "?" header *( "&" header ) + # to = #mailbox + # mailtoURL = "mailto:" [ to ] [ headers ] + MAILBOX_PATTERN = "(?:#{PATTERN::ESCAPED}|[^(),%?=&])".freeze + MAILTO_REGEXP = Regexp.new(" # :nodoc: + \\A + (#{MAILBOX_PATTERN}*?) (?# 1: to) + (?: + \\? + (#{HEADER_PATTERN}(?:\\&#{HEADER_PATTERN})*) (?# 2: headers) + )? + (?: + \\# + (#{PATTERN::FRAGMENT}) (?# 3: fragment) + )? + \\z + ", Regexp::EXTENDED, 'N').freeze + # :startdoc: + + # + # == Description + # + # Creates a new URI::MailTo object from components, with syntax checking. + # + # Components can be provided as an Array or Hash. If an Array is used, + # the components must be supplied as [to, headers]. + # + # If a Hash is used, the keys are the component names preceded by colons. + # + # The headers can be supplied as a pre-encoded string, such as + # "subject=subscribe&cc=address", or as an Array of Arrays like + # [['subject', 'subscribe'], ['cc', 'address']] + # + # Examples: + # + # require 'uri' + # + # m1 = URI::MailTo.build(['joe@example.com', 'subject=Ruby']) + # puts m1.to_s -> mailto:joe@example.com?subject=Ruby + # + # m2 = URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]]) + # puts m2.to_s -> mailto:john@example.com?Subject=Ruby&Cc=jack@example.com + # + # m3 = URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]}) + # puts m3.to_s -> mailto:listman@example.com?subject=subscribe + # + def self.build(args) + tmp = Util::make_components_hash(self, args) + + if tmp[:to] + tmp[:opaque] = tmp[:to] + else + tmp[:opaque] = '' + end + + if tmp[:headers] + tmp[:opaque] << '?' + + if tmp[:headers].kind_of?(Array) + tmp[:opaque] << tmp[:headers].collect { |x| + if x.kind_of?(Array) + x[0] + '=' + x[1..-1].to_s + else + x.to_s + end + }.join('&') + + elsif tmp[:headers].kind_of?(Hash) + tmp[:opaque] << tmp[:headers].collect { |h,v| + h + '=' + v + }.join('&') + + else + tmp[:opaque] << tmp[:headers].to_s + end + end + + return super(tmp) + end + + # + # == Description + # + # Creates a new URI::MailTo object from generic URL components with + # no syntax checking. + # + # This method is usually called from URI::parse, which checks + # the validity of each component. + # + def initialize(*arg) + super(*arg) + + @to = nil + @headers = [] + + if MAILTO_REGEXP =~ @opaque + if arg[-1] + self.to = $1 + self.headers = $2 + else + set_to($1) + set_headers($2) + end + + else + raise InvalidComponentError, + "unrecognised opaque part for mailtoURL: #{@opaque}" + end + end + + # The primary e-mail address of the URL, as a String + attr_reader :to + + # E-mail headers set by the URL, as an Array of Arrays + attr_reader :headers + + def check_to(v) + return true unless v + return true if v.size == 0 + + if OPAQUE !~ v || /\A#{MAILBOX_PATTERN}*\z/o !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + return true + end + private :check_to + + def set_to(v) + @to = v + end + protected :set_to + + def to=(v) + check_to(v) + set_to(v) + v + end + + def check_headers(v) + return true unless v + return true if v.size == 0 + + if OPAQUE !~ v || + /\A(#{HEADER_PATTERN}(?:\&#{HEADER_PATTERN})*)\z/o !~ v + raise InvalidComponentError, + "bad component(expected opaque component): #{v}" + end + + return true + end + private :check_headers + + def set_headers(v) + @headers = [] + if v + v.scan(HEADER_REGEXP) do |x| + @headers << x.split(/=/o, 2) + end + end + end + protected :set_headers + + def headers=(v) + check_headers(v) + set_headers(v) + v + end + + def to_s + @scheme + ':' + + if @to + @to + else + '' + end + + if @headers.size > 0 + '?' + @headers.collect{|x| x.join('=')}.join('&') + else + '' + end + + if @fragment + '#' + @fragment + else + '' + end + end + + # Returns the RFC822 e-mail text equivalent of the URL, as a String. + # + # Example: + # + # require 'uri' + # + # uri = URI.parse("mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr") + # uri.to_mailtext + # # => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n" + # + def to_mailtext + to = URI::unescape(@to) + head = '' + body = '' + @headers.each do |x| + case x[0] + when 'body' + body = URI::unescape(x[1]) + when 'to' + to << ', ' + URI::unescape(x[1]) + else + head << URI::unescape(x[0]).capitalize + ': ' + + URI::unescape(x[1]) + "\n" + end + end + + return "To: #{to} +#{head} +#{body} +" + end + alias to_rfc822text to_mailtext + end + + @@schemes['MAILTO'] = MailTo +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/weakref.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/weakref.rb new file mode 100644 index 00000000..591819c9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/weakref.rb @@ -0,0 +1,100 @@ +require "delegate" + +# WeakRef is a class to represent a reference to an object that is not seen by +# the tracing phase of the garbage collector. This allows the referenced +# object to be garbage collected as if nothing is referring to it. Because +# WeakRef delegates method calls to the referenced object, it may be used in +# place of that object, i.e. it is of the same duck type. +# +# Usage: +# +# foo = Object.new +# foo = Object.new +# p foo.to_s # original's class +# foo = WeakRef.new(foo) +# p foo.to_s # should be same class +# ObjectSpace.garbage_collect +# p foo.to_s # should raise exception (recycled) +class WeakRef [ref,...] + @@id_rev_map = {} # ref -> obj + @@final = lambda{|id| + __old_status = Thread.critical + Thread.critical = true + begin + rids = @@id_map[id] + if rids + for rid in rids + @@id_rev_map.delete(rid) + end + @@id_map.delete(id) + end + rid = @@id_rev_map[id] + if rid + @@id_rev_map.delete(id) + @@id_map[rid].delete(id) + @@id_map.delete(rid) if @@id_map[rid].empty? + end + ensure + Thread.critical = __old_status + end + } + + # Create a new WeakRef from +orig+. + def initialize(orig) + super + __setobj__(orig) + end + + # Return the object this WeakRef references. Raises RefError if the object + # has been garbage collected. The object returned is the object to which + # method calls are delegated (see Delegator). + def __getobj__ + unless @@id_rev_map[self.__id__] == @__id + raise RefError, "Illegal Reference - probably recycled", caller(2) + end + begin + ObjectSpace._id2ref(@__id) + rescue RangeError + raise RefError, "Illegal Reference - probably recycled", caller(2) + end + end + + def __setobj__(obj) + @__id = obj.__id__ + __old_status = Thread.critical + begin + Thread.critical = true + unless @@id_rev_map.key?(self) + ObjectSpace.define_finalizer obj, @@final + ObjectSpace.define_finalizer self, @@final + end + @@id_map[@__id] = [] unless @@id_map[@__id] + ensure + Thread.critical = __old_status + end + @@id_map[@__id].push self.__id__ + @@id_rev_map[self.__id__] = @__id + end + + # Returns true if the referenced object still exists, and false if it has + # been garbage collected. + def weakref_alive? + @@id_rev_map[self.__id__] == @__id + end +end + +if __FILE__ == $0 + require 'thread' + foo = Object.new + p foo.to_s # original's class + foo = WeakRef.new(foo) + p foo.to_s # should be same class + ObjectSpace.garbage_collect + p foo.to_s # should raise exception (recycled) +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick.rb new file mode 100644 index 00000000..8fca81ba --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick.rb @@ -0,0 +1,29 @@ +# +# WEBrick -- WEB server toolkit. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $ + +require 'webrick/compat.rb' + +require 'webrick/version.rb' +require 'webrick/config.rb' +require 'webrick/log.rb' +require 'webrick/server.rb' +require 'webrick/utils.rb' +require 'webrick/accesslog' + +require 'webrick/htmlutils.rb' +require 'webrick/httputils.rb' +require 'webrick/cookie.rb' +require 'webrick/httpversion.rb' +require 'webrick/httpstatus.rb' +require 'webrick/httprequest.rb' +require 'webrick/httpresponse.rb' +require 'webrick/httpserver.rb' +require 'webrick/httpservlet.rb' +require 'webrick/httpauth.rb' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/accesslog.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/accesslog.rb new file mode 100644 index 00000000..f9776954 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/accesslog.rb @@ -0,0 +1,67 @@ +# +# accesslog.rb -- Access log handling utilities +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 keita yamaguchi +# Copyright (c) 2002 Internet Programming with Ruby writers +# +# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $ + +module WEBrick + module AccessLog + class AccessLogError < StandardError; end + + CLF_TIME_FORMAT = "[%d/%b/%Y:%H:%M:%S %Z]" + COMMON_LOG_FORMAT = "%h %l %u %t \"%r\" %s %b" + CLF = COMMON_LOG_FORMAT + REFERER_LOG_FORMAT = "%{Referer}i -> %U" + AGENT_LOG_FORMAT = "%{User-Agent}i" + COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\"" + + module_function + + # This format specification is a subset of mod_log_config of Apache. + # http://httpd.apache.org/docs/mod/mod_log_config.html#formats + def setup_params(config, req, res) + params = Hash.new("") + params["a"] = req.peeraddr[3] + params["b"] = res.sent_size + params["e"] = ENV + params["f"] = res.filename || "" + params["h"] = req.peeraddr[2] + params["i"] = req + params["l"] = "-" + params["m"] = req.request_method + params["n"] = req.attributes + params["o"] = res + params["p"] = req.port + params["q"] = req.query_string + params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '') + params["s"] = res.status # won't support "%>s" + params["t"] = req.request_time + params["T"] = Time.now - req.request_time + params["u"] = req.user || "-" + params["U"] = req.unparsed_uri + params["v"] = config[:ServerName] + params + end + + def format(format_string, params) + format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){ + param, spec = $1, $2 + case spec[0] + when ?e, ?i, ?n, ?o + raise AccessLogError, + "parameter is required for \"#{spec}\"" unless param + params[spec][param] || "-" + when ?t + params[spec].strftime(param || CLF_TIME_FORMAT) + when ?% + "%" + else + params[spec] + end + } + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/cgi.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/cgi.rb new file mode 100644 index 00000000..3ece0e0b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/cgi.rb @@ -0,0 +1,257 @@ +# +# cgi.rb -- Yet another CGI library +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $Id: cgi.rb 11708 2007-02-12 23:01:19Z shyouhei $ + +require "webrick/httprequest" +require "webrick/httpresponse" +require "webrick/config" +require "stringio" + +module WEBrick + class CGI + CGIError = Class.new(StandardError) + + attr_reader :config, :logger + + def initialize(*args) + if defined?(MOD_RUBY) + unless ENV.has_key?("GATEWAY_INTERFACE") + Apache.request.setup_cgi_env + end + end + if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"] + httpv = $1 + end + @config = WEBrick::Config::HTTP.dup.update( + :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null", + :HTTPVersion => HTTPVersion.new(httpv || "1.0"), + :RunOnCGI => true, # to detect if it runs on CGI. + :NPH => false # set true to run as NPH script. + ) + if config = args.shift + @config.update(config) + end + @config[:Logger] ||= WEBrick::BasicLog.new($stderr) + @logger = @config[:Logger] + @options = args + end + + def [](key) + @config[key] + end + + def start(env=ENV, stdin=$stdin, stdout=$stdout) + sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout) + req = HTTPRequest.new(@config) + res = HTTPResponse.new(@config) + unless @config[:NPH] or defined?(MOD_RUBY) + def res.setup_header + unless @header["status"] + phrase = HTTPStatus::reason_phrase(@status) + @header["status"] = "#{@status} #{phrase}" + end + super + end + def res.status_line + "" + end + end + + begin + req.parse(sock) + req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup + req.path_info = (env["PATH_INFO"] || "").dup + req.query_string = env["QUERY_STRING"] + req.user = env["REMOTE_USER"] + res.request_method = req.request_method + res.request_uri = req.request_uri + res.request_http_version = req.http_version + res.keep_alive = req.keep_alive? + self.service(req, res) + rescue HTTPStatus::Error => ex + res.set_error(ex) + rescue HTTPStatus::Status => ex + res.status = ex.code + rescue Exception => ex + @logger.error(ex) + res.set_error(ex, true) + ensure + req.fixup + if defined?(MOD_RUBY) + res.setup_header + Apache.request.status_line = "#{res.status} #{res.reason_phrase}" + Apache.request.status = res.status + table = Apache.request.headers_out + res.header.each{|key, val| + case key + when /^content-encoding$/i + Apache::request.content_encoding = val + when /^content-type$/i + Apache::request.content_type = val + else + table[key] = val.to_s + end + } + res.cookies.each{|cookie| + table.add("Set-Cookie", cookie.to_s) + } + Apache.request.send_http_header + res.send_body(sock) + else + res.send_response(sock) + end + end + end + + def service(req, res) + method_name = "do_" + req.request_method.gsub(/-/, "_") + if respond_to?(method_name) + __send__(method_name, req, res) + else + raise HTTPStatus::MethodNotAllowed, + "unsupported method `#{req.request_method}'." + end + end + + class Socket + include Enumerable + + private + + def initialize(config, env, stdin, stdout) + @config = config + @env = env + @header_part = StringIO.new + @body_part = stdin + @out_port = stdout + @out_port.binmode + + @server_addr = @env["SERVER_ADDR"] || "0.0.0.0" + @server_name = @env["SERVER_NAME"] + @server_port = @env["SERVER_PORT"] + @remote_addr = @env["REMOTE_ADDR"] + @remote_host = @env["REMOTE_HOST"] || @remote_addr + @remote_port = @env["REMOTE_PORT"] || 0 + + begin + @header_part << request_line << CRLF + setup_header + @header_part << CRLF + @header_part.rewind + rescue Exception => ex + raise CGIError, "invalid CGI environment" + end + end + + def request_line + meth = @env["REQUEST_METHOD"] || "GET" + unless url = @env["REQUEST_URI"] + url = (@env["SCRIPT_NAME"] || File.expand_path($0)).dup + url << @env["PATH_INFO"].to_s + url = WEBrick::HTTPUtils.escape_path(url) + if query_string = @env["QUERY_STRING"] + unless query_string.empty? + url << "?" << query_string + end + end + end + # we cannot get real HTTP version of client ;) + httpv = @config[:HTTPVersion] + return "#{meth} #{url} HTTP/#{httpv}" + end + + def setup_header + add_header("CONTENT_TYPE", "Content-Type") + add_header("CONTENT_LENGTH", "Content-length") + @env.each_key{|name| + if /^HTTP_(.*)/ =~ name + add_header(name, $1.gsub(/_/, "-")) + end + } + end + + def add_header(envname, hdrname) + if value = @env[envname] + unless value.empty? + @header_part << hdrname << ": " << value << CRLF + end + end + end + + def input + @header_part.eof? ? @body_part : @header_part + end + + public + + def peeraddr + [nil, @remote_port, @remote_host, @remote_addr] + end + + def addr + [nil, @server_port, @server_name, @server_addr] + end + + def gets(eol=LF) + input.gets(eol) + end + + def read(size=nil) + input.read(size) + end + + def each + input.each{|line| yield(line) } + end + + def <<(data) + @out_port << data + end + + def cert + return nil unless defined?(OpenSSL) + if pem = @env["SSL_SERVER_CERT"] + OpenSSL::X509::Certificate.new(pem) unless pem.empty? + end + end + + def peer_cert + return nil unless defined?(OpenSSL) + if pem = @env["SSL_CLIENT_CERT"] + OpenSSL::X509::Certificate.new(pem) unless pem.empty? + end + end + + def peer_cert_chain + return nil unless defined?(OpenSSL) + if @env["SSL_CLIENT_CERT_CHAIN_0"] + keys = @env.keys + certs = keys.sort.collect{|k| + if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k + if pem = @env[k] + OpenSSL::X509::Certificate.new(pem) unless pem.empty? + end + end + } + certs.compact + end + end + + def cipher + return nil unless defined?(OpenSSL) + if cipher = @env["SSL_CIPHER"] + ret = [ cipher ] + ret << @env["SSL_PROTOCOL"] + ret << @env["SSL_CIPHER_USEKEYSIZE"] + ret << @env["SSL_CIPHER_ALGKEYSIZE"] + ret + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/compat.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/compat.rb new file mode 100644 index 00000000..ad7760b6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/compat.rb @@ -0,0 +1,15 @@ +# +# compat.rb -- cross platform compatibility +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $ + +module Errno + class EPROTO < SystemCallError; end + class ECONNRESET < SystemCallError; end + class ECONNABORTED < SystemCallError; end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/config.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/config.rb new file mode 100644 index 00000000..5897b977 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/config.rb @@ -0,0 +1,97 @@ +# +# config.rb -- Default configurations. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $ + +require 'webrick/version' +require 'webrick/httpversion' +require 'webrick/httputils' +require 'webrick/utils' +require 'webrick/log' + +module WEBrick + module Config + LIBDIR = File::dirname(__FILE__) + + # for GenericServer + General = { + :ServerName => Utils::getservername, + :BindAddress => nil, # "0.0.0.0" or "::" or nil + :Port => nil, # users MUST specifiy this!! + :MaxClients => 100, # maximum number of the concurrent connections + :ServerType => nil, # default: WEBrick::SimpleServer + :Logger => nil, # default: WEBrick::Log.new + :ServerSoftware => "WEBrick/#{WEBrick::VERSION} " + + "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})", + :TempDir => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp', + :DoNotListen => false, + :StartCallback => nil, + :StopCallback => nil, + :AcceptCallback => nil, + } + + # for HTTPServer, HTTPRequest, HTTPResponse ... + HTTP = General.dup.update( + :Port => 80, + :RequestTimeout => 30, + :HTTPVersion => HTTPVersion.new("1.1"), + :AccessLog => nil, + :MimeTypes => HTTPUtils::DefaultMimeTypes, + :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"], + :DocumentRoot => nil, + :DocumentRootOptions => { :FancyIndexing => true }, + :RequestHandler => nil, + :RequestCallback => nil, # alias of :RequestHandler + :ServerAlias => nil, + + # for HTTPProxyServer + :ProxyAuthProc => nil, + :ProxyContentHandler => nil, + :ProxyVia => true, + :ProxyTimeout => true, + :ProxyURI => nil, + + :CGIInterpreter => nil, + :CGIPathEnv => nil, + + # workaround: if Request-URIs contain 8bit chars, + # they should be escaped before calling of URI::parse(). + :Escape8bitURI => false + ) + + FileHandler = { + :NondisclosureName => [".ht*", "*~"], + :FancyIndexing => false, + :HandlerTable => {}, + :HandlerCallback => nil, + :DirectoryCallback => nil, + :FileCallback => nil, + :UserDir => nil, # e.g. "public_html" + :AcceptableLanguages => [] # ["en", "ja", ... ] + } + + BasicAuth = { + :AutoReloadUserDB => true, + } + + DigestAuth = { + :Algorithm => 'MD5-sess', # or 'MD5' + :Domain => nil, # an array includes domain names. + :Qop => [ 'auth' ], # 'auth' or 'auth-int' or both. + :UseOpaque => true, + :UseNextNonce => false, + :CheckNc => false, + :UseAuthenticationInfoHeader => true, + :AutoReloadUserDB => true, + :NonceExpirePeriod => 30*60, + :NonceExpireDelta => 60, + :InternetExplorerHack => true, + :OperaHack => true, + } + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/cookie.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/cookie.rb new file mode 100644 index 00000000..814e6645 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/cookie.rb @@ -0,0 +1,110 @@ +# +# cookie.rb -- Cookie class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $ + +require 'time' +require 'webrick/httputils' + +module WEBrick + class Cookie + + attr_reader :name + attr_accessor :value, :version + attr_accessor :domain, :path, :secure + attr_accessor :comment, :max_age + #attr_accessor :comment_url, :discard, :port + + def initialize(name, value) + @name = name + @value = value + @version = 0 # Netscape Cookie + + @domain = @path = @secure = @comment = @max_age = + @expires = @comment_url = @discard = @port = nil + end + + def expires=(t) + @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s) + end + + def expires + @expires && Time.parse(@expires) + end + + def to_s + ret = "" + ret << @name << "=" << @value + ret << "; " << "Version=" << @version.to_s if @version > 0 + ret << "; " << "Domain=" << @domain if @domain + ret << "; " << "Expires=" << @expires if @expires + ret << "; " << "Max-Age=" << @max_age.to_s if @max_age + ret << "; " << "Comment=" << @comment if @comment + ret << "; " << "Path=" << @path if @path + ret << "; " << "Secure" if @secure + ret + end + + # Cookie::parse() + # It parses Cookie field sent from the user agent. + def self.parse(str) + if str + ret = [] + cookie = nil + ver = 0 + str.split(/[;,]\s+/).each{|x| + key, val = x.split(/=/,2) + val = val ? HTTPUtils::dequote(val) : "" + case key + when "$Version"; ver = val.to_i + when "$Path"; cookie.path = val + when "$Domain"; cookie.domain = val + when "$Port"; cookie.port = val + else + ret << cookie if cookie + cookie = self.new(key, val) + cookie.version = ver + end + } + ret << cookie if cookie + ret + end + end + + def self.parse_set_cookie(str) + cookie_elem = str.split(/;/) + first_elem = cookie_elem.shift + first_elem.strip! + key, value = first_elem.split(/=/, 2) + cookie = new(key, HTTPUtils.dequote(value)) + cookie_elem.each{|pair| + pair.strip! + key, value = pair.split(/=/, 2) + if value + value = HTTPUtils.dequote(value.strip) + end + case key.downcase + when "domain" then cookie.domain = value + when "path" then cookie.path = value + when "expires" then cookie.expires = value + when "max-age" then cookie.max_age = Integer(value) + when "comment" then cookie.comment = value + when "version" then cookie.version = Integer(value) + when "secure" then cookie.secure = true + end + } + return cookie + end + + def self.parse_set_cookies(str) + return str.split(/,(?=[^;,]*=)|,$/).collect{|c| + parse_set_cookie(c) + } + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/htmlutils.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/htmlutils.rb new file mode 100644 index 00000000..cf8d542c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/htmlutils.rb @@ -0,0 +1,25 @@ +# +# htmlutils.rb -- HTMLUtils Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htmlutils.rb,v 1.7 2002/09/21 12:23:35 gotoyuzo Exp $ + +module WEBrick + module HTMLUtils + + def escape(string) + str = string ? string.dup : "" + str.gsub!(/&/n, '&') + str.gsub!(/\"/n, '"') + str.gsub!(/>/n, '>') + str.gsub!(/ generate_next_nonce(req), + 'rspauth' => digest_res + } + if @use_opaque + opaque_struct.time = req.request_time + opaque_struct.nonce = auth_info['nextnonce'] + opaque_struct.nc = "%08x" % (auth_req['nc'].hex + 1) + end + if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int" + ['qop','cnonce','nc'].each{|key| + auth_info[key] = auth_req[key] + } + end + res[@resp_info_field] = auth_info.keys.map{|key| + if key == 'nc' + key + '=' + auth_info[key] + else + key + "=" + HTTPUtils::quote(auth_info[key]) + end + }.join(', ') + end + info('%s: authentication scceeded.', auth_req['username']) + req.user = auth_req['username'] + return true + end + + def split_param_value(string) + ret = {} + while string.size != 0 + case string + when /^\s*([\w\-\.\*\%\!]+)=\s*\"((\\.|[^\"])*)\"\s*,?/ + key = $1 + matched = $2 + string = $' + ret[key] = matched.gsub(/\\(.)/, "\\1") + when /^\s*([\w\-\.\*\%\!]+)=\s*([^,\"]*),?/ + key = $1 + matched = $2 + string = $' + ret[key] = matched.clone + when /^s*^,/ + string = $' + else + break + end + end + ret + end + + def generate_next_nonce(req) + now = "%012d" % req.request_time.to_i + pk = hexdigest(now, @instance_key)[0,32] + nonce = [now + ":" + pk].pack("m*").chop # it has 60 length of chars. + nonce + end + + def check_nonce(req, auth_req) + username = auth_req['username'] + nonce = auth_req['nonce'] + + pub_time, pk = nonce.unpack("m*")[0].split(":", 2) + if (!pub_time || !pk) + error("%s: empty nonce is given", username) + return false + elsif (hexdigest(pub_time, @instance_key)[0,32] != pk) + error("%s: invalid private-key: %s for %s", + username, hexdigest(pub_time, @instance_key)[0,32], pk) + return false + end + + diff_time = req.request_time.to_i - pub_time.to_i + if (diff_time < 0) + error("%s: difference of time-stamp is negative.", username) + return false + elsif diff_time > @nonce_expire_period + error("%s: nonce is expired.", username) + return false + end + + return true + end + + def generate_opaque(req) + @mutex.synchronize{ + now = req.request_time + if now - @last_nonce_expire > @nonce_expire_delta + @opaques.delete_if{|key,val| + (now - val.time) > @nonce_expire_period + } + @last_nonce_expire = now + end + begin + opaque = Utils::random_string(16) + end while @opaques[opaque] + @opaques[opaque] = OpaqueInfo.new(now, nil, '00000001') + opaque + } + end + + def check_opaque(opaque_struct, req, auth_req) + if (@use_next_nonce && auth_req['nonce'] != opaque_struct.nonce) + error('%s: nonce unmatched. "%s" for "%s"', + auth_req['username'], auth_req['nonce'], opaque_struct.nonce) + return false + elsif !check_nonce(req, auth_req) + return false + end + if (@check_nc && auth_req['nc'] != opaque_struct.nc) + error('%s: nc unmatched."%s" for "%s"', + auth_req['username'], auth_req['nc'], opaque_struct.nc) + return false + end + true + end + + def check_uri(req, auth_req) + uri = auth_req['uri'] + if uri != req.request_uri.to_s && uri != req.unparsed_uri && + (@internet_explorer_hack && uri != req.path) + error('%s: uri unmatch. "%s" for "%s"', auth_req['username'], + auth_req['uri'], req.request_uri.to_s) + return false + end + true + end + + def hexdigest(*args) + @h.hexdigest(args.join(":")) + end + end + + class ProxyDigestAuth < DigestAuth + include ProxyAuthenticator + + def check_uri(req, auth_req) + return true + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htdigest.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htdigest.rb new file mode 100644 index 00000000..3949756f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htdigest.rb @@ -0,0 +1,91 @@ +# +# httpauth/htdigest.rb -- Apache compatible htdigest file +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $ + +require 'webrick/httpauth/userdb' +require 'webrick/httpauth/digestauth' +require 'tempfile' + +module WEBrick + module HTTPAuth + class Htdigest + include UserDB + + def initialize(path) + @path = path + @mtime = Time.at(0) + @digest = Hash.new + @mutex = Mutex::new + @auth_type = DigestAuth + open(@path,"a").close unless File::exist?(@path) + reload + end + + def reload + mtime = File::mtime(@path) + if mtime > @mtime + @digest.clear + open(@path){|io| + while line = io.gets + line.chomp! + user, realm, pass = line.split(/:/, 3) + unless @digest[realm] + @digest[realm] = Hash.new + end + @digest[realm][user] = pass + end + } + @mtime = mtime + end + end + + def flush(output=nil) + output ||= @path + tmp = Tempfile.new("htpasswd", File::dirname(output)) + begin + each{|item| tmp.puts(item.join(":")) } + tmp.close + File::rename(tmp.path, output) + rescue + tmp.close(true) + end + end + + def get_passwd(realm, user, reload_db) + reload() if reload_db + if hash = @digest[realm] + hash[user] + end + end + + def set_passwd(realm, user, pass) + @mutex.synchronize{ + unless @digest[realm] + @digest[realm] = Hash.new + end + @digest[realm][user] = make_passwd(realm, user, pass) + } + end + + def delete_passwd(realm, user) + if hash = @digest[realm] + hash.delete(user) + end + end + + def each + @digest.keys.sort.each{|realm| + hash = @digest[realm] + hash.keys.sort.each{|user| + yield([user, realm, hash[user]]) + } + } + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htgroup.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htgroup.rb new file mode 100644 index 00000000..c9270c61 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htgroup.rb @@ -0,0 +1,61 @@ +# +# httpauth/htgroup.rb -- Apache compatible htgroup file +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htgroup.rb,v 1.1 2003/02/16 22:22:56 gotoyuzo Exp $ + +require 'tempfile' + +module WEBrick + module HTTPAuth + class Htgroup + def initialize(path) + @path = path + @mtime = Time.at(0) + @group = Hash.new + open(@path,"a").close unless File::exist?(@path) + reload + end + + def reload + if (mtime = File::mtime(@path)) > @mtime + @group.clear + open(@path){|io| + while line = io.gets + line.chomp! + group, members = line.split(/:\s*/) + @group[group] = members.split(/\s+/) + end + } + @mtime = mtime + end + end + + def flush(output=nil) + output ||= @path + tmp = Tempfile.new("htgroup", File::dirname(output)) + begin + @group.keys.sort.each{|group| + tmp.puts(format("%s: %s", group, self.members(group).join(" "))) + } + tmp.close + File::rename(tmp.path, output) + rescue + tmp.close(true) + end + end + + def members(group) + reload + @group[group] || [] + end + + def add(group, members) + @group[group] = members(group) | members + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htpasswd.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htpasswd.rb new file mode 100644 index 00000000..40f9297b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/htpasswd.rb @@ -0,0 +1,83 @@ +# +# httpauth/htpasswd -- Apache compatible htpasswd file +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $ + +require 'webrick/httpauth/userdb' +require 'webrick/httpauth/basicauth' +require 'tempfile' + +module WEBrick + module HTTPAuth + class Htpasswd + include UserDB + + def initialize(path) + @path = path + @mtime = Time.at(0) + @passwd = Hash.new + @auth_type = BasicAuth + open(@path,"a").close unless File::exist?(@path) + reload + end + + def reload + mtime = File::mtime(@path) + if mtime > @mtime + @passwd.clear + open(@path){|io| + while line = io.gets + line.chomp! + case line + when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z! + user, pass = line.split(":") + when /:\$/, /:\{SHA\}/ + raise NotImplementedError, + 'MD5, SHA1 .htpasswd file not supported' + else + raise StandardError, 'bad .htpasswd file' + end + @passwd[user] = pass + end + } + @mtime = mtime + end + end + + def flush(output=nil) + output ||= @path + tmp = Tempfile.new("htpasswd", File::dirname(output)) + begin + each{|item| tmp.puts(item.join(":")) } + tmp.close + File::rename(tmp.path, output) + rescue + tmp.close(true) + end + end + + def get_passwd(realm, user, reload_db) + reload() if reload_db + @passwd[user] + end + + def set_passwd(realm, user, pass) + @passwd[user] = make_passwd(realm, user, pass) + end + + def delete_passwd(realm, user) + @passwd.delete(user) + end + + def each + @passwd.keys.sort.each{|user| + yield([user, @passwd[user]]) + } + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/userdb.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/userdb.rb new file mode 100644 index 00000000..33e01405 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpauth/userdb.rb @@ -0,0 +1,29 @@ +# +# httpauth/userdb.rb -- UserDB mix-in module. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: userdb.rb,v 1.2 2003/02/20 07:15:48 gotoyuzo Exp $ + +module WEBrick + module HTTPAuth + module UserDB + attr_accessor :auth_type # BasicAuth or DigestAuth + + def make_passwd(realm, user, pass) + @auth_type::make_passwd(realm, user, pass) + end + + def set_passwd(realm, user, pass) + self[user] = pass + end + + def get_passwd(realm, user, reload_db=false) + # reload_db is dummy + make_passwd(realm, user, self[user]) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpproxy.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpproxy.rb new file mode 100644 index 00000000..14e34997 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpproxy.rb @@ -0,0 +1,254 @@ +# +# httpproxy.rb -- HTTPProxy Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 GOTO Kentaro +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $ +# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $ + +require "webrick/httpserver" +require "net/http" + +Net::HTTP::version_1_2 if RUBY_VERSION < "1.7" + +module WEBrick + NullReader = Object.new + class << NullReader + def read(*args) + nil + end + alias gets read + end + + class HTTPProxyServer < HTTPServer + def initialize(config) + super + c = @config + @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}" + end + + def service(req, res) + if req.request_method == "CONNECT" + proxy_connect(req, res) + elsif req.unparsed_uri =~ %r!^http://! + proxy_service(req, res) + else + super(req, res) + end + end + + def proxy_auth(req, res) + if proc = @config[:ProxyAuthProc] + proc.call(req, res) + end + req.header.delete("proxy-authorization") + end + + # Some header fields shuold not be transfered. + HopByHop = %w( connection keep-alive proxy-authenticate upgrade + proxy-authorization te trailers transfer-encoding ) + ShouldNotTransfer = %w( set-cookie proxy-connection ) + def split_field(f) f ? f.split(/,\s+/).collect{|i| i.downcase } : [] end + + def choose_header(src, dst) + connections = split_field(src['connection']) + src.each{|key, value| + key = key.downcase + if HopByHop.member?(key) || # RFC2616: 13.5.1 + connections.member?(key) || # RFC2616: 14.10 + ShouldNotTransfer.member?(key) # pragmatics + @logger.debug("choose_header: `#{key}: #{value}'") + next + end + dst[key] = value + } + end + + # Net::HTTP is stupid about the multiple header fields. + # Here is workaround: + def set_cookie(src, dst) + if str = src['set-cookie'] + cookies = [] + str.split(/,\s*/).each{|token| + if /^[^=]+;/o =~ token + cookies[-1] << ", " << token + elsif /=/o =~ token + cookies << token + else + cookies[-1] << ", " << token + end + } + dst.cookies.replace(cookies) + end + end + + def set_via(h) + if @config[:ProxyVia] + if h['via'] + h['via'] << ", " << @via + else + h['via'] = @via + end + end + end + + def proxy_uri(req, res) + @config[:ProxyURI] + end + + def proxy_service(req, res) + # Proxy Authentication + proxy_auth(req, res) + + # Create Request-URI to send to the origin server + uri = req.request_uri + path = uri.path.dup + path << "?" << uri.query if uri.query + + # Choose header fields to transfer + header = Hash.new + choose_header(req, header) + set_via(header) + + # select upstream proxy server + if proxy = proxy_uri(req, res) + proxy_host = proxy.host + proxy_port = proxy.port + if proxy.userinfo + credentials = "Basic " + [proxy.userinfo].pack("m*") + credentials.chomp! + header['proxy-authorization'] = credentials + end + end + + response = nil + begin + http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port) + http.start{ + if @config[:ProxyTimeout] + ################################## these issues are + http.open_timeout = 30 # secs # necessary (maybe bacause + http.read_timeout = 60 # secs # Ruby's bug, but why?) + ################################## + end + case req.request_method + when "GET" then response = http.get(path, header) + when "POST" then response = http.post(path, req.body || "", header) + when "HEAD" then response = http.head(path, header) + else + raise HTTPStatus::MethodNotAllowed, + "unsupported method `#{req.request_method}'." + end + } + rescue => err + logger.debug("#{err.class}: #{err.message}") + raise HTTPStatus::ServiceUnavailable, err.message + end + + # Persistent connction requirements are mysterious for me. + # So I will close the connection in every response. + res['proxy-connection'] = "close" + res['connection'] = "close" + + # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPProxy + res.status = response.code.to_i + choose_header(response, res) + set_cookie(response, res) + set_via(res) + res.body = response.body + + # Process contents + if handler = @config[:ProxyContentHandler] + handler.call(req, res) + end + end + + def proxy_connect(req, res) + # Proxy Authentication + proxy_auth(req, res) + + ua = Thread.current[:WEBrickSocket] # User-Agent + raise HTTPStatus::InternalServerError, + "[BUG] cannot get socket" unless ua + + host, port = req.unparsed_uri.split(":", 2) + # Proxy authentication for upstream proxy server + if proxy = proxy_uri(req, res) + proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0" + if proxy.userinfo + credentials = "Basic " + [proxy.userinfo].pack("m*") + credentials.chomp! + end + host, port = proxy.host, proxy.port + end + + begin + @logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.") + os = TCPSocket.new(host, port) # origin server + + if proxy + @logger.debug("CONNECT: sending a Request-Line") + os << proxy_request_line << CRLF + @logger.debug("CONNECT: > #{proxy_request_line}") + if credentials + @logger.debug("CONNECT: sending a credentials") + os << "Proxy-Authorization: " << credentials << CRLF + end + os << CRLF + proxy_status_line = os.gets(LF) + @logger.debug("CONNECT: read a Status-Line form the upstream server") + @logger.debug("CONNECT: < #{proxy_status_line}") + if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line + while line = os.gets(LF) + break if /\A(#{CRLF}|#{LF})\z/om =~ line + end + else + raise HTTPStatus::BadGateway + end + end + @logger.debug("CONNECT #{host}:#{port}: succeeded") + res.status = HTTPStatus::RC_OK + rescue => ex + @logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'") + res.set_error(ex) + raise HTTPStatus::EOFError + ensure + if handler = @config[:ProxyContentHandler] + handler.call(req, res) + end + res.send_response(ua) + access_log(@config, req, res) + + # Should clear request-line not to send the sesponse twice. + # see: HTTPServer#run + req.parse(NullReader) rescue nil + end + + begin + while fds = IO::select([ua, os]) + if fds[0].member?(ua) + buf = ua.sysread(1024); + @logger.debug("CONNECT: #{buf.size} byte from User-Agent") + os.syswrite(buf) + elsif fds[0].member?(os) + buf = os.sysread(1024); + @logger.debug("CONNECT: #{buf.size} byte from #{host}:#{port}") + ua.syswrite(buf) + end + end + rescue => ex + os.close + @logger.debug("CONNECT #{host}:#{port}: closed") + end + + raise HTTPStatus::EOFError + end + + def do_OPTIONS(req, res) + res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httprequest.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httprequest.rb new file mode 100644 index 00000000..1d32293a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httprequest.rb @@ -0,0 +1,365 @@ +# +# httprequest.rb -- HTTPRequest Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $ + +require 'timeout' +require 'uri' + +require 'webrick/httpversion' +require 'webrick/httpstatus' +require 'webrick/httputils' +require 'webrick/cookie' + +module WEBrick + + class HTTPRequest + BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ] + BUFSIZE = 1024*4 + + # Request line + attr_reader :request_line + attr_reader :request_method, :unparsed_uri, :http_version + + # Request-URI + attr_reader :request_uri, :host, :port, :path + attr_accessor :script_name, :path_info, :query_string + + # Header and entity body + attr_reader :raw_header, :header, :cookies + attr_reader :accept, :accept_charset + attr_reader :accept_encoding, :accept_language + + # Misc + attr_accessor :user + attr_reader :addr, :peeraddr + attr_reader :attributes + attr_reader :keep_alive + attr_reader :request_time + + def initialize(config) + @config = config + @logger = config[:Logger] + + @request_line = @request_method = + @unparsed_uri = @http_version = nil + + @request_uri = @host = @port = @path = nil + @script_name = @path_info = nil + @query_string = nil + @query = nil + @form_data = nil + + @raw_header = Array.new + @header = nil + @cookies = [] + @accept = [] + @accept_charset = [] + @accept_encoding = [] + @accept_language = [] + @body = "" + + @addr = @peeraddr = nil + @attributes = {} + @user = nil + @keep_alive = false + @request_time = nil + + @remaining_size = nil + @socket = nil + end + + def parse(socket=nil) + @socket = socket + begin + @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : [] + @addr = socket.respond_to?(:addr) ? socket.addr : [] + rescue Errno::ENOTCONN + raise HTTPStatus::EOFError + end + + read_request_line(socket) + if @http_version.major > 0 + read_header(socket) + @header['cookie'].each{|cookie| + @cookies += Cookie::parse(cookie) + } + @accept = HTTPUtils.parse_qvalues(self['accept']) + @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset']) + @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding']) + @accept_language = HTTPUtils.parse_qvalues(self['accept-language']) + end + return if @request_method == "CONNECT" + return if @unparsed_uri == "*" + + begin + @request_uri = parse_uri(@unparsed_uri) + @path = HTTPUtils::unescape(@request_uri.path) + @path = HTTPUtils::normalize_path(@path) + @host = @request_uri.host + @port = @request_uri.port + @query_string = @request_uri.query + @script_name = "" + @path_info = @path.dup + rescue + raise HTTPStatus::BadRequest, "bad URI `#{@unparsed_uri}'." + end + + if /close/io =~ self["connection"] + @keep_alive = false + elsif /keep-alive/io =~ self["connection"] + @keep_alive = true + elsif @http_version < "1.1" + @keep_alive = false + else + @keep_alive = true + end + end + + def body(&block) + block ||= Proc.new{|chunk| @body << chunk } + read_body(@socket, block) + @body.empty? ? nil : @body + end + + def query + unless @query + parse_query() + end + @query + end + + def content_length + return Integer(self['content-length']) + end + + def content_type + return self['content-type'] + end + + def [](header_name) + if @header + value = @header[header_name.downcase] + value.empty? ? nil : value.join(", ") + end + end + + def each + @header.each{|k, v| + value = @header[k] + yield(k, value.empty? ? nil : value.join(", ")) + } + end + + def keep_alive? + @keep_alive + end + + def to_s + ret = @request_line.dup + @raw_header.each{|line| ret << line } + ret << CRLF + ret << body if body + ret + end + + def fixup() + begin + body{|chunk| } # read remaining body + rescue HTTPStatus::Error => ex + @logger.error("HTTPRequest#fixup: #{ex.class} occured.") + @keep_alive = false + rescue => ex + @logger.error(ex) + @keep_alive = false + end + end + + def meta_vars + # This method provides the metavariables defined by the revision 3 + # of ``The WWW Common Gateway Interface Version 1.1''. + # (http://Web.Golux.Com/coar/cgi/) + + meta = Hash.new + + cl = self["Content-Length"] + ct = self["Content-Type"] + meta["CONTENT_LENGTH"] = cl if cl.to_i > 0 + meta["CONTENT_TYPE"] = ct.dup if ct + meta["GATEWAY_INTERFACE"] = "CGI/1.1" + meta["PATH_INFO"] = @path_info ? @path_info.dup : "" + #meta["PATH_TRANSLATED"] = nil # no plan to be provided + meta["QUERY_STRING"] = @query_string ? @query_string.dup : "" + meta["REMOTE_ADDR"] = @peeraddr[3] + meta["REMOTE_HOST"] = @peeraddr[2] + #meta["REMOTE_IDENT"] = nil # no plan to be provided + meta["REMOTE_USER"] = @user + meta["REQUEST_METHOD"] = @request_method.dup + meta["REQUEST_URI"] = @request_uri.to_s + meta["SCRIPT_NAME"] = @script_name.dup + meta["SERVER_NAME"] = @host + meta["SERVER_PORT"] = @port.to_s + meta["SERVER_PROTOCOL"] = "HTTP/" + @config[:HTTPVersion].to_s + meta["SERVER_SOFTWARE"] = @config[:ServerSoftware].dup + + self.each{|key, val| + next if /^content-type$/i =~ key + next if /^content-length$/i =~ key + name = "HTTP_" + key + name.gsub!(/-/o, "_") + name.upcase! + meta[name] = val + } + + meta + end + + private + + def read_request_line(socket) + @request_line = read_line(socket) if socket + @request_time = Time.now + raise HTTPStatus::EOFError unless @request_line + if /^(\S+)\s+(\S+)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line + @request_method = $1 + @unparsed_uri = $2 + @http_version = HTTPVersion.new($3 ? $3 : "0.9") + else + rl = @request_line.sub(/\x0d?\x0a\z/o, '') + raise HTTPStatus::BadRequest, "bad Request-Line `#{rl}'." + end + end + + def read_header(socket) + if socket + while line = read_line(socket) + break if /\A(#{CRLF}|#{LF})\z/om =~ line + @raw_header << line + end + end + begin + @header = HTTPUtils::parse_header(@raw_header) + rescue => ex + raise HTTPStatus::BadRequest, ex.message + end + end + + def parse_uri(str, scheme="http") + if @config[:Escape8bitURI] + str = HTTPUtils::escape8bit(str) + end + uri = URI::parse(str) + return uri if uri.absolute? + if self["host"] + pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/n + host, port = *self['host'].scan(pattern)[0] + elsif @addr.size > 0 + host, port = @addr[2], @addr[1] + else + host, port = @config[:ServerName], @config[:Port] + end + uri.scheme = scheme + uri.host = host + uri.port = port ? port.to_i : nil + return URI::parse(uri.to_s) + end + + def read_body(socket, block) + return unless socket + if tc = self['transfer-encoding'] + case tc + when /chunked/io then read_chunked(socket, block) + else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}." + end + elsif self['content-length'] || @remaining_size + @remaining_size ||= self['content-length'].to_i + while @remaining_size > 0 + sz = BUFSIZE < @remaining_size ? BUFSIZE : @remaining_size + break unless buf = read_data(socket, sz) + @remaining_size -= buf.size + block.call(buf) + end + if @remaining_size > 0 && @socket.eof? + raise HTTPStatus::BadRequest, "invalid body size." + end + elsif BODY_CONTAINABLE_METHODS.member?(@request_method) + raise HTTPStatus::LengthRequired + end + return @body + end + + def read_chunk_size(socket) + line = read_line(socket) + if /^([0-9a-fA-F]+)(?:;(\S+))?/ =~ line + chunk_size = $1.hex + chunk_ext = $2 + [ chunk_size, chunk_ext ] + else + raise HTTPStatus::BadRequest, "bad chunk `#{line}'." + end + end + + def read_chunked(socket, block) + chunk_size, = read_chunk_size(socket) + while chunk_size > 0 + data = "" + while data.size < chunk_size + tmp = read_data(socket, chunk_size-data.size) # read chunk-data + break unless tmp + data << tmp + end + if data.nil? || data.size != chunk_size + raise BadRequest, "bad chunk data size." + end + read_line(socket) # skip CRLF + block.call(data) + chunk_size, = read_chunk_size(socket) + end + read_header(socket) # trailer + CRLF + @header.delete("transfer-encoding") + @remaining_size = 0 + end + + def _read_data(io, method, arg) + begin + timeout(@config[:RequestTimeout]){ + return io.__send__(method, arg) + } + rescue Errno::ECONNRESET + return nil + rescue TimeoutError + raise HTTPStatus::RequestTimeout + end + end + + def read_line(io) + _read_data(io, :gets, LF) + end + + def read_data(io, size) + _read_data(io, :read, size) + end + + def parse_query() + begin + if @request_method == "GET" || @request_method == "HEAD" + @query = HTTPUtils::parse_query(@query_string) + elsif self['content-type'] =~ /^application\/x-www-form-urlencoded/ + @query = HTTPUtils::parse_query(body) + elsif self['content-type'] =~ /^multipart\/form-data; boundary=(.+)/ + boundary = HTTPUtils::dequote($1) + @query = HTTPUtils::parse_form_data(body, boundary) + else + @query = Hash.new + end + rescue => ex + raise HTTPStatus::BadRequest, ex.message + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpresponse.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpresponse.rb new file mode 100644 index 00000000..d0f232d1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpresponse.rb @@ -0,0 +1,327 @@ +# +# httpresponse.rb -- HTTPResponse Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $ + +require 'time' +require 'webrick/httpversion' +require 'webrick/htmlutils' +require 'webrick/httputils' +require 'webrick/httpstatus' + +module WEBrick + class HTTPResponse + BUFSIZE = 1024*4 + + attr_reader :http_version, :status, :header + attr_reader :cookies + attr_accessor :reason_phrase + attr_accessor :body + + attr_accessor :request_method, :request_uri, :request_http_version + attr_accessor :filename + attr_accessor :keep_alive + attr_reader :config, :sent_size + + def initialize(config) + @config = config + @logger = config[:Logger] + @header = Hash.new + @status = HTTPStatus::RC_OK + @reason_phrase = nil + @http_version = HTTPVersion::convert(@config[:HTTPVersion]) + @body = '' + @keep_alive = true + @cookies = [] + @request_method = nil + @request_uri = nil + @request_http_version = @http_version # temporary + @chunked = false + @filename = nil + @sent_size = 0 + end + + def status_line + "HTTP/#@http_version #@status #@reason_phrase #{CRLF}" + end + + def status=(status) + @status = status + @reason_phrase = HTTPStatus::reason_phrase(status) + end + + def [](field) + @header[field.downcase] + end + + def []=(field, value) + @header[field.downcase] = value.to_s + end + + def content_length + if len = self['content-length'] + return Integer(len) + end + end + + def content_length=(len) + self['content-length'] = len.to_s + end + + def content_type + self['content-type'] + end + + def content_type=(type) + self['content-type'] = type + end + + def each + @header.each{|k, v| yield(k, v) } + end + + def chunked? + @chunked + end + + def chunked=(val) + @chunked = val ? true : false + end + + def keep_alive? + @keep_alive + end + + def send_response(socket) + begin + setup_header() + send_header(socket) + send_body(socket) + rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex + @logger.debug(ex) + @keep_alive = false + rescue Exception => ex + @logger.error(ex) + @keep_alive = false + end + end + + def setup_header() + @reason_phrase ||= HTTPStatus::reason_phrase(@status) + @header['server'] ||= @config[:ServerSoftware] + @header['date'] ||= Time.now.httpdate + + # HTTP/0.9 features + if @request_http_version < "1.0" + @http_version = HTTPVersion.new("0.9") + @keep_alive = false + end + + # HTTP/1.0 features + if @request_http_version < "1.1" + if chunked? + @chunked = false + ver = @request_http_version.to_s + msg = "chunked is set for an HTTP/#{ver} request. (ignored)" + @logger.warn(msg) + end + end + + # Determin the message length (RFC2616 -- 4.4 Message Length) + if @status == 304 || @status == 204 || HTTPStatus::info?(@status) + @header.delete('content-length') + @body = "" + elsif chunked? + @header["transfer-encoding"] = "chunked" + @header.delete('content-length') + elsif %r{^multipart/byteranges} =~ @header['content-type'] + @header.delete('content-length') + elsif @header['content-length'].nil? + unless @body.is_a?(IO) + @header['content-length'] = @body ? @body.size : 0 + end + end + + # Keep-Alive connection. + if @header['connection'] == "close" + @keep_alive = false + elsif keep_alive? + if chunked? || @header['content-length'] + @header['connection'] = "Keep-Alive" + end + else + @header['connection'] = "close" + end + + # Location is a single absoluteURI. + if location = @header['location'] + if @request_uri + @header['location'] = @request_uri.merge(location) + end + end + end + + def send_header(socket) + if @http_version.major > 0 + data = status_line() + @header.each{|key, value| + tmp = key.gsub(/\bwww|^te$|\b\w/){|s| s.upcase } + data << "#{tmp}: #{value}" << CRLF + } + @cookies.each{|cookie| + data << "Set-Cookie: " << cookie.to_s << CRLF + } + data << CRLF + _write_data(socket, data) + end + end + + def send_body(socket) + case @body + when IO then send_body_io(socket) + else send_body_string(socket) + end + end + + def to_s + ret = "" + send_response(ret) + ret + end + + def set_redirect(status, url) + @body = "#{url.to_s}.\n" + @header['location'] = url.to_s + raise status + end + + def set_error(ex, backtrace=false) + case ex + when HTTPStatus::Status + @keep_alive = false if HTTPStatus::error?(ex.code) + self.status = ex.code + else + @keep_alive = false + self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR + end + @header['content-type'] = "text/html" + + if respond_to?(:create_error_page) + create_error_page() + return + end + + if @request_uri + host, port = @request_uri.host, @request_uri.port + else + host, port = @config[:ServerName], @config[:Port] + end + + @body = '' + @body << <<-_end_of_html_ + + + #{HTMLUtils::escape(@reason_phrase)} + +

    #{HTMLUtils::escape(@reason_phrase)}

    + #{HTMLUtils::escape(ex.message)} +
    + _end_of_html_ + + if backtrace && $DEBUG + @body << "backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' " + @body << "#{HTMLUtils::escape(ex.message)}" + @body << "
    "
    +        ex.backtrace.each{|line| @body << "\t#{line}\n"}
    +        @body << "

    " + end + + @body << <<-_end_of_html_ +
    + #{HTMLUtils::escape(@config[:ServerSoftware])} at + #{host}:#{port} +
    + + + _end_of_html_ + end + + private + + def send_body_io(socket) + begin + if @request_method == "HEAD" + # do nothing + elsif chunked? + while buf = @body.read(BUFSIZE) + next if buf.empty? + data = "" + data << format("%x", buf.size) << CRLF + data << buf << CRLF + _write_data(socket, data) + @sent_size += buf.size + end + _write_data(socket, "0#{CRLF}#{CRLF}") + else + size = @header['content-length'].to_i + _send_file(socket, @body, 0, size) + @sent_size = size + end + ensure + @body.close + end + end + + def send_body_string(socket) + if @request_method == "HEAD" + # do nothing + elsif chunked? + remain = body ? @body.size : 0 + while buf = @body[@sent_size, BUFSIZE] + break if buf.empty? + data = "" + data << format("%x", buf.size) << CRLF + data << buf << CRLF + _write_data(socket, data) + @sent_size += buf.size + end + _write_data(socket, "0#{CRLF}#{CRLF}") + else + if @body && @body.size > 0 + _write_data(socket, @body) + @sent_size = @body.size + end + end + end + + def _send_file(output, input, offset, size) + while offset > 0 + sz = BUFSIZE < offset ? BUFSIZE : offset + buf = input.read(sz) + offset -= buf.size + end + + if size == 0 + while buf = input.read(BUFSIZE) + _write_data(output, buf) + end + else + while size > 0 + sz = BUFSIZE < size ? BUFSIZE : size + buf = input.read(sz) + _write_data(output, buf) + size -= buf.size + end + end + end + + def _write_data(socket, data) + socket << data + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/https.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/https.rb new file mode 100644 index 00000000..81b65ce8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/https.rb @@ -0,0 +1,63 @@ +# +# https.rb -- SSL/TLS enhancement for HTTPServer +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $ + +require 'webrick/ssl' + +module WEBrick + module Config + HTTP.update(SSL) + end + + class HTTPRequest + attr_reader :cipher, :server_cert, :client_cert + + alias orig_parse parse + + def parse(socket=nil) + if socket.respond_to?(:cert) + @server_cert = socket.cert || @config[:SSLCertificate] + @client_cert = socket.peer_cert + @client_cert_chain = socket.peer_cert_chain + @cipher = socket.cipher + end + orig_parse(socket) + end + + alias orig_parse_uri parse_uri + + def parse_uri(str, scheme="https") + if @server_cert + return orig_parse_uri(str, scheme) + end + return orig_parse_uri(str) + end + + alias orig_meta_vars meta_vars + + def meta_vars + meta = orig_meta_vars + if @server_cert + meta["HTTPS"] = "on" + meta["SSL_SERVER_CERT"] = @server_cert.to_pem + meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : "" + if @client_cert_chain + @client_cert_chain.each_with_index{|cert, i| + meta["SSL_CLIENT_CERT_CHAIN_#{i}"] = cert.to_pem + } + end + meta["SSL_CIPHER"] = @cipher[0] + meta["SSL_PROTOCOL"] = @cipher[1] + meta["SSL_CIPHER_USEKEYSIZE"] = @cipher[2].to_s + meta["SSL_CIPHER_ALGKEYSIZE"] = @cipher[3].to_s + end + meta + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpserver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpserver.rb new file mode 100644 index 00000000..9edb0018 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpserver.rb @@ -0,0 +1,210 @@ +# +# httpserver.rb -- HTTPServer Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $ + +require 'webrick/server' +require 'webrick/httputils' +require 'webrick/httpstatus' +require 'webrick/httprequest' +require 'webrick/httpresponse' +require 'webrick/httpservlet' +require 'webrick/accesslog' + +module WEBrick + class HTTPServerError < ServerError; end + + class HTTPServer < ::WEBrick::GenericServer + def initialize(config={}, default=Config::HTTP) + super + @http_version = HTTPVersion::convert(@config[:HTTPVersion]) + + @mount_tab = MountTable.new + if @config[:DocumentRoot] + mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot], + @config[:DocumentRootOptions]) + end + + unless @config[:AccessLog] + @config[:AccessLog] = [ + [ $stderr, AccessLog::COMMON_LOG_FORMAT ], + [ $stderr, AccessLog::REFERER_LOG_FORMAT ] + ] + end + + @virtual_hosts = Array.new + end + + def run(sock) + while true + res = HTTPResponse.new(@config) + req = HTTPRequest.new(@config) + server = self + begin + timeout = @config[:RequestTimeout] + while timeout > 0 + break if IO.select([sock], nil, nil, 0.5) + timeout = 0 if @status != :Running + timeout -= 0.5 + end + raise HTTPStatus::EOFError if timeout <= 0 || sock.eof? + req.parse(sock) + res.request_method = req.request_method + res.request_uri = req.request_uri + res.request_http_version = req.http_version + res.keep_alive = req.keep_alive? + server = lookup_server(req) || self + if callback = server[:RequestCallback] || server[:RequestHandler] + callback.call(req, res) + end + server.service(req, res) + rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex + res.set_error(ex) + rescue HTTPStatus::Error => ex + @logger.error(ex.message) + res.set_error(ex) + rescue HTTPStatus::Status => ex + res.status = ex.code + rescue StandardError => ex + @logger.error(ex) + res.set_error(ex, true) + ensure + if req.request_line + req.fixup() + res.send_response(sock) + server.access_log(@config, req, res) + end + end + break if @http_version < "1.1" + break unless req.keep_alive? + break unless res.keep_alive? + end + end + + def service(req, res) + if req.unparsed_uri == "*" + if req.request_method == "OPTIONS" + do_OPTIONS(req, res) + raise HTTPStatus::OK + end + raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found." + end + + servlet, options, script_name, path_info = search_servlet(req.path) + raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet + req.script_name = script_name + req.path_info = path_info + si = servlet.get_instance(self, *options) + @logger.debug(format("%s is invoked.", si.class.name)) + si.service(req, res) + end + + def do_OPTIONS(req, res) + res["allow"] = "GET,HEAD,POST,OPTIONS" + end + + def mount(dir, servlet, *options) + @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir)) + @mount_tab[dir] = [ servlet, options ] + end + + def mount_proc(dir, proc=nil, &block) + proc ||= block + raise HTTPServerError, "must pass a proc or block" unless proc + mount(dir, HTTPServlet::ProcHandler.new(proc)) + end + + def unmount(dir) + @logger.debug(sprintf("unmount %s.", dir)) + @mount_tab.delete(dir) + end + alias umount unmount + + def search_servlet(path) + script_name, path_info = @mount_tab.scan(path) + servlet, options = @mount_tab[script_name] + if servlet + [ servlet, options, script_name, path_info ] + end + end + + def virtual_host(server) + @virtual_hosts << server + @virtual_hosts = @virtual_hosts.sort_by{|s| + num = 0 + num -= 4 if s[:BindAddress] + num -= 2 if s[:Port] + num -= 1 if s[:ServerName] + num + } + end + + def lookup_server(req) + @virtual_hosts.find{|s| + (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) && + (s[:Port].nil? || req.port == s[:Port]) && + ((s[:ServerName].nil? || req.host == s[:ServerName]) || + (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host})) + } + end + + def access_log(config, req, res) + param = AccessLog::setup_params(config, req, res) + @config[:AccessLog].each{|logger, fmt| + logger << AccessLog::format(fmt+"\n", param) + } + end + + class MountTable + def initialize + @tab = Hash.new + compile + end + + def [](dir) + dir = normalize(dir) + @tab[dir] + end + + def []=(dir, val) + dir = normalize(dir) + @tab[dir] = val + compile + val + end + + def delete(dir) + dir = normalize(dir) + res = @tab.delete(dir) + compile + res + end + + def scan(path) + @scanner =~ path + [ $&, $' ] + end + + private + + def compile + k = @tab.keys + k.sort! + k.reverse! + k.collect!{|path| Regexp.escape(path) } + @scanner = Regexp.new("^(" + k.join("|") +")(?=/|$)") + end + + def normalize(dir) + ret = dir ? dir.dup : "" + ret.sub!(%r|/+$|, "") + ret + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet.rb new file mode 100644 index 00000000..ac7c022b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet.rb @@ -0,0 +1,22 @@ +# +# httpservlet.rb -- HTTPServlet Utility File +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $ + +require 'webrick/httpservlet/abstract' +require 'webrick/httpservlet/filehandler' +require 'webrick/httpservlet/cgihandler' +require 'webrick/httpservlet/erbhandler' +require 'webrick/httpservlet/prochandler' + +module WEBrick + module HTTPServlet + FileHandler.add_handler("cgi", CGIHandler) + FileHandler.add_handler("rhtml", ERBHandler) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/abstract.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/abstract.rb new file mode 100644 index 00000000..5375c462 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/abstract.rb @@ -0,0 +1,71 @@ +# +# httpservlet.rb -- HTTPServlet Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $ + +require 'thread' + +require 'webrick/htmlutils' +require 'webrick/httputils' +require 'webrick/httpstatus' + +module WEBrick + module HTTPServlet + class HTTPServletError < StandardError; end + + class AbstractServlet + def self.get_instance(config, *options) + self.new(config, *options) + end + + def initialize(server, *options) + @server = @config = server + @logger = @server[:Logger] + @options = options + end + + def service(req, res) + method_name = "do_" + req.request_method.gsub(/-/, "_") + if respond_to?(method_name) + __send__(method_name, req, res) + else + raise HTTPStatus::MethodNotAllowed, + "unsupported method `#{req.request_method}'." + end + end + + def do_GET(req, res) + raise HTTPStatus::NotFound, "not found." + end + + def do_HEAD(req, res) + do_GET(req, res) + end + + def do_OPTIONS(req, res) + m = self.methods.grep(/^do_[A-Z]+$/) + m.collect!{|i| i.sub(/do_/, "") } + m.sort! + res["allow"] = m.join(",") + end + + private + + def redirect_to_directory_uri(req, res) + if req.path[-1] != ?/ + location = WEBrick::HTTPUtils.escape_path(req.path + "/") + if req.query_string && req.query_string.size > 0 + location << "?" << req.query_string + end + res.set_redirect(HTTPStatus::MovedPermanently, location) + end + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/cgi_runner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/cgi_runner.rb new file mode 100644 index 00000000..006abd45 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/cgi_runner.rb @@ -0,0 +1,47 @@ +# +# cgi_runner.rb -- CGI launcher. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $ + +def sysread(io, size) + buf = "" + while size > 0 + tmp = io.sysread(size) + buf << tmp + size -= tmp.size + end + return buf +end + +STDIN.binmode + +buf = "" +len = sysread(STDIN, 8).to_i +out = sysread(STDIN, len) +STDOUT.reopen(open(out, "w")) + +len = sysread(STDIN, 8).to_i +err = sysread(STDIN, len) +STDERR.reopen(open(err, "w")) + +len = sysread(STDIN, 8).to_i +dump = sysread(STDIN, len) +hash = Marshal.restore(dump) +ENV.keys.each{|name| ENV.delete(name) } +hash.each{|k, v| ENV[k] = v if v } + +dir = File::dirname(ENV["SCRIPT_FILENAME"]) +Dir::chdir dir + +if interpreter = ARGV[0] + argv = ARGV.dup + argv << ENV["SCRIPT_FILENAME"] + exec(*argv) + # NOTREACHED +end +exec ENV["SCRIPT_FILENAME"] diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/cgihandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/cgihandler.rb new file mode 100644 index 00000000..a35b59ed --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/cgihandler.rb @@ -0,0 +1,104 @@ +# +# cgihandler.rb -- CGIHandler Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $ + +require 'rbconfig' +require 'tempfile' +require 'webrick/config' +require 'webrick/httpservlet/abstract' + +module WEBrick + module HTTPServlet + + class CGIHandler < AbstractServlet + Ruby = File::join(::Config::CONFIG['bindir'], + ::Config::CONFIG['ruby_install_name']) + Ruby << ::Config::CONFIG['EXEEXT'] + CGIRunner = "\"#{Ruby}\" \"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\"" + + def initialize(server, name) + super + @script_filename = name + @tempdir = server[:TempDir] + @cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}" + end + + def do_GET(req, res) + data = nil + status = -1 + + cgi_in = IO::popen(@cgicmd, "wb") + cgi_out = Tempfile.new("webrick.cgiout.", @tempdir) + cgi_err = Tempfile.new("webrick.cgierr.", @tempdir) + begin + cgi_in.sync = true + meta = req.meta_vars + meta["SCRIPT_FILENAME"] = @script_filename + meta["PATH"] = @config[:CGIPathEnv] + if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + meta["SystemRoot"] = ENV["SystemRoot"] + end + dump = Marshal.dump(meta) + + cgi_in.write("%8d" % cgi_out.path.size) + cgi_in.write(cgi_out.path) + cgi_in.write("%8d" % cgi_err.path.size) + cgi_in.write(cgi_err.path) + cgi_in.write("%8d" % dump.size) + cgi_in.write(dump) + + if req.body and req.body.size > 0 + cgi_in.write(req.body) + end + ensure + cgi_in.close + status = $?.exitstatus + sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + data = cgi_out.read + cgi_out.close(true) + if errmsg = cgi_err.read + if errmsg.size > 0 + @logger.error("CGIHandler: #{@script_filename}:\n" + errmsg) + end + end + cgi_err.close(true) + end + + if status != 0 + @logger.error("CGIHandler: #{@script_filename} exit with #{status}") + end + + data = "" unless data + raw_header, body = data.split(/^[\xd\xa]+/on, 2) + raise HTTPStatus::InternalServerError, + "Premature end of script headers: #{@script_filename}" if body.nil? + + begin + header = HTTPUtils::parse_header(raw_header) + if /^(\d+)/ =~ header['status'][0] + res.status = $1.to_i + header.delete('status') + end + if header.has_key?('set-cookie') + header['set-cookie'].each{|k| + res.cookies << Cookie.parse_set_cookie(k) + } + header.delete('set-cookie') + end + header.each{|key, val| res[key] = val.join(", ") } + rescue => ex + raise HTTPStatus::InternalServerError, ex.message + end + res.body = body + end + alias do_POST do_GET + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/erbhandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/erbhandler.rb new file mode 100644 index 00000000..b9d5e65b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/erbhandler.rb @@ -0,0 +1,54 @@ +# +# erbhandler.rb -- ERBHandler Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $ + +require 'webrick/httpservlet/abstract.rb' + +require 'erb' + +module WEBrick + module HTTPServlet + + class ERBHandler < AbstractServlet + def initialize(server, name) + super + @script_filename = name + end + + def do_GET(req, res) + unless defined?(ERB) + @logger.warn "#{self.class}: ERB not defined." + raise HTTPStatus::Forbidden, "ERBHandler cannot work." + end + begin + data = open(@script_filename){|io| io.read } + res.body = evaluate(ERB.new(data), req, res) + res['content-type'] = + HTTPUtils::mime_type(@script_filename, @config[:MimeTypes]) + rescue StandardError => ex + raise + rescue Exception => ex + @logger.error(ex) + raise HTTPStatus::InternalServerError, ex.message + end + end + + alias do_POST do_GET + + private + def evaluate(erb, servlet_request, servlet_response) + Module.new.module_eval{ + meta_vars = servlet_request.meta_vars + query = servlet_request.query + erb.result(binding) + } + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/filehandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/filehandler.rb new file mode 100644 index 00000000..24f59d71 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/filehandler.rb @@ -0,0 +1,435 @@ +# +# filehandler.rb -- FileHandler Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $ + +require 'thread' +require 'time' + +require 'webrick/htmlutils' +require 'webrick/httputils' +require 'webrick/httpstatus' + +module WEBrick + module HTTPServlet + + class DefaultFileHandler < AbstractServlet + def initialize(server, local_path) + super + @local_path = local_path + end + + def do_GET(req, res) + st = File::stat(@local_path) + mtime = st.mtime + res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i) + + if not_modified?(req, res, mtime, res['etag']) + res.body = '' + raise HTTPStatus::NotModified + elsif req['range'] + make_partial_content(req, res, @local_path, st.size) + raise HTTPStatus::PartialContent + else + mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes]) + res['content-type'] = mtype + res['content-length'] = st.size + res['last-modified'] = mtime.httpdate + res.body = open(@local_path, "rb") + end + end + + def not_modified?(req, res, mtime, etag) + if ir = req['if-range'] + begin + if Time.httpdate(ir) >= mtime + return true + end + rescue + if HTTPUtils::split_header_value(ir).member?(res['etag']) + return true + end + end + end + + if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime + return true + end + + if (inm = req['if-none-match']) && + HTTPUtils::split_header_value(inm).member?(res['etag']) + return true + end + + return false + end + + def make_partial_content(req, res, filename, filesize) + mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes]) + unless ranges = HTTPUtils::parse_range_header(req['range']) + raise HTTPStatus::BadRequest, + "Unrecognized range-spec: \"#{req['range']}\"" + end + open(filename, "rb"){|io| + if ranges.size > 1 + time = Time.now + boundary = "#{time.sec}_#{time.usec}_#{Process::pid}" + body = '' + ranges.each{|range| + first, last = prepare_range(range, filesize) + next if first < 0 + io.pos = first + content = io.read(last-first+1) + body << "--" << boundary << CRLF + body << "Content-Type: #{mtype}" << CRLF + body << "Content-Range: #{first}-#{last}/#{filesize}" << CRLF + body << CRLF + body << content + body << CRLF + } + raise HTTPStatus::RequestRangeNotSatisfiable if body.empty? + body << "--" << boundary << "--" << CRLF + res["content-type"] = "multipart/byteranges; boundary=#{boundary}" + res.body = body + elsif range = ranges[0] + first, last = prepare_range(range, filesize) + raise HTTPStatus::RequestRangeNotSatisfiable if first < 0 + if last == filesize - 1 + content = io.dup + content.pos = first + else + io.pos = first + content = io.read(last-first+1) + end + res['content-type'] = mtype + res['content-range'] = "#{first}-#{last}/#{filesize}" + res['content-length'] = last - first + 1 + res.body = content + else + raise HTTPStatus::BadRequest + end + } + end + + def prepare_range(range, filesize) + first = range.first < 0 ? filesize + range.first : range.first + return -1, -1 if first < 0 || first >= filesize + last = range.last < 0 ? filesize + range.last : range.last + last = filesize - 1 if last >= filesize + return first, last + end + end + + class FileHandler < AbstractServlet + HandlerTable = Hash.new + + def self.add_handler(suffix, handler) + HandlerTable[suffix] = handler + end + + def self.remove_handler(suffix) + HandlerTable.delete(suffix) + end + + def initialize(server, root, options={}, default=Config::FileHandler) + @config = server.config + @logger = @config[:Logger] + @root = File.expand_path(root) + if options == true || options == false + options = { :FancyIndexing => options } + end + @options = default.dup.update(options) + end + + def service(req, res) + # if this class is mounted on "/" and /~username is requested. + # we're going to override path informations before invoking service. + if defined?(Etc) && @options[:UserDir] && req.script_name.empty? + if %r|^(/~([^/]+))| =~ req.path_info + script_name, user = $1, $2 + path_info = $' + begin + passwd = Etc::getpwnam(user) + @root = File::join(passwd.dir, @options[:UserDir]) + req.script_name = script_name + req.path_info = path_info + rescue + @logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed" + end + end + end + prevent_directory_traversal(req, res) + super(req, res) + end + + def do_GET(req, res) + unless exec_handler(req, res) + set_dir_list(req, res) + end + end + + def do_POST(req, res) + unless exec_handler(req, res) + raise HTTPStatus::NotFound, "`#{req.path}' not found." + end + end + + def do_OPTIONS(req, res) + unless exec_handler(req, res) + super(req, res) + end + end + + # ToDo + # RFC2518: HTTP Extensions for Distributed Authoring -- WEBDAV + # + # PROPFIND PROPPATCH MKCOL DELETE PUT COPY MOVE + # LOCK UNLOCK + + # RFC3253: Versioning Extensions to WebDAV + # (Web Distributed Authoring and Versioning) + # + # VERSION-CONTROL REPORT CHECKOUT CHECK_IN UNCHECKOUT + # MKWORKSPACE UPDATE LABEL MERGE ACTIVITY + + private + + def trailing_pathsep?(path) + # check for trailing path separator: + # File.dirname("/aaaa/bbbb/") #=> "/aaaa") + # File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb") + # File.dirname("/aaaa/bbbb") #=> "/aaaa") + # File.dirname("/aaaa/bbbbx") #=> "/aaaa") + return File.dirname(path) != File.dirname(path+"x") + end + + def prevent_directory_traversal(req, res) + # Preventing directory traversal on Windows platforms; + # Backslashes (0x5c) in path_info are not interpreted as special + # character in URI notation. So the value of path_info should be + # normalize before accessing to the filesystem. + + if trailing_pathsep?(req.path_info) + # File.expand_path removes the trailing path separator. + # Adding a character is a workaround to save it. + # File.expand_path("/aaa/") #=> "/aaa" + # File.expand_path("/aaa/" + "x") #=> "/aaa/x" + expanded = File.expand_path(req.path_info + "x") + expanded.chop! # remove trailing "x" + else + expanded = File.expand_path(req.path_info) + end + req.path_info = expanded + end + + def exec_handler(req, res) + raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root + if set_filename(req, res) + handler = get_handler(req, res) + call_callback(:HandlerCallback, req, res) + h = handler.get_instance(@config, res.filename) + h.service(req, res) + return true + end + call_callback(:HandlerCallback, req, res) + return false + end + + def get_handler(req, res) + suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase + if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename + if @options[:AcceptableLanguages].include?($2.downcase) + suffix2 = $1.downcase + end + end + handler_table = @options[:HandlerTable] + return handler_table[suffix1] || handler_table[suffix2] || + HandlerTable[suffix1] || HandlerTable[suffix2] || + DefaultFileHandler + end + + def set_filename(req, res) + res.filename = @root.dup + path_info = req.path_info.scan(%r|/[^/]*|) + + path_info.unshift("") # dummy for checking @root dir + while base = path_info.first + break if base == "/" + break unless File.directory?(File.expand_path(res.filename + base)) + shift_path_info(req, res, path_info) + call_callback(:DirectoryCallback, req, res) + end + + if base = path_info.first + if base == "/" + if file = search_index_file(req, res) + shift_path_info(req, res, path_info, file) + call_callback(:FileCallback, req, res) + return true + end + shift_path_info(req, res, path_info) + elsif file = search_file(req, res, base) + shift_path_info(req, res, path_info, file) + call_callback(:FileCallback, req, res) + return true + else + raise HTTPStatus::NotFound, "`#{req.path}' not found." + end + end + + return false + end + + def check_filename(req, res, name) + if nondisclosure_name?(name) || windows_ambiguous_name?(name) + @logger.warn("the request refers nondisclosure name `#{name}'.") + raise HTTPStatus::NotFound, "`#{req.path}' not found." + end + end + + def shift_path_info(req, res, path_info, base=nil) + tmp = path_info.shift + base = base || tmp + req.path_info = path_info.join + req.script_name << base + res.filename = File.expand_path(res.filename + base) + check_filename(req, res, File.basename(res.filename)) + end + + def search_index_file(req, res) + @config[:DirectoryIndex].each{|index| + if file = search_file(req, res, "/"+index) + return file + end + } + return nil + end + + def search_file(req, res, basename) + langs = @options[:AcceptableLanguages] + path = res.filename + basename + if File.file?(path) + return basename + elsif langs.size > 0 + req.accept_language.each{|lang| + path_with_lang = path + ".#{lang}" + if langs.member?(lang) && File.file?(path_with_lang) + return basename + ".#{lang}" + end + } + (langs - req.accept_language).each{|lang| + path_with_lang = path + ".#{lang}" + if File.file?(path_with_lang) + return basename + ".#{lang}" + end + } + end + return nil + end + + def call_callback(callback_name, req, res) + if cb = @options[callback_name] + cb.call(req, res) + end + end + + def windows_ambiguous_name?(name) + return true if /[. ]+\z/ =~ name + return true if /::\$DATA\z/ =~ name + return false + end + + def nondisclosure_name?(name) + @options[:NondisclosureName].each{|pattern| + if File.fnmatch(pattern, name, File::FNM_CASEFOLD) + return true + end + } + return false + end + + def set_dir_list(req, res) + redirect_to_directory_uri(req, res) + unless @options[:FancyIndexing] + raise HTTPStatus::Forbidden, "no access permission to `#{req.path}'" + end + local_path = res.filename + list = Dir::entries(local_path).collect{|name| + next if name == "." || name == ".." + next if nondisclosure_name?(name) + next if windows_ambiguous_name?(name) + st = (File::stat(File.join(local_path, name)) rescue nil) + if st.nil? + [ name, nil, -1 ] + elsif st.directory? + [ name + "/", st.mtime, -1 ] + else + [ name, st.mtime, st.size ] + end + } + list.compact! + + if d0 = req.query["N"]; idx = 0 + elsif d0 = req.query["M"]; idx = 1 + elsif d0 = req.query["S"]; idx = 2 + else d0 = "A" ; idx = 0 + end + d1 = (d0 == "A") ? "D" : "A" + + if d0 == "A" + list.sort!{|a,b| a[idx] <=> b[idx] } + else + list.sort!{|a,b| b[idx] <=> a[idx] } + end + + res['content-type'] = "text/html" + + res.body = <<-_end_of_html_ + + + Index of #{HTMLUtils::escape(req.path)} + +

    Index of #{HTMLUtils::escape(req.path)}

    + _end_of_html_ + + res.body << "
    \n"
    +        res.body << " Name                          "
    +        res.body << "Last modified         "
    +        res.body << "Size\n"
    +        res.body << "
    \n" + + list.unshift [ "..", File::mtime(local_path+"/.."), -1 ] + list.each{ |name, time, size| + if name == ".." + dname = "Parent Directory" + elsif name.size > 25 + dname = name.sub(/^(.{23})(.*)/){ $1 + ".." } + else + dname = name + end + s = " #{dname}" + s << " " * (30 - dname.size) + s << (time ? time.strftime("%Y/%m/%d %H:%M ") : " " * 22) + s << (size >= 0 ? size.to_s : "-") << "\n" + res.body << s + } + res.body << "

    " + + res.body << <<-_end_of_html_ +
    + #{HTMLUtils::escape(@config[:ServerSoftware])}
    + at #{req.host}:#{req.port} +
    + + + _end_of_html_ + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/prochandler.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/prochandler.rb new file mode 100644 index 00000000..783cb278 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpservlet/prochandler.rb @@ -0,0 +1,33 @@ +# +# prochandler.rb -- ProcHandler Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $ + +require 'webrick/httpservlet/abstract.rb' + +module WEBrick + module HTTPServlet + + class ProcHandler < AbstractServlet + def get_instance(server, *options) + self + end + + def initialize(proc) + @proc = proc + end + + def do_GET(request, response) + @proc.call(request, response) + end + + alias do_POST do_GET + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpstatus.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpstatus.rb new file mode 100644 index 00000000..0b22c992 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpstatus.rb @@ -0,0 +1,126 @@ +# +# httpstatus.rb -- HTTPStatus Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $ + +module WEBrick + + module HTTPStatus + + class Status < StandardError; end + class Info < Status; end + class Success < Status; end + class Redirect < Status; end + class Error < Status; end + class ClientError < Error; end + class ServerError < Error; end + + class EOFError < StandardError; end + + StatusMessage = { + 100, 'Continue', + 101, 'Switching Protocols', + 200, 'OK', + 201, 'Created', + 202, 'Accepted', + 203, 'Non-Authoritative Information', + 204, 'No Content', + 205, 'Reset Content', + 206, 'Partial Content', + 300, 'Multiple Choices', + 301, 'Moved Permanently', + 302, 'Found', + 303, 'See Other', + 304, 'Not Modified', + 305, 'Use Proxy', + 307, 'Temporary Redirect', + 400, 'Bad Request', + 401, 'Unauthorized', + 402, 'Payment Required', + 403, 'Forbidden', + 404, 'Not Found', + 405, 'Method Not Allowed', + 406, 'Not Acceptable', + 407, 'Proxy Authentication Required', + 408, 'Request Timeout', + 409, 'Conflict', + 410, 'Gone', + 411, 'Length Required', + 412, 'Precondition Failed', + 413, 'Request Entity Too Large', + 414, 'Request-URI Too Large', + 415, 'Unsupported Media Type', + 416, 'Request Range Not Satisfiable', + 417, 'Expectation Failed', + 500, 'Internal Server Error', + 501, 'Not Implemented', + 502, 'Bad Gateway', + 503, 'Service Unavailable', + 504, 'Gateway Timeout', + 505, 'HTTP Version Not Supported' + } + + CodeToError = {} + + StatusMessage.each{|code, message| + var_name = message.gsub(/[ \-]/,'_').upcase + err_name = message.gsub(/[ \-]/,'') + + case code + when 100...200; parent = Info + when 200...300; parent = Success + when 300...400; parent = Redirect + when 400...500; parent = ClientError + when 500...600; parent = ServerError + end + + eval %- + RC_#{var_name} = #{code} + class #{err_name} < #{parent} + def self.code() RC_#{var_name} end + def self.reason_phrase() StatusMessage[code] end + def code() self::class::code end + def reason_phrase() self::class::reason_phrase end + alias to_i code + end + - + + CodeToError[code] = const_get(err_name) + } + + def reason_phrase(code) + StatusMessage[code.to_i] + end + def info?(code) + code.to_i >= 100 and code.to_i < 200 + end + def success?(code) + code.to_i >= 200 and code.to_i < 300 + end + def redirect?(code) + code.to_i >= 300 and code.to_i < 400 + end + def error?(code) + code.to_i >= 400 and code.to_i < 600 + end + def client_error?(code) + code.to_i >= 400 and code.to_i < 500 + end + def server_error?(code) + code.to_i >= 500 and code.to_i < 600 + end + + def self.[](code) + CodeToError[code] + end + + module_function :reason_phrase + module_function :info?, :success?, :redirect?, :error? + module_function :client_error?, :server_error? + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httputils.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httputils.rb new file mode 100644 index 00000000..976d3e91 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httputils.rb @@ -0,0 +1,391 @@ +# +# httputils.rb -- HTTPUtils Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $ + +require 'socket' +require 'tempfile' + +module WEBrick + CR = "\x0d" + LF = "\x0a" + CRLF = "\x0d\x0a" + + module HTTPUtils + + def normalize_path(path) + raise "abnormal path `#{path}'" if path[0] != ?/ + ret = path.dup + + ret.gsub!(%r{/+}o, '/') # // => / + while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => / + while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo + + raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret + ret + end + module_function :normalize_path + + ##### + + DefaultMimeTypes = { + "ai" => "application/postscript", + "asc" => "text/plain", + "avi" => "video/x-msvideo", + "bin" => "application/octet-stream", + "bmp" => "image/bmp", + "class" => "application/octet-stream", + "cer" => "application/pkix-cert", + "crl" => "application/pkix-crl", + "crt" => "application/x-x509-ca-cert", + #"crl" => "application/x-pkcs7-crl", + "css" => "text/css", + "dms" => "application/octet-stream", + "doc" => "application/msword", + "dvi" => "application/x-dvi", + "eps" => "application/postscript", + "etx" => "text/x-setext", + "exe" => "application/octet-stream", + "gif" => "image/gif", + "htm" => "text/html", + "html" => "text/html", + "jpe" => "image/jpeg", + "jpeg" => "image/jpeg", + "jpg" => "image/jpeg", + "lha" => "application/octet-stream", + "lzh" => "application/octet-stream", + "mov" => "video/quicktime", + "mpe" => "video/mpeg", + "mpeg" => "video/mpeg", + "mpg" => "video/mpeg", + "pbm" => "image/x-portable-bitmap", + "pdf" => "application/pdf", + "pgm" => "image/x-portable-graymap", + "png" => "image/png", + "pnm" => "image/x-portable-anymap", + "ppm" => "image/x-portable-pixmap", + "ppt" => "application/vnd.ms-powerpoint", + "ps" => "application/postscript", + "qt" => "video/quicktime", + "ras" => "image/x-cmu-raster", + "rb" => "text/plain", + "rd" => "text/plain", + "rtf" => "application/rtf", + "sgm" => "text/sgml", + "sgml" => "text/sgml", + "tif" => "image/tiff", + "tiff" => "image/tiff", + "txt" => "text/plain", + "xbm" => "image/x-xbitmap", + "xls" => "application/vnd.ms-excel", + "xml" => "text/xml", + "xpm" => "image/x-xpixmap", + "xwd" => "image/x-xwindowdump", + "zip" => "application/zip", + } + + # Load Apache compatible mime.types file. + def load_mime_types(file) + open(file){ |io| + hash = Hash.new + io.each{ |line| + next if /^#/ =~ line + line.chomp! + mimetype, ext0 = line.split(/\s+/, 2) + next unless ext0 + next if ext0.empty? + ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype } + } + hash + } + end + module_function :load_mime_types + + def mime_type(filename, mime_tab) + suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase) + suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase) + mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream" + end + module_function :mime_type + + ##### + + def parse_header(raw) + header = Hash.new([].freeze) + field = nil + raw.each{|line| + case line + when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om + field, value = $1, $2 + field.downcase! + header[field] = [] unless header.has_key?(field) + header[field] << value + when /^\s+(.*?)\s*\z/om + value = $1 + unless field + raise "bad header '#{line.inspect}'." + end + header[field][-1] << " " << value + else + raise "bad header '#{line.inspect}'." + end + } + header.each{|key, values| + values.each{|value| + value.strip! + value.gsub!(/\s+/, " ") + } + } + header + end + module_function :parse_header + + def split_header_value(str) + str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+) + (?:,\s*|\Z)'xn).flatten + end + module_function :split_header_value + + def parse_range_header(ranges_specifier) + if /^bytes=(.*)/ =~ ranges_specifier + byte_range_set = split_header_value($1) + byte_range_set.collect{|range_spec| + case range_spec + when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i + when /^(\d+)-/ then $1.to_i .. -1 + when /^-(\d+)/ then -($1.to_i) .. -1 + else return nil + end + } + end + end + module_function :parse_range_header + + def parse_qvalues(value) + tmp = [] + if value + parts = value.split(/,\s*/) + parts.each {|part| + if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part) + val = m[1] + q = (m[2] or 1).to_f + tmp.push([val, q]) + end + } + tmp = tmp.sort_by{|val, q| -q} + tmp.collect!{|val, q| val} + end + return tmp + end + module_function :parse_qvalues + + ##### + + def dequote(str) + ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup + ret.gsub!(/\\(.)/, "\\1") + ret + end + module_function :dequote + + def quote(str) + '"' << str.gsub(/[\\\"]/o, "\\\1") << '"' + end + module_function :quote + + ##### + + class FormData < String + EmptyRawHeader = [].freeze + EmptyHeader = {}.freeze + + attr_accessor :name, :filename, :next_data + protected :next_data + + def initialize(*args) + @name = @filename = @next_data = nil + if args.empty? + @raw_header = [] + @header = nil + super("") + else + @raw_header = EmptyRawHeader + @header = EmptyHeader + super(args.shift) + unless args.empty? + @next_data = self.class.new(*args) + end + end + end + + def [](*key) + begin + @header[key[0].downcase].join(", ") + rescue StandardError, NameError + super + end + end + + def <<(str) + if @header + super + elsif str == CRLF + @header = HTTPUtils::parse_header(@raw_header) + if cd = self['content-disposition'] + if /\s+name="(.*?)"/ =~ cd then @name = $1 end + if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end + end + else + @raw_header << str + end + self + end + + def append_data(data) + tmp = self + while tmp + unless tmp.next_data + tmp.next_data = data + break + end + tmp = tmp.next_data + end + self + end + + def each_data + tmp = self + while tmp + next_data = tmp.next_data + yield(tmp) + tmp = next_data + end + end + + def list + ret = [] + each_data{|data| + ret << data.to_s + } + ret + end + + alias :to_ary :list + + def to_s + String.new(self) + end + end + + def parse_query(str) + query = Hash.new + if str + str.split(/[&;]/).each{|x| + next if x.empty? + key, val = x.split(/=/,2) + key = unescape_form(key) + val = unescape_form(val.to_s) + val = FormData.new(val) + val.name = key + if query.has_key?(key) + query[key].append_data(val) + next + end + query[key] = val + } + end + query + end + module_function :parse_query + + def parse_form_data(io, boundary) + boundary_regexp = /\A--#{boundary}(--)?#{CRLF}\z/ + form_data = Hash.new + return form_data unless io + data = nil + io.each{|line| + if boundary_regexp =~ line + if data + data.chop! + key = data.name + if form_data.has_key?(key) + form_data[key].append_data(data) + else + form_data[key] = data + end + end + data = FormData.new + next + else + if data + data << line + end + end + } + return form_data + end + module_function :parse_form_data + + ##### + + reserved = ';/?:@&=+$,' + num = '0123456789' + lowalpha = 'abcdefghijklmnopqrstuvwxyz' + upalpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + mark = '-_.!~*\'()' + unreserved = num + lowalpha + upalpha + mark + control = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f" + space = " " + delims = '<>#%"' + unwise = '{}|\\^[]`' + nonascii = (0x80..0xff).collect{|c| c.chr }.join + + module_function + + def _make_regex(str) /([#{Regexp.escape(str)}])/n end + def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end + def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1[0] } end + def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end + + UNESCAPED = _make_regex(control+space+delims+unwise+nonascii) + UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii) + NONASCII = _make_regex(nonascii) + ESCAPED = /%([0-9a-fA-F]{2})/ + UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,") + + def escape(str) + _escape(str, UNESCAPED) + end + + def unescape(str) + _unescape(str, ESCAPED) + end + + def escape_form(str) + ret = _escape(str, UNESCAPED_FORM) + ret.gsub!(/ /, "+") + ret + end + + def unescape_form(str) + _unescape(str.gsub(/\+/, " "), ESCAPED) + end + + def escape_path(str) + result = "" + str.scan(%r{/([^/]*)}).each{|i| + result << "/" << _escape(i[0], UNESCAPED_PCHAR) + } + return result + end + + def escape8bit(str) + _escape(str, NONASCII) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpversion.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpversion.rb new file mode 100644 index 00000000..86907a26 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/httpversion.rb @@ -0,0 +1,49 @@ +# +# HTTPVersion.rb -- presentation of HTTP version +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpversion.rb,v 1.5 2002/09/21 12:23:37 gotoyuzo Exp $ + +module WEBrick + class HTTPVersion + include Comparable + + attr_accessor :major, :minor + + def self.convert(version) + version.is_a?(self) ? version : new(version) + end + + def initialize(version) + case version + when HTTPVersion + @major, @minor = version.major, version.minor + when String + if /^(\d+)\.(\d+)$/ =~ version + @major, @minor = $1.to_i, $2.to_i + end + end + if @major.nil? || @minor.nil? + raise ArgumentError, + format("cannot convert %s into %s", version.class, self.class) + end + end + + def <=>(other) + unless other.is_a?(self.class) + other = self.class.new(other) + end + if (ret = @major <=> other.major) == 0 + return @minor <=> other.minor + end + return ret + end + + def to_s + format("%d.%d", @major, @minor) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/log.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/log.rb new file mode 100644 index 00000000..5d4fd0a1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/log.rb @@ -0,0 +1,88 @@ +# +# log.rb -- Log Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: log.rb,v 1.26 2002/10/06 17:06:10 gotoyuzo Exp $ + +module WEBrick + class BasicLog + # log-level constant + FATAL, ERROR, WARN, INFO, DEBUG = 1, 2, 3, 4, 5 + + attr_accessor :level + + def initialize(log_file=nil, level=nil) + @level = level || INFO + case log_file + when String + @log = open(log_file, "a+") + @log.sync = true + @opened = true + when NilClass + @log = $stderr + else + @log = log_file # requires "<<". (see BasicLog#log) + end + end + + def close + @log.close if @opened + @log = nil + end + + def log(level, data) + if @log && level <= @level + data += "\n" if /\n\Z/ !~ data + @log << data + end + end + + def <<(obj) + log(INFO, obj.to_s) + end + + def fatal(msg) log(FATAL, "FATAL " << format(msg)); end + def error(msg) log(ERROR, "ERROR " << format(msg)); end + def warn(msg) log(WARN, "WARN " << format(msg)); end + def info(msg) log(INFO, "INFO " << format(msg)); end + def debug(msg) log(DEBUG, "DEBUG " << format(msg)); end + + def fatal?; @level >= FATAL; end + def error?; @level >= ERROR; end + def warn?; @level >= WARN; end + def info?; @level >= INFO; end + def debug?; @level >= DEBUG; end + + private + + def format(arg) + str = if arg.is_a?(Exception) + "#{arg.class}: #{arg.message}\n\t" << + arg.backtrace.join("\n\t") << "\n" + elsif arg.respond_to?(:to_str) + arg.to_str + else + arg.inspect + end + end + end + + class Log < BasicLog + attr_accessor :time_format + + def initialize(log_file=nil, level=nil) + super(log_file, level) + @time_format = "[%Y-%m-%d %H:%M:%S]" + end + + def log(level, data) + tmp = Time.now.strftime(@time_format) + tmp << " " << data + super(level, tmp) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/server.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/server.rb new file mode 100644 index 00000000..16dbd46f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/server.rb @@ -0,0 +1,200 @@ +# +# server.rb -- GenericServer Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $ + +require 'thread' +require 'socket' +require 'timeout' +require 'webrick/config' +require 'webrick/log' + +module WEBrick + + class ServerError < StandardError; end + + class SimpleServer + def SimpleServer.start + yield + end + end + + class Daemon + def Daemon.start + exit!(0) if fork + Process::setsid + exit!(0) if fork + Dir::chdir("/") + File::umask(0) + STDIN.reopen("/dev/null") + STDOUT.reopen("/dev/null", "w") + STDERR.reopen("/dev/null", "w") + yield if block_given? + end + end + + class GenericServer + attr_reader :status, :config, :logger, :tokens, :listeners + + def initialize(config={}, default=Config::General) + @config = default.dup.update(config) + @status = :Stop + @config[:Logger] ||= Log::new + @logger = @config[:Logger] + + @tokens = SizedQueue.new(@config[:MaxClients]) + @config[:MaxClients].times{ @tokens.push(nil) } + + webrickv = WEBrick::VERSION + rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]" + @logger.info("WEBrick #{webrickv}") + @logger.info("ruby #{rubyv}") + + @listeners = [] + unless @config[:DoNotListen] + if @config[:Listen] + warn(":Listen option is deprecated; use GenericServer#listen") + end + listen(@config[:BindAddress], @config[:Port]) + if @config[:Port] == 0 + @config[:Port] = @listeners[0].addr[1] + end + end + end + + def [](key) + @config[key] + end + + def listen(address, port) + @listeners += Utils::create_listeners(address, port, @logger) + end + + def start(&block) + raise ServerError, "already started." if @status != :Stop + server_type = @config[:ServerType] || SimpleServer + + server_type.start{ + @logger.info \ + "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}" + call_callback(:StartCallback) + + thgroup = ThreadGroup.new + @status = :Running + while @status == :Running + begin + if svrs = IO.select(@listeners, nil, nil, 2.0) + svrs[0].each{|svr| + @tokens.pop # blocks while no token is there. + if sock = accept_client(svr) + th = start_thread(sock, &block) + th[:WEBrickThread] = true + thgroup.add(th) + else + @tokens.push(nil) + end + } + end + rescue Errno::EBADF, IOError => ex + # if the listening socket was closed in GenericServer#shutdown, + # IO::select raise it. + rescue Exception => ex + msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" + @logger.error msg + end + end + + @logger.info "going to shutdown ..." + thgroup.list.each{|th| th.join if th[:WEBrickThread] } + call_callback(:StopCallback) + @logger.info "#{self.class}#start done." + @status = :Stop + } + end + + def stop + if @status == :Running + @status = :Shutdown + end + end + + def shutdown + stop + @listeners.each{|s| + if @logger.debug? + addr = s.addr + @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})") + end + s.close + } + @listeners.clear + end + + def run(sock) + @logger.fatal "run() must be provided by user." + end + + private + + def accept_client(svr) + sock = nil + begin + sock = svr.accept + sock.sync = true + Utils::set_non_blocking(sock) + Utils::set_close_on_exec(sock) + rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex + # TCP connection was established but RST segment was sent + # from peer before calling TCPServer#accept. + rescue Exception => ex + msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" + @logger.error msg + end + return sock + end + + def start_thread(sock, &block) + Thread.start{ + begin + Thread.current[:WEBrickSocket] = sock + begin + addr = sock.peeraddr + @logger.debug "accept: #{addr[3]}:#{addr[1]}" + rescue SocketError + @logger.debug "accept:
    " + raise + end + call_callback(:AcceptCallback, sock) + block ? block.call(sock) : run(sock) + rescue Errno::ENOTCONN + @logger.debug "Errno::ENOTCONN raised" + rescue ServerError => ex + msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" + @logger.error msg + rescue Exception => ex + @logger.error ex + ensure + @tokens.push(nil) + Thread.current[:WEBrickSocket] = nil + if addr + @logger.debug "close: #{addr[3]}:#{addr[1]}" + else + @logger.debug "close:
    " + end + sock.close + end + } + end + + def call_callback(callback_name, *args) + if cb = @config[callback_name] + cb.call(*args) + end + end + end # end of GenericServer +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/ssl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/ssl.rb new file mode 100644 index 00000000..4c71c879 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/ssl.rb @@ -0,0 +1,126 @@ +# +# ssl.rb -- SSL/TLS enhancement for GenericServer +# +# Copyright (c) 2003 GOTOU Yuuzou All rights reserved. +# +# $Id: ssl.rb 11708 2007-02-12 23:01:19Z shyouhei $ + +require 'webrick' +require 'openssl' + +module WEBrick + module Config + svrsoft = General[:ServerSoftware] + osslv = ::OpenSSL::OPENSSL_VERSION.split[1] + SSL = { + :ServerSoftware => "#{svrsoft} OpenSSL/#{osslv}", + :SSLEnable => false, + :SSLCertificate => nil, + :SSLPrivateKey => nil, + :SSLClientCA => nil, + :SSLExtraChainCert => nil, + :SSLCACertificateFile => nil, + :SSLCACertificatePath => nil, + :SSLCertificateStore => nil, + :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE, + :SSLVerifyDepth => nil, + :SSLVerifyCallback => nil, # custom verification + :SSLTimeout => nil, + :SSLOptions => nil, + :SSLStartImmediately => true, + # Must specify if you use auto generated certificate. + :SSLCertName => nil, + :SSLCertComment => "Generated by Ruby/OpenSSL" + } + General.update(SSL) + end + + module Utils + def create_self_signed_cert(bits, cn, comment) + rsa = OpenSSL::PKey::RSA.new(bits){|p, n| + case p + when 0; $stderr.putc "." # BN_generate_prime + when 1; $stderr.putc "+" # BN_generate_prime + when 2; $stderr.putc "*" # searching good prime, + # n = #of try, + # but also data from BN_generate_prime + when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q, + # but also data from BN_generate_prime + else; $stderr.putc "*" # BN_generate_prime + end + } + cert = OpenSSL::X509::Certificate.new + cert.version = 3 + cert.serial = 0 + name = OpenSSL::X509::Name.new(cn) + cert.subject = name + cert.issuer = name + cert.not_before = Time.now + cert.not_after = Time.now + (365*24*60*60) + cert.public_key = rsa.public_key + + ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) + ef.issuer_certificate = cert + cert.extensions = [ + ef.create_extension("basicConstraints","CA:FALSE"), + ef.create_extension("keyUsage", "keyEncipherment"), + ef.create_extension("subjectKeyIdentifier", "hash"), + ef.create_extension("extendedKeyUsage", "serverAuth"), + ef.create_extension("nsComment", comment), + ] + aki = ef.create_extension("authorityKeyIdentifier", + "keyid:always,issuer:always") + cert.add_extension(aki) + cert.sign(rsa, OpenSSL::Digest::SHA1.new) + + return [ cert, rsa ] + end + module_function :create_self_signed_cert + end + + class GenericServer + def ssl_context + @ssl_context ||= nil + end + + def listen(address, port) + listeners = Utils::create_listeners(address, port, @logger) + if @config[:SSLEnable] + unless ssl_context + @ssl_context = setup_ssl_context(@config) + @logger.info("\n" + @config[:SSLCertificate].to_text) + end + listeners.collect!{|svr| + ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context) + ssvr.start_immediately = @config[:SSLStartImmediately] + ssvr + } + end + @listeners += listeners + end + + def setup_ssl_context(config) + unless config[:SSLCertificate] + cn = config[:SSLCertName] + comment = config[:SSLCertComment] + cert, key = Utils::create_self_signed_cert(1024, cn, comment) + config[:SSLCertificate] = cert + config[:SSLPrivateKey] = key + end + ctx = OpenSSL::SSL::SSLContext.new + ctx.key = config[:SSLPrivateKey] + ctx.cert = config[:SSLCertificate] + ctx.client_ca = config[:SSLClientCA] + ctx.extra_chain_cert = config[:SSLExtraChainCert] + ctx.ca_file = config[:SSLCACertificateFile] + ctx.ca_path = config[:SSLCACertificatePath] + ctx.cert_store = config[:SSLCertificateStore] + ctx.verify_mode = config[:SSLVerifyClient] + ctx.verify_depth = config[:SSLVerifyDepth] + ctx.verify_callback = config[:SSLVerifyCallback] + ctx.timeout = config[:SSLTimeout] + ctx.options = config[:SSLOptions] + ctx + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/utils.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/utils.rb new file mode 100644 index 00000000..cf9da6f2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/utils.rb @@ -0,0 +1,100 @@ +# +# utils.rb -- Miscellaneous utilities +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $ + +require 'socket' +require 'fcntl' +begin + require 'etc' +rescue LoadError + nil +end + +module WEBrick + module Utils + def set_non_blocking(io) + flag = File::NONBLOCK + if defined?(Fcntl::F_GETFL) + flag |= io.fcntl(Fcntl::F_GETFL) + end + io.fcntl(Fcntl::F_SETFL, flag) + end + module_function :set_non_blocking + + def set_close_on_exec(io) + if defined?(Fcntl::FD_CLOEXEC) + io.fcntl(Fcntl::FD_CLOEXEC, 1) + end + end + module_function :set_close_on_exec + + def su(user) + if defined?(Etc) + pw = Etc.getpwnam(user) + Process::initgroups(user, pw.gid) + Process::Sys::setgid(pw.gid) + Process::Sys::setuid(pw.uid) + else + warn("WEBrick::Utils::su doesn't work on this platform") + end + end + module_function :su + + def getservername + host = Socket::gethostname + begin + Socket::gethostbyname(host)[0] + rescue + host + end + end + module_function :getservername + + def create_listeners(address, port, logger=nil) + unless port + raise ArgumentError, "must specify port" + end + res = Socket::getaddrinfo(address, port, + Socket::AF_UNSPEC, # address family + Socket::SOCK_STREAM, # socket type + 0, # protocol + Socket::AI_PASSIVE) # flag + last_error = nil + sockets = [] + res.each{|ai| + begin + logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger + sock = TCPServer.new(ai[3], port) + port = sock.addr[1] if port == 0 + Utils::set_close_on_exec(sock) + sockets << sock + rescue => ex + logger.warn("TCPServer Error: #{ex}") if logger + last_error = ex + end + } + raise last_error if sockets.empty? + return sockets + end + module_function :create_listeners + + RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "0123456789" + + "abcdefghijklmnopqrstuvwxyz" + + def random_string(len) + rand_max = RAND_CHARS.size + ret = "" + len.times{ ret << RAND_CHARS[rand(rand_max)] } + ret + end + module_function :random_string + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/version.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/version.rb new file mode 100644 index 00000000..b2b9fd3b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/webrick/version.rb @@ -0,0 +1,13 @@ +# +# version.rb -- version and release date +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $ + +module WEBrick + VERSION = "1.3.1" +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/binding.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/binding.rb new file mode 100644 index 00000000..58a21d82 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/binding.rb @@ -0,0 +1,65 @@ +# WSDL4R - WSDL binding definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL + + +class Binding < Info + attr_reader :name # required + attr_reader :type # required + attr_reader :operations + attr_reader :soapbinding + + def initialize + super + @name = nil + @type = nil + @operations = XSD::NamedElements.new + @soapbinding = nil + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when OperationName + o = OperationBinding.new + @operations << o + o + when SOAPBindingName + o = WSDL::SOAP::Binding.new + @soapbinding = o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + when TypeAttrName + @type = value + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/data.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/data.rb new file mode 100644 index 00000000..45eaad85 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/data.rb @@ -0,0 +1,64 @@ +# WSDL4R - WSDL data definitions. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'wsdl/documentation' +require 'wsdl/definitions' +require 'wsdl/types' +require 'wsdl/message' +require 'wsdl/part' +require 'wsdl/portType' +require 'wsdl/operation' +require 'wsdl/param' +require 'wsdl/binding' +require 'wsdl/operationBinding' +require 'wsdl/service' +require 'wsdl/port' +require 'wsdl/import' + + +module WSDL + + +ArrayTypeAttrName = XSD::QName.new(Namespace, 'arrayType') +BindingName = XSD::QName.new(Namespace, 'binding') +DefinitionsName = XSD::QName.new(Namespace, 'definitions') +DocumentationName = XSD::QName.new(Namespace, 'documentation') +FaultName = XSD::QName.new(Namespace, 'fault') +ImportName = XSD::QName.new(Namespace, 'import') +InputName = XSD::QName.new(Namespace, 'input') +MessageName = XSD::QName.new(Namespace, 'message') +OperationName = XSD::QName.new(Namespace, 'operation') +OutputName = XSD::QName.new(Namespace, 'output') +PartName = XSD::QName.new(Namespace, 'part') +PortName = XSD::QName.new(Namespace, 'port') +PortTypeName = XSD::QName.new(Namespace, 'portType') +ServiceName = XSD::QName.new(Namespace, 'service') +TypesName = XSD::QName.new(Namespace, 'types') + +SchemaName = XSD::QName.new(XSD::Namespace, 'schema') + +SOAPAddressName = XSD::QName.new(SOAPBindingNamespace, 'address') +SOAPBindingName = XSD::QName.new(SOAPBindingNamespace, 'binding') +SOAPHeaderName = XSD::QName.new(SOAPBindingNamespace, 'header') +SOAPBodyName = XSD::QName.new(SOAPBindingNamespace, 'body') +SOAPFaultName = XSD::QName.new(SOAPBindingNamespace, 'fault') +SOAPOperationName = XSD::QName.new(SOAPBindingNamespace, 'operation') + +BindingAttrName = XSD::QName.new(nil, 'binding') +ElementAttrName = XSD::QName.new(nil, 'element') +LocationAttrName = XSD::QName.new(nil, 'location') +MessageAttrName = XSD::QName.new(nil, 'message') +NameAttrName = XSD::QName.new(nil, 'name') +NamespaceAttrName = XSD::QName.new(nil, 'namespace') +ParameterOrderAttrName = XSD::QName.new(nil, 'parameterOrder') +TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace') +TypeAttrName = XSD::QName.new(nil, 'type') + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/definitions.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/definitions.rb new file mode 100644 index 00000000..5235037c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/definitions.rb @@ -0,0 +1,250 @@ +# WSDL4R - WSDL definitions. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL + + +class Definitions < Info + attr_reader :name + attr_reader :targetnamespace + attr_reader :imports + + attr_accessor :location + attr_reader :importedschema + + def initialize + super + @name = nil + @targetnamespace = nil + @location = nil + @importedschema = {} + + @types = nil + @imports = [] + @messages = XSD::NamedElements.new + @porttypes = XSD::NamedElements.new + @bindings = XSD::NamedElements.new + @services = XSD::NamedElements.new + + @anontypes = XSD::NamedElements.new + @root = self + end + + def inspect + sprintf("#<%s:0x%x %s>", self.class.name, __id__, @name || '(unnamed)') + end + + def targetnamespace=(targetnamespace) + @targetnamespace = targetnamespace + if @name + @name = XSD::QName.new(@targetnamespace, @name.name) + end + end + + def collect_attributes + result = XSD::NamedElements.new + if @types + @types.schemas.each do |schema| + result.concat(schema.collect_attributes) + end + end + @imports.each do |import| + result.concat(import.content.collect_attributes) + end + result + end + + def collect_elements + result = XSD::NamedElements.new + if @types + @types.schemas.each do |schema| + result.concat(schema.collect_elements) + end + end + @imports.each do |import| + result.concat(import.content.collect_elements) + end + result + end + + def collect_complextypes + result = @anontypes.dup + if @types + @types.schemas.each do |schema| + result.concat(schema.collect_complextypes) + end + end + @imports.each do |import| + result.concat(import.content.collect_complextypes) + end + result + end + + def collect_simpletypes + result = XSD::NamedElements.new + if @types + @types.schemas.each do |schema| + result.concat(schema.collect_simpletypes) + end + end + @imports.each do |import| + result.concat(import.content.collect_simpletypes) + end + result + end + + # ToDo: simpletype must be accepted... + def add_type(complextype) + @anontypes << complextype + end + + def messages + result = @messages.dup + @imports.each do |import| + result.concat(import.content.messages) if self.class === import.content + end + result + end + + def porttypes + result = @porttypes.dup + @imports.each do |import| + result.concat(import.content.porttypes) if self.class === import.content + end + result + end + + def bindings + result = @bindings.dup + @imports.each do |import| + result.concat(import.content.bindings) if self.class === import.content + end + result + end + + def services + result = @services.dup + @imports.each do |import| + result.concat(import.content.services) if self.class === import.content + end + result + end + + def message(name) + message = @messages[name] + return message if message + @imports.each do |import| + message = import.content.message(name) if self.class === import.content + return message if message + end + nil + end + + def porttype(name) + porttype = @porttypes[name] + return porttype if porttype + @imports.each do |import| + porttype = import.content.porttype(name) if self.class === import.content + return porttype if porttype + end + nil + end + + def binding(name) + binding = @bindings[name] + return binding if binding + @imports.each do |import| + binding = import.content.binding(name) if self.class === import.content + return binding if binding + end + nil + end + + def service(name) + service = @services[name] + return service if service + @imports.each do |import| + service = import.content.service(name) if self.class === import.content + return service if service + end + nil + end + + def porttype_binding(name) + binding = @bindings.find { |item| item.type == name } + return binding if binding + @imports.each do |import| + binding = import.content.porttype_binding(name) if self.class === import.content + return binding if binding + end + nil + end + + def parse_element(element) + case element + when ImportName + o = Import.new + @imports << o + o + when TypesName + o = Types.new + @types = o + o + when MessageName + o = Message.new + @messages << o + o + when PortTypeName + o = PortType.new + @porttypes << o + o + when BindingName + o = Binding.new + @bindings << o + o + when ServiceName + o = Service.new + @services << o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + when TargetNamespaceAttrName + self.targetnamespace = value.source + else + nil + end + end + + def self.parse_element(element) + if element == DefinitionsName + Definitions.new + else + nil + end + end + +private + +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/documentation.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/documentation.rb new file mode 100644 index 00000000..3a7fd7d2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/documentation.rb @@ -0,0 +1,32 @@ +# WSDL4R - WSDL SOAP documentation element. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Documentation < Info + def initialize + super + end + + def parse_element(element) + # Accepts any element. + self + end + + def parse_attr(attr, value) + # Accepts any attribute. + true + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/import.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/import.rb new file mode 100644 index 00000000..faf60871 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/import.rb @@ -0,0 +1,80 @@ +# WSDL4R - WSDL import definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/importer' + + +module WSDL + + +class Import < Info + attr_reader :namespace + attr_reader :location + attr_reader :content + + def initialize + super + @namespace = nil + @location = nil + @content = nil + @web_client = nil + end + + def parse_element(element) + case element + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NamespaceAttrName + @namespace = value.source + if @content + @content.targetnamespace = @namespace + end + @namespace + when LocationAttrName + @location = URI.parse(value.source) + if @location.relative? and !parent.location.nil? and + !parent.location.relative? + @location = parent.location + @location + end + if root.importedschema.key?(@location) + @content = root.importedschema[@location] + else + root.importedschema[@location] = nil # placeholder + @content = import(@location) + if @content.is_a?(Definitions) + @content.root = root + if @namespace + @content.targetnamespace = @namespace + end + end + root.importedschema[@location] = @content + end + @location + else + nil + end + end + +private + + def import(location) + Importer.import(location, root) + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/importer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/importer.rb new file mode 100644 index 00000000..481bd81b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/importer.rb @@ -0,0 +1,38 @@ +# WSDL4R - WSDL importer library. +# Copyright (C) 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/xmlSchema/importer' +require 'wsdl/parser' + + +module WSDL + + +class Importer < WSDL::XMLSchema::Importer + def self.import(location, originalroot = nil) + new.import(location, originalroot) + end + +private + + def parse(content, location, originalroot) + opt = { + :location => location, + :originalroot => originalroot + } + begin + WSDL::Parser.new(opt).parse(content) + rescue WSDL::Parser::ParseError + super(content, location, originalroot) + end + end + +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/info.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/info.rb new file mode 100644 index 00000000..ffd90390 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/info.rb @@ -0,0 +1,39 @@ +# WSDL4R - WSDL information base. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module WSDL + + +class Info + attr_accessor :root + attr_accessor :parent + attr_accessor :id + + def initialize + @root = nil + @parent = nil + @id = nil + end + + def inspect + if self.respond_to?(:name) + sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.name) + else + sprintf("#<%s:0x%x>", self.class.name, __id__) + end + end + + def parse_element(element); end # abstract + + def parse_attr(attr, value); end # abstract + + def parse_epilogue; end # abstract +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/message.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/message.rb new file mode 100644 index 00000000..cecc602d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/message.rb @@ -0,0 +1,54 @@ +# WSDL4R - WSDL message definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Message < Info + attr_reader :name # required + attr_reader :parts + + def initialize + super + @name = nil + @parts = [] + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when PartName + o = Part.new + @parts << o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(parent.targetnamespace, value.source) + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/operation.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/operation.rb new file mode 100644 index 00000000..fb7f4a80 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/operation.rb @@ -0,0 +1,130 @@ +# WSDL4R - WSDL operation definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Operation < Info + class NameInfo + attr_reader :op_name + attr_reader :optype_name + attr_reader :parts + def initialize(op_name, optype_name, parts) + @op_name = op_name + @optype_name = optype_name + @parts = parts + end + end + + attr_reader :name # required + attr_reader :parameter_order # optional + attr_reader :input + attr_reader :output + attr_reader :fault + attr_reader :type # required + + def initialize + super + @name = nil + @type = nil + @parameter_order = nil + @input = nil + @output = nil + @fault = [] + end + + def targetnamespace + parent.targetnamespace + end + + def input_info + typename = input.find_message.name + NameInfo.new(@name, typename, inputparts) + end + + def output_info + typename = output.find_message.name + NameInfo.new(@name, typename, outputparts) + end + + def inputparts + sort_parts(input.find_message.parts) + end + + def inputname + XSD::QName.new(targetnamespace, input.name ? input.name.name : @name.name) + end + + def outputparts + sort_parts(output.find_message.parts) + end + + def outputname + XSD::QName.new(targetnamespace, + output.name ? output.name.name : @name.name + 'Response') + end + + def parse_element(element) + case element + when InputName + o = Param.new + @input = o + o + when OutputName + o = Param.new + @output = o + o + when FaultName + o = Param.new + @fault << o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + when TypeAttrName + @type = value + when ParameterOrderAttrName + @parameter_order = value.source.split(/\s+/) + else + nil + end + end + +private + + def sort_parts(parts) + return parts.dup unless parameter_order + result = [] + parameter_order.each do |orderitem| + if (ele = parts.find { |part| part.name == orderitem }) + result << ele + end + end + if result.length == 0 + return parts.dup + end + # result length can be shorter than parts's. + # return part must not be a part of the parameterOrder. + result + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/operationBinding.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/operationBinding.rb new file mode 100644 index 00000000..c2b8cd65 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/operationBinding.rb @@ -0,0 +1,108 @@ +# WSDL4R - WSDL bound operation definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class OperationBinding < Info + attr_reader :name # required + attr_reader :input + attr_reader :output + attr_reader :fault + attr_reader :soapoperation + + def initialize + super + @name = nil + @input = nil + @output = nil + @fault = [] + @soapoperation = nil + end + + def targetnamespace + parent.targetnamespace + end + + def porttype + root.porttype(parent.type) + end + + def find_operation + porttype.operations[@name] or raise RuntimeError.new("#{@name} not found") + end + + def soapoperation_name + if @soapoperation + @soapoperation.input_info.op_name + else + find_operation.name + end + end + + def soapoperation_style + style = nil + if @soapoperation + style = @soapoperation.operation_style + elsif parent.soapbinding + style = parent.soapbinding.style + else + raise TypeError.new("operation style definition not found") + end + style || :document + end + + def soapaction + if @soapoperation + @soapoperation.soapaction + else + nil + end + end + + def parse_element(element) + case element + when InputName + o = Param.new + @input = o + o + when OutputName + o = Param.new + @output = o + o + when FaultName + o = Param.new + @fault << o + o + when SOAPOperationName + o = WSDL::SOAP::Operation.new + @soapoperation = o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/param.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/param.rb new file mode 100644 index 00000000..b6836b7d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/param.rb @@ -0,0 +1,85 @@ +# WSDL4R - WSDL param definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Param < Info + attr_reader :message # required + attr_reader :name # optional but required for fault. + attr_reader :soapbody + attr_reader :soapheader + attr_reader :soapfault + + def initialize + super + @message = nil + @name = nil + @soapbody = nil + @soapheader = [] + @soapfault = nil + end + + def targetnamespace + parent.targetnamespace + end + + def find_message + root.message(@message) or raise RuntimeError.new("#{@message} not found") + end + + def soapbody_use + if @soapbody + @soapbody.use || :literal + else + raise RuntimeError.new("soap:body not found") + end + end + + def parse_element(element) + case element + when SOAPBodyName + o = WSDL::SOAP::Body.new + @soapbody = o + o + when SOAPHeaderName + o = WSDL::SOAP::Header.new + @soapheader << o + o + when SOAPFaultName + o = WSDL::SOAP::Fault.new + @soap_fault = o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when MessageAttrName + if value.namespace.nil? + value = XSD::QName.new(targetnamespace, value.source) + end + @message = value + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/parser.rb new file mode 100644 index 00000000..f96e96ee --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/parser.rb @@ -0,0 +1,163 @@ +# WSDL4R - WSDL XML Instance parser library. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'xsd/ns' +require 'xsd/charset' +require 'xsd/datatypes' +require 'xsd/xmlparser' +require 'wsdl/wsdl' +require 'wsdl/data' +require 'wsdl/xmlSchema/data' +require 'wsdl/soap/data' + + +module WSDL + + +class Parser + include WSDL + + class ParseError < Error; end + class FormatDecodeError < ParseError; end + class UnknownElementError < FormatDecodeError; end + class UnknownAttributeError < FormatDecodeError; end + class UnexpectedElementError < FormatDecodeError; end + class ElementConstraintError < FormatDecodeError; end + class AttributeConstraintError < FormatDecodeError; end + +private + + class ParseFrame + attr_reader :ns + attr_reader :name + attr_accessor :node + + private + + def initialize(ns, name, node) + @ns = ns + @name = name + @node = node + end + end + +public + + def initialize(opt = {}) + @parser = XSD::XMLParser.create_parser(self, opt) + @parsestack = nil + @lastnode = nil + @ignored = {} + @location = opt[:location] + @originalroot = opt[:originalroot] + end + + def parse(string_or_readable) + @parsestack = [] + @lastnode = nil + @textbuf = '' + @parser.do_parse(string_or_readable) + @lastnode + end + + def charset + @parser.charset + end + + def start_element(name, attrs) + lastframe = @parsestack.last + ns = parent = nil + if lastframe + ns = lastframe.ns.clone_ns + parent = lastframe.node + else + ns = XSD::NS.new + parent = nil + end + attrs = XSD::XMLParser.filter_ns(ns, attrs) + node = decode_tag(ns, name, attrs, parent) + @parsestack << ParseFrame.new(ns, name, node) + end + + def characters(text) + lastframe = @parsestack.last + if lastframe + # Need not to be cloned because character does not have attr. + ns = lastframe.ns + decode_text(ns, text) + else + p text if $DEBUG + end + end + + def end_element(name) + lastframe = @parsestack.pop + unless name == lastframe.name + raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'") + end + decode_tag_end(lastframe.ns, lastframe.node) + @lastnode = lastframe.node + end + +private + + def decode_tag(ns, name, attrs, parent) + o = nil + elename = ns.parse(name) + if !parent + if elename == DefinitionsName + o = Definitions.parse_element(elename) + o.location = @location + else + raise UnknownElementError.new("unknown element: #{elename}") + end + o.root = @originalroot if @originalroot # o.root = o otherwise + else + if elename == XMLSchema::AnnotationName + # only the first annotation element is allowed for each xsd element. + o = XMLSchema::Annotation.new + else + o = parent.parse_element(elename) + end + unless o + unless @ignored.key?(elename) + warn("ignored element: #{elename}") + @ignored[elename] = elename + end + o = Documentation.new # which accepts any element. + end + # node could be a pseudo element. pseudo element has its own parent. + o.root = parent.root + o.parent = parent if o.parent.nil? + end + attrs.each do |key, value| + attr_ele = ns.parse(key, true) + value_ele = ns.parse(value, true) + value_ele.source = value # for recovery; value may not be a QName + unless o.parse_attr(attr_ele, value_ele) + unless @ignored.key?(attr_ele) + warn("ignored attr: #{attr_ele}") + @ignored[attr_ele] = attr_ele + end + end + end + o + end + + def decode_tag_end(ns, node) + node.parse_epilogue + end + + def decode_text(ns, text) + @textbuf << text + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/part.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/part.rb new file mode 100644 index 00000000..5dafd4ee --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/part.rb @@ -0,0 +1,52 @@ +# WSDL4R - WSDL part definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Part < Info + attr_reader :name # required + attr_reader :element # optional + attr_reader :type # optional + + def initialize + super + @name = nil + @element = nil + @type = nil + end + + def parse_element(element) + case element + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = value.source + when ElementAttrName + @element = value + when TypeAttrName + @type = value + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/port.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/port.rb new file mode 100644 index 00000000..883cc323 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/port.rb @@ -0,0 +1,84 @@ +# WSDL4R - WSDL port definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Port < Info + attr_reader :name # required + attr_reader :binding # required + attr_reader :soap_address + + def initialize + super + @name = nil + @binding = nil + @soap_address = nil + end + + def targetnamespace + parent.targetnamespace + end + + def porttype + root.porttype(find_binding.type) + end + + def find_binding + root.binding(@binding) or raise RuntimeError.new("#{@binding} not found") + end + + def inputoperation_map + result = {} + find_binding.operations.each do |op_bind| + op_info = op_bind.soapoperation.input_info + result[op_info.op_name] = op_info + end + result + end + + def outputoperation_map + result = {} + find_binding.operations.each do |op_bind| + op_info = op_bind.soapoperation.output_info + result[op_info.op_name] = op_info + end + result + end + + def parse_element(element) + case element + when SOAPAddressName + o = WSDL::SOAP::Address.new + @soap_address = o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + when BindingAttrName + @binding = value + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/portType.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/portType.rb new file mode 100644 index 00000000..03e37690 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/portType.rb @@ -0,0 +1,73 @@ +# WSDL4R - WSDL portType definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL + + +class PortType < Info + attr_reader :name # required + attr_reader :operations + + def targetnamespace + parent.targetnamespace + end + + def initialize + super + @name = nil + @operations = XSD::NamedElements.new + end + + def find_binding + root.bindings.find { |item| item.type == @name } or + raise RuntimeError.new("#{@name} not found") + end + + def locations + bind_name = find_binding.name + result = [] + root.services.each do |service| + service.ports.each do |port| + if port.binding == bind_name + result << port.soap_address.location if port.soap_address + end + end + end + result + end + + def parse_element(element) + case element + when OperationName + o = Operation.new + @operations << o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/service.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/service.rb new file mode 100644 index 00000000..652b1273 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/service.rb @@ -0,0 +1,61 @@ +# WSDL4R - WSDL service definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL + + +class Service < Info + attr_reader :name # required + attr_reader :ports + attr_reader :soap_address + + def initialize + super + @name = nil + @ports = XSD::NamedElements.new + @soap_address = nil + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when PortName + o = Port.new + @ports << o + o + when SOAPAddressName + o = WSDL::SOAP::Address.new + @soap_address = o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + else + nil + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/address.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/address.rb new file mode 100644 index 00000000..0b2b59ca --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/address.rb @@ -0,0 +1,40 @@ +# WSDL4R - WSDL SOAP address definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class Address < Info + attr_reader :location + + def initialize + super + @location = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when LocationAttrName + @location = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/binding.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/binding.rb new file mode 100644 index 00000000..7e15a997 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/binding.rb @@ -0,0 +1,49 @@ +# WSDL4R - WSDL SOAP binding definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class Binding < Info + attr_reader :style + attr_reader :transport + + def initialize + super + @style = nil + @transport = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when StyleAttrName + if ["document", "rpc"].include?(value.source) + @style = value.source.intern + else + raise Parser::AttributeConstraintError.new( + "Unexpected value #{ value }.") + end + when TransportAttrName + @transport = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/body.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/body.rb new file mode 100644 index 00000000..824f8121 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/body.rb @@ -0,0 +1,56 @@ +# WSDL4R - WSDL SOAP body definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class Body < Info + attr_reader :parts + attr_reader :use # required + attr_reader :encodingstyle + attr_reader :namespace + + def initialize + super + @parts = nil + @use = nil + @encodingstyle = nil + @namespace = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when PartsAttrName + @parts = value.source + when UseAttrName + if ['literal', 'encoded'].include?(value.source) + @use = value.source.intern + else + raise RuntimeError.new("unknown use of soap:body: #{value.source}") + end + when EncodingStyleAttrName + @encodingstyle = value.source + when NamespaceAttrName + @namespace = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/cgiStubCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/cgiStubCreator.rb new file mode 100644 index 00000000..2c4dff2f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/cgiStubCreator.rb @@ -0,0 +1,76 @@ +# WSDL4R - Creating CGI stub code from WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/mappingRegistryCreator' +require 'wsdl/soap/methodDefCreator' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class CGIStubCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(service_name) + warn("CGI stub can have only 1 port. Creating stub for the first port... Rests are ignored.") + port = @definitions.service(service_name).ports[0] + dump_porttype(port.porttype.name) + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + methoddef, types = MethodDefCreator.new(@definitions).dump(name) + mr_creator = MappingRegistryCreator.new(@definitions) + c1 = XSD::CodeGen::ClassDef.new(class_name) + c1.def_require("soap/rpc/cgistub") + c1.def_require("soap/mapping/registry") + c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new") + c1.def_code(mr_creator.dump(types)) + c1.def_code <<-EOD +Methods = [ +#{methoddef.gsub(/^/, " ")} +] + EOD + c2 = XSD::CodeGen::ClassDef.new(class_name + "App", + "::SOAP::RPC::CGIStub") + c2.def_method("initialize", "*arg") do + <<-EOD + super(*arg) + servant = #{class_name}.new + #{class_name}::Methods.each do |definitions| + opt = definitions.last + if opt[:request_style] == :document + @router.add_document_operation(servant, *definitions) + else + @router.add_rpc_operation(servant, *definitions) + end + end + self.mapping_registry = #{class_name}::MappingRegistry + self.level = Logger::Severity::ERROR + EOD + end + c1.dump + "\n" + c2.dump + format(<<-EOD) + #{class_name}App.new('app', nil).start + EOD + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/classDefCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/classDefCreator.rb new file mode 100644 index 00000000..aeb67c06 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/classDefCreator.rb @@ -0,0 +1,314 @@ +# WSDL4R - Creating class definition from WSDL +# Copyright (C) 2002, 2003, 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/data' +require 'wsdl/soap/classDefCreatorSupport' +require 'xsd/codegen' + + +module WSDL +module SOAP + + +class ClassDefCreator + include ClassDefCreatorSupport + + def initialize(definitions) + @elements = definitions.collect_elements + @simpletypes = definitions.collect_simpletypes + @complextypes = definitions.collect_complextypes + @faulttypes = nil + if definitions.respond_to?(:collect_faulttypes) + @faulttypes = definitions.collect_faulttypes + end + end + + def dump(type = nil) + result = "require 'xsd/qname'\n" + if type + result = dump_classdef(type.name, type) + else + str = dump_element + unless str.empty? + result << "\n" unless result.empty? + result << str + end + str = dump_complextype + unless str.empty? + result << "\n" unless result.empty? + result << str + end + str = dump_simpletype + unless str.empty? + result << "\n" unless result.empty? + result << str + end + end + result + end + +private + + def dump_element + @elements.collect { |ele| + if ele.local_complextype + dump_classdef(ele.name, ele.local_complextype, + ele.elementform == 'qualified') + elsif ele.local_simpletype + dump_simpletypedef(ele.name, ele.local_simpletype) + else + nil + end + }.compact.join("\n") + end + + def dump_simpletype + @simpletypes.collect { |type| + dump_simpletypedef(type.name, type) + }.compact.join("\n") + end + + def dump_complextype + @complextypes.collect { |type| + case type.compoundtype + when :TYPE_STRUCT, :TYPE_EMPTY + dump_classdef(type.name, type) + when :TYPE_ARRAY + dump_arraydef(type) + when :TYPE_SIMPLE + dump_simpleclassdef(type) + when :TYPE_MAP + # mapped as a general Hash + nil + else + raise RuntimeError.new( + "unknown kind of complexContent: #{type.compoundtype}") + end + }.compact.join("\n") + end + + def dump_simpletypedef(qname, simpletype) + if !simpletype.restriction or simpletype.restriction.enumeration.empty? + return nil + end + c = XSD::CodeGen::ModuleDef.new(create_class_name(qname)) + c.comment = "#{qname}" + const = {} + simpletype.restriction.enumeration.each do |value| + constname = safeconstname(value) + const[constname] ||= 0 + if (const[constname] += 1) > 1 + constname += "_#{const[constname]}" + end + c.def_const(constname, ndq(value)) + end + c.dump + end + + def dump_simpleclassdef(type_or_element) + qname = type_or_element.name + base = create_class_name(type_or_element.simplecontent.base) + c = XSD::CodeGen::ClassDef.new(create_class_name(qname), base) + c.comment = "#{qname}" + c.dump + end + + def dump_classdef(qname, typedef, qualified = false) + if @faulttypes and @faulttypes.index(qname) + c = XSD::CodeGen::ClassDef.new(create_class_name(qname), + '::StandardError') + else + c = XSD::CodeGen::ClassDef.new(create_class_name(qname)) + end + c.comment = "#{qname}" + c.def_classvar('schema_type', ndq(qname.name)) + c.def_classvar('schema_ns', ndq(qname.namespace)) + c.def_classvar('schema_qualified', dq('true')) if qualified + schema_element = [] + init_lines = '' + params = [] + typedef.each_element do |element| + if element.type == XSD::AnyTypeName + type = nil + elsif klass = element_basetype(element) + type = klass.name + elsif element.type + type = create_class_name(element.type) + else + type = nil # means anyType. + # do we define a class for local complexType from it's name? + # type = create_class_name(element.name) + # + # + # + # + # + end + name = name_element(element).name + attrname = safemethodname?(name) ? name : safemethodname(name) + varname = safevarname(name) + c.def_attr(attrname, true, varname) + init_lines << "@#{varname} = #{varname}\n" + if element.map_as_array? + params << "#{varname} = []" + type << '[]' if type + else + params << "#{varname} = nil" + end + # nil means @@schema_ns + varname + eleqname = + (varname == name && element.name.namespace == qname.namespace) ? + nil : element.name + schema_element << [varname, eleqname, type] + end + unless typedef.attributes.empty? + define_attribute(c, typedef.attributes) + init_lines << "@__xmlattr = {}\n" + end + c.def_classvar('schema_element', + '[' + + schema_element.collect { |varname, name, type| + '[' + + ( + if name + varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']' + else + varname.dump + ', ' + ndq(type) + end + ) + + ']' + }.join(', ') + + ']' + ) + c.def_method('initialize', *params) do + init_lines + end + c.dump + end + + def element_basetype(ele) + if klass = basetype_class(ele.type) + klass + elsif ele.local_simpletype + basetype_class(ele.local_simpletype.base) + else + nil + end + end + + def attribute_basetype(attr) + if klass = basetype_class(attr.type) + klass + elsif attr.local_simpletype + basetype_class(attr.local_simpletype.base) + else + nil + end + end + + def basetype_class(type) + return nil if type.nil? + if simpletype = @simpletypes[type] + basetype_mapped_class(simpletype.base) + else + basetype_mapped_class(type) + end + end + + def define_attribute(c, attributes) + schema_attribute = [] + attributes.each do |attribute| + name = name_attribute(attribute) + if klass = attribute_basetype(attribute) + type = klass.name + else + type = nil + end + methodname = safemethodname('xmlattr_' + name.name) + c.def_method(methodname) do <<-__EOD__ + (@__xmlattr ||= {})[#{dqname(name)}] + __EOD__ + end + c.def_method(methodname + '=', 'value') do <<-__EOD__ + (@__xmlattr ||= {})[#{dqname(name)}] = value + __EOD__ + end + schema_attribute << [name, type] + end + c.def_classvar('schema_attribute', + '{' + + schema_attribute.collect { |name, type| + dqname(name) + ' => ' + ndq(type) + }.join(', ') + + '}' + ) + end + + def name_element(element) + return element.name if element.name + return element.ref if element.ref + raise RuntimeError.new("cannot define name of #{element}") + end + + def name_attribute(attribute) + return attribute.name if attribute.name + return attribute.ref if attribute.ref + raise RuntimeError.new("cannot define name of #{attribute}") + end + + DEFAULT_ITEM_NAME = XSD::QName.new(nil, 'item') + + def dump_arraydef(complextype) + qname = complextype.name + c = XSD::CodeGen::ClassDef.new(create_class_name(qname), '::Array') + c.comment = "#{qname}" + child_type = complextype.child_type + c.def_classvar('schema_type', ndq(child_type.name)) + c.def_classvar('schema_ns', ndq(child_type.namespace)) + child_element = complextype.find_aryelement + schema_element = [] + if child_type == XSD::AnyTypeName + type = nil + elsif child_element and (klass = element_basetype(child_element)) + type = klass.name + elsif child_type + type = create_class_name(child_type) + else + type = nil + end + if child_element + if child_element.map_as_array? + type << '[]' if type + end + child_element_name = child_element.name + else + child_element_name = DEFAULT_ITEM_NAME + end + schema_element << [child_element_name.name, child_element_name, type] + c.def_classvar('schema_element', + '[' + + schema_element.collect { |varname, name, type| + '[' + + ( + if name + varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']' + else + varname.dump + ', ' + ndq(type) + end + ) + + ']' + }.join(', ') + + ']' + ) + c.dump + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/classDefCreatorSupport.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/classDefCreatorSupport.rb new file mode 100644 index 00000000..8f335653 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/classDefCreatorSupport.rb @@ -0,0 +1,126 @@ +# WSDL4R - Creating class code support from WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'soap/mapping' +require 'soap/mapping/typeMap' +require 'xsd/codegen/gensupport' + + +module WSDL +module SOAP + + +module ClassDefCreatorSupport + include XSD::CodeGen::GenSupport + + def create_class_name(qname) + if klass = basetype_mapped_class(qname) + ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass).name + else + safeconstname(qname.name) + end + end + + def basetype_mapped_class(name) + ::SOAP::TypeMap[name] + end + + def dump_method_signature(operation) + name = operation.name.name + input = operation.input + output = operation.output + fault = operation.fault + signature = "#{ name }#{ dump_inputparam(input) }" + str = <<__EOD__ +# SYNOPSIS +# #{name}#{dump_inputparam(input)} +# +# ARGS +#{dump_inout_type(input).chomp} +# +# RETURNS +#{dump_inout_type(output).chomp} +# +__EOD__ + unless fault.empty? + faultstr = (fault.collect { |f| dump_inout_type(f).chomp }).join(', ') + str <<<<__EOD__ +# RAISES +# #{faultstr} +# +__EOD__ + end + str + end + + def dq(ele) + ele.dump + end + + def ndq(ele) + ele.nil? ? 'nil' : dq(ele) + end + + def sym(ele) + ':' + ele + end + + def dqname(qname) + qname.dump + end + +private + + def dump_inout_type(param) + if param + message = param.find_message + params = "" + message.parts.each do |part| + name = safevarname(part.name) + if part.type + typename = safeconstname(part.type.name) + params << add_at("# #{name}", "#{typename} - #{part.type}\n", 20) + elsif part.element + typename = safeconstname(part.element.name) + params << add_at("# #{name}", "#{typename} - #{part.element}\n", 20) + end + end + unless params.empty? + return params + end + end + "# N/A\n" + end + + def dump_inputparam(input) + message = input.find_message + params = "" + message.parts.each do |part| + params << ", " unless params.empty? + params << safevarname(part.name) + end + if params.empty? + "" + else + "(#{ params })" + end + end + + def add_at(base, str, pos) + if base.size >= pos + base + ' ' + str + else + base + ' ' * (pos - base.size) + str + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/clientSkeltonCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/clientSkeltonCreator.rb new file mode 100644 index 00000000..916f0d4d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/clientSkeltonCreator.rb @@ -0,0 +1,78 @@ +# WSDL4R - Creating client skelton code from WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class ClientSkeltonCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(service_name) + result = "" + @definitions.service(service_name).ports.each do |port| + result << dump_porttype(port.porttype.name) + result << "\n" + end + result + end + +private + + def dump_porttype(name) + drv_name = create_class_name(name) + + result = "" + result << <<__EOD__ +endpoint_url = ARGV.shift +obj = #{ drv_name }.new(endpoint_url) + +# run ruby with -d to see SOAP wiredumps. +obj.wiredump_dev = STDERR if $DEBUG + +__EOD__ + @definitions.porttype(name).operations.each do |operation| + result << dump_method_signature(operation) + result << dump_input_init(operation.input) << "\n" + result << dump_operation(operation) << "\n\n" + end + result + end + + def dump_operation(operation) + name = operation.name + input = operation.input + "puts obj.#{ safemethodname(name.name) }#{ dump_inputparam(input) }" + end + + def dump_input_init(input) + result = input.find_message.parts.collect { |part| + safevarname(part.name) + }.join(" = ") + if result.empty? + "" + else + result << " = nil" + end + result + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/complexType.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/complexType.rb new file mode 100644 index 00000000..b2e13d05 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/complexType.rb @@ -0,0 +1,161 @@ +# WSDL4R - SOAP complexType definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/xmlSchema/complexType' +require 'soap/mapping' + + +module WSDL +module XMLSchema + + +class ComplexType < Info + def compoundtype + @compoundtype ||= check_type + end + + def check_type + if content + if attributes.empty? and + content.elements.size == 1 and content.elements[0].maxoccurs != '1' + if name == ::SOAP::Mapping::MapQName + :TYPE_MAP + else + :TYPE_ARRAY + end + else + :TYPE_STRUCT + end + elsif complexcontent + if complexcontent.base == ::SOAP::ValueArrayName + :TYPE_ARRAY + else + complexcontent.basetype.check_type + end + elsif simplecontent + :TYPE_SIMPLE + elsif !attributes.empty? + :TYPE_STRUCT + else # empty complexType definition (seen in partner.wsdl of salesforce) + :TYPE_EMPTY + end + end + + def child_type(name = nil) + case compoundtype + when :TYPE_STRUCT + if ele = find_element(name) + ele.type + elsif ele = find_element_by_name(name.name) + ele.type + end + when :TYPE_ARRAY + @contenttype ||= content_arytype + when :TYPE_MAP + item_ele = find_element_by_name("item") or + raise RuntimeError.new("'item' element not found in Map definition.") + content = item_ele.local_complextype or + raise RuntimeError.new("No complexType definition for 'item'.") + if ele = content.find_element(name) + ele.type + elsif ele = content.find_element_by_name(name.name) + ele.type + end + else + raise NotImplementedError.new("Unknown kind of complexType.") + end + end + + def child_defined_complextype(name) + ele = nil + case compoundtype + when :TYPE_STRUCT, :TYPE_MAP + unless ele = find_element(name) + if name.namespace.nil? + ele = find_element_by_name(name.name) + end + end + when :TYPE_ARRAY + if content.elements.size == 1 + ele = content.elements[0] + else + raise RuntimeError.new("Assert: must not reach.") + end + else + raise RuntimeError.new("Assert: Not implemented.") + end + unless ele + raise RuntimeError.new("Cannot find #{name} as a children of #{@name}.") + end + ele.local_complextype + end + + def find_arytype + unless compoundtype == :TYPE_ARRAY + raise RuntimeError.new("Assert: not for array") + end + if complexcontent + complexcontent.attributes.each do |attribute| + if attribute.ref == ::SOAP::AttrArrayTypeName + return attribute.arytype + end + end + if check_array_content(complexcontent.content) + return element_simpletype(complexcontent.content.elements[0]) + end + elsif check_array_content(content) + return element_simpletype(content.elements[0]) + end + raise RuntimeError.new("Assert: Unknown array definition.") + end + + def find_aryelement + unless compoundtype == :TYPE_ARRAY + raise RuntimeError.new("Assert: not for array") + end + if complexcontent + if check_array_content(complexcontent.content) + return complexcontent.content.elements[0] + end + elsif check_array_content(content) + return content.elements[0] + end + nil # use default item name + end + +private + + def element_simpletype(element) + if element.type + element.type + elsif element.local_simpletype + element.local_simpletype.base + else + nil + end + end + + def check_array_content(content) + content and content.elements.size == 1 and + content.elements[0].maxoccurs != '1' + end + + def content_arytype + if arytype = find_arytype + ns = arytype.namespace + name = arytype.name.sub(/\[(?:,)*\]$/, '') + XSD::QName.new(ns, name) + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/data.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/data.rb new file mode 100644 index 00000000..48512d37 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/data.rb @@ -0,0 +1,42 @@ +# WSDL4R - WSDL SOAP binding data definitions. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'wsdl/soap/definitions' +require 'wsdl/soap/binding' +require 'wsdl/soap/operation' +require 'wsdl/soap/body' +require 'wsdl/soap/element' +require 'wsdl/soap/header' +require 'wsdl/soap/headerfault' +require 'wsdl/soap/fault' +require 'wsdl/soap/address' +require 'wsdl/soap/complexType' + + +module WSDL +module SOAP + + +HeaderFaultName = XSD::QName.new(SOAPBindingNamespace, 'headerfault') + +LocationAttrName = XSD::QName.new(nil, 'location') +StyleAttrName = XSD::QName.new(nil, 'style') +TransportAttrName = XSD::QName.new(nil, 'transport') +UseAttrName = XSD::QName.new(nil, 'use') +PartsAttrName = XSD::QName.new(nil, 'parts') +PartAttrName = XSD::QName.new(nil, 'part') +NameAttrName = XSD::QName.new(nil, 'name') +MessageAttrName = XSD::QName.new(nil, 'message') +EncodingStyleAttrName = XSD::QName.new(nil, 'encodingStyle') +NamespaceAttrName = XSD::QName.new(nil, 'namespace') +SOAPActionAttrName = XSD::QName.new(nil, 'soapAction') + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/definitions.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/definitions.rb new file mode 100644 index 00000000..b014d5af --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/definitions.rb @@ -0,0 +1,149 @@ +# WSDL4R - WSDL additional definitions for SOAP. +# Copyright (C) 2002-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' +require 'soap/mapping' + + +module WSDL + + +class Definitions < Info + def self.soap_rpc_complextypes + types = XSD::NamedElements.new + types << array_complextype + types << fault_complextype + types << exception_complextype + types + end + + def self.array_complextype + type = XMLSchema::ComplexType.new(::SOAP::ValueArrayName) + type.complexcontent = XMLSchema::ComplexContent.new + type.complexcontent.base = ::SOAP::ValueArrayName + attr = XMLSchema::Attribute.new + attr.ref = ::SOAP::AttrArrayTypeName + anytype = XSD::AnyTypeName.dup + anytype.name += '[]' + attr.arytype = anytype + type.complexcontent.attributes << attr + type + end + +=begin + + + + + + + + +=end + def self.fault_complextype + type = XMLSchema::ComplexType.new(::SOAP::EleFaultName) + faultcode = XMLSchema::Element.new(::SOAP::EleFaultCodeName, XSD::XSDQName::Type) + faultstring = XMLSchema::Element.new(::SOAP::EleFaultStringName, XSD::XSDString::Type) + faultactor = XMLSchema::Element.new(::SOAP::EleFaultActorName, XSD::XSDAnyURI::Type) + faultactor.minoccurs = 0 + detail = XMLSchema::Element.new(::SOAP::EleFaultDetailName, XSD::AnyTypeName) + detail.minoccurs = 0 + type.all_elements = [faultcode, faultstring, faultactor, detail] + type.final = 'extension' + type + end + + def self.exception_complextype + type = XMLSchema::ComplexType.new(XSD::QName.new( + ::SOAP::Mapping::RubyCustomTypeNamespace, 'SOAPException')) + excn_name = XMLSchema::Element.new(XSD::QName.new(nil, 'excn_type_name'), XSD::XSDString::Type) + cause = XMLSchema::Element.new(XSD::QName.new(nil, 'cause'), XSD::AnyTypeName) + backtrace = XMLSchema::Element.new(XSD::QName.new(nil, 'backtrace'), ::SOAP::ValueArrayName) + message = XMLSchema::Element.new(XSD::QName.new(nil, 'message'), XSD::XSDString::Type) + type.all_elements = [excn_name, cause, backtrace, message] + type + end + + def soap_rpc_complextypes(binding) + types = rpc_operation_complextypes(binding) + types + self.class.soap_rpc_complextypes + end + + def collect_faulttypes + result = [] + collect_fault_messages.each do |name| + faultparts = message(name).parts + if faultparts.size != 1 + raise RuntimeError.new("expecting fault message to have only 1 part") + end + if result.index(faultparts[0].type).nil? + result << faultparts[0].type + end + end + result + end + +private + + def collect_fault_messages + result = [] + porttypes.each do |porttype| + porttype.operations.each do |operation| + operation.fault.each do |fault| + if result.index(fault.message).nil? + result << fault.message + end + end + end + end + result + end + + def rpc_operation_complextypes(binding) + types = XSD::NamedElements.new + binding.operations.each do |op_bind| + if op_bind_rpc?(op_bind) + operation = op_bind.find_operation + if op_bind.input + type = XMLSchema::ComplexType.new(op_bind.soapoperation_name) + message = messages[operation.input.message] + type.sequence_elements = elements_from_message(message) + types << type + end + if op_bind.output + type = XMLSchema::ComplexType.new(operation.outputname) + message = messages[operation.output.message] + type.sequence_elements = elements_from_message(message) + types << type + end + end + end + types + end + + def op_bind_rpc?(op_bind) + op_bind.soapoperation_style == :rpc + end + + def elements_from_message(message) + message.parts.collect { |part| + if part.element + collect_elements[part.element] + elsif part.name.nil? or part.type.nil? + raise RuntimeError.new("part of a message must be an element or typed") + else + qname = XSD::QName.new(nil, part.name) + XMLSchema::Element.new(qname, part.type) + end + } + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/driverCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/driverCreator.rb new file mode 100644 index 00000000..eba7c158 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/driverCreator.rb @@ -0,0 +1,95 @@ +# WSDL4R - Creating driver code from WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/mappingRegistryCreator' +require 'wsdl/soap/methodDefCreator' +require 'wsdl/soap/classDefCreatorSupport' +require 'xsd/codegen' + + +module WSDL +module SOAP + + +class DriverCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(porttype = nil) + if porttype.nil? + result = "" + @definitions.porttypes.each do |type| + result << dump_porttype(type.name) + result << "\n" + end + else + result = dump_porttype(porttype) + end + result + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + methoddef, types = MethodDefCreator.new(@definitions).dump(name) + mr_creator = MappingRegistryCreator.new(@definitions) + binding = @definitions.bindings.find { |item| item.type == name } + return '' unless binding.soapbinding # not a SOAP binding + address = @definitions.porttype(name).locations[0] + + c = XSD::CodeGen::ClassDef.new(class_name, "::SOAP::RPC::Driver") + c.def_require("soap/rpc/driver") + c.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new") + c.def_const("DefaultEndpointUrl", ndq(address)) + c.def_code(mr_creator.dump(types)) + c.def_code <<-EOD +Methods = [ +#{methoddef.gsub(/^/, " ")} +] + EOD + c.def_method("initialize", "endpoint_url = nil") do + <<-EOD + endpoint_url ||= DefaultEndpointUrl + super(endpoint_url, nil) + self.mapping_registry = MappingRegistry + init_methods + EOD + end + c.def_privatemethod("init_methods") do + <<-EOD + Methods.each do |definitions| + opt = definitions.last + if opt[:request_style] == :document + add_document_operation(*definitions) + else + add_rpc_operation(*definitions) + qname = definitions[0] + name = definitions[2] + if qname.name != name and qname.name.capitalize == name.capitalize + ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg| + __send__(name, *arg) + end + end + end + end + EOD + end + c.dump + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/element.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/element.rb new file mode 100644 index 00000000..0fa6017c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/element.rb @@ -0,0 +1,28 @@ +# WSDL4R - XMLSchema element definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/xmlSchema/element' + + +module WSDL +module XMLSchema + + +class Element < Info + def map_as_array? + maxoccurs != '1' + end + + def attributes + @local_complextype.attributes + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/fault.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/fault.rb new file mode 100644 index 00000000..2862b659 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/fault.rb @@ -0,0 +1,56 @@ +# WSDL4R - WSDL SOAP body definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class Fault < Info + attr_reader :name # required + attr_reader :use # required + attr_reader :encodingstyle + attr_reader :namespace + + def initialize + super + @name = nil + @use = nil + @encodingstyle = nil + @namespace = nil + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + when UseAttrName + @use = value.source + when EncodingStyleAttrName + @encodingstyle = value.source + when NamespaceAttrName + @namespace = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/header.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/header.rb new file mode 100644 index 00000000..8d7c4e9d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/header.rb @@ -0,0 +1,86 @@ +# WSDL4R - WSDL SOAP body definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class Header < Info + attr_reader :headerfault + + attr_reader :message # required + attr_reader :part # required + attr_reader :use # required + attr_reader :encodingstyle + attr_reader :namespace + + def initialize + super + @message = nil + @part = nil + @use = nil + @encodingstyle = nil + @namespace = nil + @headerfault = nil + end + + def targetnamespace + parent.targetnamespace + end + + def find_message + root.message(@message) or raise RuntimeError.new("#{@message} not found") + end + + def find_part + find_message.parts.each do |part| + if part.name == @part + return part + end + end + raise RuntimeError.new("#{@part} not found") + end + + def parse_element(element) + case element + when HeaderFaultName + o = WSDL::SOAP::HeaderFault.new + @headerfault = o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when MessageAttrName + if value.namespace.nil? + value = XSD::QName.new(targetnamespace, value.source) + end + @message = value + when PartAttrName + @part = value.source + when UseAttrName + @use = value.source + when EncodingStyleAttrName + @encodingstyle = value.source + when NamespaceAttrName + @namespace = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/headerfault.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/headerfault.rb new file mode 100644 index 00000000..d6b14f26 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/headerfault.rb @@ -0,0 +1,56 @@ +# WSDL4R - WSDL SOAP body definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class HeaderFault < Info + attr_reader :message # required + attr_reader :part # required + attr_reader :use # required + attr_reader :encodingstyle + attr_reader :namespace + + def initialize + super + @message = nil + @part = nil + @use = nil + @encodingstyle = nil + @namespace = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when MessageAttrName + @message = value + when PartAttrName + @part = value.source + when UseAttrName + @use = value.source + when EncodingStyleAttrName + @encodingstyle = value.source + when NamespaceAttrName + @namespace = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/mappingRegistryCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/mappingRegistryCreator.rb new file mode 100644 index 00000000..8669339c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/mappingRegistryCreator.rb @@ -0,0 +1,92 @@ +# WSDL4R - Creating MappingRegistry code from WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class MappingRegistryCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + @complextypes = @definitions.collect_complextypes + @types = nil + end + + def dump(types) + @types = types + map_cache = [] + map = "" + @types.each do |type| + if map_cache.index(type).nil? + map_cache << type + if type.namespace != XSD::Namespace + if typemap = dump_typemap(type) + map << typemap + end + end + end + end + return map + end + +private + + def dump_typemap(type) + if definedtype = @complextypes[type] + case definedtype.compoundtype + when :TYPE_STRUCT + dump_struct_typemap(definedtype) + when :TYPE_ARRAY + dump_array_typemap(definedtype) + when :TYPE_MAP, :TYPE_EMPTY + nil + else + raise NotImplementedError.new("must not reach here") + end + end + end + + def dump_struct_typemap(definedtype) + ele = definedtype.name + return <<__EOD__ +MappingRegistry.set( + #{create_class_name(ele)}, + ::SOAP::SOAPStruct, + ::SOAP::Mapping::Registry::TypedStructFactory, + { :type => #{dqname(ele)} } +) +__EOD__ + end + + def dump_array_typemap(definedtype) + ele = definedtype.name + arytype = definedtype.find_arytype || XSD::AnyTypeName + type = XSD::QName.new(arytype.namespace, arytype.name.sub(/\[(?:,)*\]$/, '')) + @types << type + return <<__EOD__ +MappingRegistry.set( + #{create_class_name(ele)}, + ::SOAP::SOAPArray, + ::SOAP::Mapping::Registry::TypedArrayFactory, + { :type => #{dqname(type)} } +) +__EOD__ + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/methodDefCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/methodDefCreator.rb new file mode 100644 index 00000000..f3ffadbe --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/methodDefCreator.rb @@ -0,0 +1,228 @@ +# WSDL4R - Creating driver code from WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' +require 'soap/rpc/element' + + +module WSDL +module SOAP + + +class MethodDefCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + @simpletypes = @definitions.collect_simpletypes + @complextypes = @definitions.collect_complextypes + @elements = @definitions.collect_elements + @types = [] + end + + def dump(porttype) + @types.clear + result = "" + operations = @definitions.porttype(porttype).operations + binding = @definitions.porttype_binding(porttype) + operations.each do |operation| + op_bind = binding.operations[operation.name] + next unless op_bind # no binding is defined + next unless op_bind.soapoperation # not a SOAP operation binding + result << ",\n" unless result.empty? + result << dump_method(operation, op_bind).chomp + end + return result, @types + end + + def collect_rpcparameter(operation) + result = operation.inputparts.collect { |part| + collect_type(part.type) + param_set(::SOAP::RPC::SOAPMethod::IN, part.name, rpcdefinedtype(part)) + } + outparts = operation.outputparts + if outparts.size > 0 + retval = outparts[0] + collect_type(retval.type) + result << param_set(::SOAP::RPC::SOAPMethod::RETVAL, retval.name, + rpcdefinedtype(retval)) + cdr(outparts).each { |part| + collect_type(part.type) + result << param_set(::SOAP::RPC::SOAPMethod::OUT, part.name, + rpcdefinedtype(part)) + } + end + result + end + + def collect_documentparameter(operation) + param = [] + operation.inputparts.each do |input| + param << param_set(::SOAP::RPC::SOAPMethod::IN, input.name, + documentdefinedtype(input), elementqualified(input)) + end + operation.outputparts.each do |output| + param << param_set(::SOAP::RPC::SOAPMethod::OUT, output.name, + documentdefinedtype(output), elementqualified(output)) + end + param + end + +private + + def dump_method(operation, binding) + name = safemethodname(operation.name.name) + name_as = operation.name.name + style = binding.soapoperation_style + inputuse = binding.input.soapbody_use + outputuse = binding.output.soapbody_use + namespace = binding.input.soapbody.namespace + if style == :rpc + qname = XSD::QName.new(namespace, name_as) + paramstr = param2str(collect_rpcparameter(operation)) + else + qname = nil + paramstr = param2str(collect_documentparameter(operation)) + end + if paramstr.empty? + paramstr = '[]' + else + paramstr = "[ " << paramstr.split(/\r?\n/).join("\n ") << " ]" + end + definitions = <<__EOD__ +#{ndq(binding.soapaction)}, + #{dq(name)}, + #{paramstr}, + { :request_style => #{sym(style.id2name)}, :request_use => #{sym(inputuse.id2name)}, + :response_style => #{sym(style.id2name)}, :response_use => #{sym(outputuse.id2name)} } +__EOD__ + if style == :rpc + return <<__EOD__ +[ #{qname.dump}, + #{definitions}] +__EOD__ + else + return <<__EOD__ +[ #{definitions}] +__EOD__ + end + end + + def rpcdefinedtype(part) + if mapped = basetype_mapped_class(part.type) + ['::' + mapped.name] + elsif definedtype = @simpletypes[part.type] + ['::' + basetype_mapped_class(definedtype.base).name] + elsif definedtype = @elements[part.element] + #['::SOAP::SOAPStruct', part.element.namespace, part.element.name] + ['nil', part.element.namespace, part.element.name] + elsif definedtype = @complextypes[part.type] + case definedtype.compoundtype + when :TYPE_STRUCT, :TYPE_EMPTY # ToDo: empty should be treated as void. + type = create_class_name(part.type) + [type, part.type.namespace, part.type.name] + when :TYPE_MAP + [Hash.name, part.type.namespace, part.type.name] + when :TYPE_ARRAY + arytype = definedtype.find_arytype || XSD::AnyTypeName + ns = arytype.namespace + name = arytype.name.sub(/\[(?:,)*\]$/, '') + type = create_class_name(XSD::QName.new(ns, name)) + [type + '[]', ns, name] + else + raise NotImplementedError.new("must not reach here") + end + else + raise RuntimeError.new("part: #{part.name} cannot be resolved") + end + end + + def documentdefinedtype(part) + if mapped = basetype_mapped_class(part.type) + ['::' + mapped.name, nil, part.name] + elsif definedtype = @simpletypes[part.type] + ['::' + basetype_mapped_class(definedtype.base).name, nil, part.name] + elsif definedtype = @elements[part.element] + ['::SOAP::SOAPElement', part.element.namespace, part.element.name] + elsif definedtype = @complextypes[part.type] + ['::SOAP::SOAPElement', part.type.namespace, part.type.name] + else + raise RuntimeError.new("part: #{part.name} cannot be resolved") + end + end + + def elementqualified(part) + if mapped = basetype_mapped_class(part.type) + false + elsif definedtype = @simpletypes[part.type] + false + elsif definedtype = @elements[part.element] + definedtype.elementform == 'qualified' + elsif definedtype = @complextypes[part.type] + false + else + raise RuntimeError.new("part: #{part.name} cannot be resolved") + end + end + + def param_set(io_type, name, type, ele = nil) + [io_type, name, type, ele] + end + + def collect_type(type) + # ignore inline type definition. + return if type.nil? + return if @types.include?(type) + @types << type + return unless @complextypes[type] + @complextypes[type].each_element do |element| + collect_type(element.type) + end + end + + def param2str(params) + params.collect { |param| + io, name, type, ele = param + unless ele.nil? + "[#{dq(io)}, #{dq(name)}, #{type2str(type)}, #{ele2str(ele)}]" + else + "[#{dq(io)}, #{dq(name)}, #{type2str(type)}]" + end + }.join(",\n") + end + + def type2str(type) + if type.size == 1 + "[#{dq(type[0])}]" + else + "[#{dq(type[0])}, #{ndq(type[1])}, #{dq(type[2])}]" + end + end + + def ele2str(ele) + qualified = ele + if qualified + "true" + else + "false" + end + end + + def cdr(ary) + result = ary.dup + result.shift + result + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/operation.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/operation.rb new file mode 100644 index 00000000..502d34a0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/operation.rb @@ -0,0 +1,122 @@ +# WSDL4R - WSDL SOAP operation definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module SOAP + + +class Operation < Info + class OperationInfo + attr_reader :style + attr_reader :op_name + attr_reader :optype_name + attr_reader :headerparts + attr_reader :bodyparts + attr_reader :faultpart + attr_reader :soapaction + + def initialize(style, op_name, optype_name, headerparts, bodyparts, faultpart, soapaction) + @style = style + @op_name = op_name + @optype_name = optype_name + @headerparts = headerparts + @bodyparts = bodyparts + @faultpart = faultpart + @soapaction = soapaction + end + end + + attr_reader :soapaction + attr_reader :style + + def initialize + super + @soapaction = nil + @style = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when StyleAttrName + if ["document", "rpc"].include?(value.source) + @style = value.source.intern + else + raise Parser::AttributeConstraintError.new( + "Unexpected value #{ value }.") + end + when SOAPActionAttrName + @soapaction = value.source + else + nil + end + end + + def input_info + name_info = parent.find_operation.input_info + param_info(name_info, parent.input) + end + + def output_info + name_info = parent.find_operation.output_info + param_info(name_info, parent.output) + end + + def operation_style + return @style if @style + if parent_binding.soapbinding + return parent_binding.soapbinding.style + end + nil + end + +private + + def parent_binding + parent.parent + end + + def param_info(name_info, param) + op_name = name_info.op_name + optype_name = name_info.optype_name + + soapheader = param.soapheader + headerparts = soapheader.collect { |item| item.find_part } + + soapbody = param.soapbody + if soapbody.encodingstyle and + soapbody.encodingstyle != ::SOAP::EncodingNamespace + raise NotImplementedError.new( + "EncodingStyle '#{ soapbody.encodingstyle }' not supported.") + end + if soapbody.namespace + op_name = XSD::QName.new(soapbody.namespace, op_name.name) + end + if soapbody.parts + target = soapbody.parts.split(/\s+/) + bodyparts = name_info.parts.find_all { |part| + target.include?(part.name) + } + else + bodyparts = name_info.parts + end + + faultpart = nil + OperationInfo.new(operation_style, op_name, optype_name, headerparts, bodyparts, faultpart, parent.soapaction) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/servantSkeltonCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/servantSkeltonCreator.rb new file mode 100644 index 00000000..88294ffe --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/servantSkeltonCreator.rb @@ -0,0 +1,67 @@ +# WSDL4R - Creating servant skelton code from WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/classDefCreatorSupport' +require 'xsd/codegen' + + +module WSDL +module SOAP + + +class ServantSkeltonCreator + include ClassDefCreatorSupport + include XSD::CodeGen::GenSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(porttype = nil) + if porttype.nil? + result = "" + @definitions.porttypes.each do |type| + result << dump_porttype(type.name) + result << "\n" + end + else + result = dump_porttype(porttype) + end + result + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + c = XSD::CodeGen::ClassDef.new(class_name) + operations = @definitions.porttype(name).operations + operations.each do |operation| + name = safemethodname(operation.name.name) + input = operation.input + params = input.find_message.parts.collect { |part| + safevarname(part.name) + } + m = XSD::CodeGen::MethodDef.new(name, params) do <<-EOD + p [#{params.join(", ")}] + raise NotImplementedError.new + EOD + end + m.comment = dump_method_signature(operation) + c.add_method(m) + end + c.dump + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/standaloneServerStubCreator.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/standaloneServerStubCreator.rb new file mode 100644 index 00000000..0b751b51 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/standaloneServerStubCreator.rb @@ -0,0 +1,85 @@ +# WSDL4R - Creating standalone server stub code from WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/soap/mappingRegistryCreator' +require 'wsdl/soap/methodDefCreator' +require 'wsdl/soap/classDefCreatorSupport' + + +module WSDL +module SOAP + + +class StandaloneServerStubCreator + include ClassDefCreatorSupport + + attr_reader :definitions + + def initialize(definitions) + @definitions = definitions + end + + def dump(service_name) + warn("- Standalone stub can have only 1 port for now. So creating stub for the first port and rests are ignored.") + warn("- Standalone server stub ignores port location defined in WSDL. Location is http://localhost:10080/ by default. Generated client from WSDL must be configured to point this endpoint manually.") + port = @definitions.service(service_name).ports[0] + dump_porttype(port.porttype.name) + end + +private + + def dump_porttype(name) + class_name = create_class_name(name) + methoddef, types = MethodDefCreator.new(@definitions).dump(name) + mr_creator = MappingRegistryCreator.new(@definitions) + + c1 = XSD::CodeGen::ClassDef.new(class_name) + c1.def_require("soap/rpc/standaloneServer") + c1.def_require("soap/mapping/registry") + c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new") + c1.def_code(mr_creator.dump(types)) + c1.def_code <<-EOD +Methods = [ +#{methoddef.gsub(/^/, " ")} +] + EOD + c2 = XSD::CodeGen::ClassDef.new(class_name + "App", + "::SOAP::RPC::StandaloneServer") + c2.def_method("initialize", "*arg") do + <<-EOD + super(*arg) + servant = #{class_name}.new + #{class_name}::Methods.each do |definitions| + opt = definitions.last + if opt[:request_style] == :document + @router.add_document_operation(servant, *definitions) + else + @router.add_rpc_operation(servant, *definitions) + end + end + self.mapping_registry = #{class_name}::MappingRegistry + EOD + end + c1.dump + "\n" + c2.dump + format(<<-EOD) + + if $0 == __FILE__ + # Change listen port. + server = #{class_name}App.new('app', nil, '0.0.0.0', 10080) + trap(:INT) do + server.shutdown + end + server.start + end + EOD + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/wsdl2ruby.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/wsdl2ruby.rb new file mode 100644 index 00000000..16b05fb0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/soap/wsdl2ruby.rb @@ -0,0 +1,176 @@ +# WSDL4R - WSDL to ruby mapping library. +# Copyright (C) 2002-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'logger' +require 'xsd/qname' +require 'wsdl/importer' +require 'wsdl/soap/classDefCreator' +require 'wsdl/soap/servantSkeltonCreator' +require 'wsdl/soap/driverCreator' +require 'wsdl/soap/clientSkeltonCreator' +require 'wsdl/soap/standaloneServerStubCreator' +require 'wsdl/soap/cgiStubCreator' + + +module WSDL +module SOAP + + +class WSDL2Ruby + attr_accessor :location + attr_reader :opt + attr_accessor :logger + attr_accessor :basedir + + def run + unless @location + raise RuntimeError, "WSDL location not given" + end + @wsdl = import(@location) + @name = @wsdl.name ? @wsdl.name.name : 'default' + create_file + end + +private + + def initialize + @location = nil + @opt = {} + @logger = Logger.new(STDERR) + @basedir = nil + @wsdl = nil + @name = nil + end + + def create_file + create_classdef if @opt.key?('classdef') + create_servant_skelton(@opt['servant_skelton']) if @opt.key?('servant_skelton') + create_cgi_stub(@opt['cgi_stub']) if @opt.key?('cgi_stub') + create_standalone_server_stub(@opt['standalone_server_stub']) if @opt.key?('standalone_server_stub') + create_driver(@opt['driver']) if @opt.key?('driver') + create_client_skelton(@opt['client_skelton']) if @opt.key?('client_skelton') + end + + def create_classdef + @logger.info { "Creating class definition." } + @classdef_filename = @name + '.rb' + check_file(@classdef_filename) or return + write_file(@classdef_filename) do |f| + f << WSDL::SOAP::ClassDefCreator.new(@wsdl).dump + end + end + + def create_client_skelton(servicename) + @logger.info { "Creating client skelton." } + servicename ||= @wsdl.services[0].name.name + @client_skelton_filename = servicename + 'Client.rb' + check_file(@client_skelton_filename) or return + write_file(@client_skelton_filename) do |f| + f << shbang << "\n" + f << "require '#{@driver_filename}'\n\n" if @driver_filename + f << WSDL::SOAP::ClientSkeltonCreator.new(@wsdl).dump( + create_name(servicename)) + end + end + + def create_servant_skelton(porttypename) + @logger.info { "Creating servant skelton." } + @servant_skelton_filename = (porttypename || @name + 'Servant') + '.rb' + check_file(@servant_skelton_filename) or return + write_file(@servant_skelton_filename) do |f| + f << "require '#{@classdef_filename}'\n\n" if @classdef_filename + f << WSDL::SOAP::ServantSkeltonCreator.new(@wsdl).dump( + create_name(porttypename)) + end + end + + def create_cgi_stub(servicename) + @logger.info { "Creating CGI stub." } + servicename ||= @wsdl.services[0].name.name + @cgi_stubFilename = servicename + '.cgi' + check_file(@cgi_stubFilename) or return + write_file(@cgi_stubFilename) do |f| + f << shbang << "\n" + if @servant_skelton_filename + f << "require '#{@servant_skelton_filename}'\n\n" + end + f << WSDL::SOAP::CGIStubCreator.new(@wsdl).dump(create_name(servicename)) + end + end + + def create_standalone_server_stub(servicename) + @logger.info { "Creating standalone stub." } + servicename ||= @wsdl.services[0].name.name + @standalone_server_stub_filename = servicename + '.rb' + check_file(@standalone_server_stub_filename) or return + write_file(@standalone_server_stub_filename) do |f| + f << shbang << "\n" + f << "require '#{@servant_skelton_filename}'\n\n" if @servant_skelton_filename + f << WSDL::SOAP::StandaloneServerStubCreator.new(@wsdl).dump( + create_name(servicename)) + end + end + + def create_driver(porttypename) + @logger.info { "Creating driver." } + @driver_filename = (porttypename || @name) + 'Driver.rb' + check_file(@driver_filename) or return + write_file(@driver_filename) do |f| + f << "require '#{@classdef_filename}'\n\n" if @classdef_filename + f << WSDL::SOAP::DriverCreator.new(@wsdl).dump( + create_name(porttypename)) + end + end + + def write_file(filename) + if @basedir + filename = File.join(basedir, filename) + end + File.open(filename, "w") do |f| + yield f + end + end + + def check_file(filename) + if @basedir + filename = File.join(basedir, filename) + end + if FileTest.exist?(filename) + if @opt.key?('force') + @logger.warn { + "File '#{filename}' exists but overrides it." + } + true + else + @logger.warn { + "File '#{filename}' exists. #{$0} did not override it." + } + false + end + else + @logger.info { "Creates file '#{filename}'." } + true + end + end + + def shbang + "#!/usr/bin/env ruby" + end + + def create_name(name) + name ? XSD::QName.new(@wsdl.targetnamespace, name) : nil + end + + def import(location) + WSDL::Importer.import(location) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/types.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/types.rb new file mode 100644 index 00000000..96ae5a49 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/types.rb @@ -0,0 +1,43 @@ +# WSDL4R - WSDL types definition. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL + + +class Types < Info + attr_reader :schemas + + def initialize + super + @schemas = [] + end + + def parse_element(element) + case element + when SchemaName + o = XMLSchema::Schema.new + @schemas << o + o + when DocumentationName + o = Documentation.new + o + else + nil + end + end + + def parse_attr(attr, value) + nil + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/wsdl.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/wsdl.rb new file mode 100644 index 00000000..eb13c188 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/wsdl.rb @@ -0,0 +1,23 @@ +# WSDL4R - Base definitions. +# Copyright (C) 2000, 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' + + +module WSDL + + +Version = '0.0.2' + +Namespace = 'http://schemas.xmlsoap.org/wsdl/' +SOAPBindingNamespace ='http://schemas.xmlsoap.org/wsdl/soap/' + +class Error < StandardError; end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/all.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/all.rb new file mode 100644 index 00000000..bb9566fe --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/all.rb @@ -0,0 +1,69 @@ +# WSDL4R - XMLSchema complexType definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class All < Info + attr_reader :minoccurs + attr_reader :maxoccurs + attr_reader :elements + + def initialize + super() + @minoccurs = '1' + @maxoccurs = '1' + @elements = [] + end + + def targetnamespace + parent.targetnamespace + end + + def elementformdefault + parent.elementformdefault + end + + def <<(element) + @elements << element + end + + def parse_element(element) + case element + when AnyName + o = Any.new + @elements << o + o + when ElementName + o = Element.new + @elements << o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when MaxOccursAttrName + @maxoccurs = value.source + when MinOccursAttrName + @minoccurs = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/annotation.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/annotation.rb new file mode 100644 index 00000000..633bd196 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/annotation.rb @@ -0,0 +1,34 @@ +# WSDL4R - WSDL SOAP documentation element. +# Copyright (C) 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Annotation < Info + def initialize + super + end + + def parse_element(element) + # Accepts any element. + self + end + + def parse_attr(attr, value) + # Accepts any attribute. + true + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/any.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/any.rb new file mode 100644 index 00000000..72d25e8d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/any.rb @@ -0,0 +1,56 @@ +# WSDL4R - XMLSchema any definition for WSDL. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Any < Info + attr_accessor :maxoccurs + attr_accessor :minoccurs + attr_accessor :namespace + attr_accessor :process_contents + + def initialize + super() + @maxoccurs = '1' + @minoccurs = '1' + @namespace = '##any' + @process_contents = 'strict' + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when MaxOccursAttrName + @maxoccurs = value.source + when MinOccursAttrName + @minoccurs = value.source + when NamespaceAttrName + @namespace = value.source + when ProcessContentsAttrName + @process_contents = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/attribute.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/attribute.rb new file mode 100644 index 00000000..f9048661 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/attribute.rb @@ -0,0 +1,127 @@ +# WSDL4R - XMLSchema attribute definition for WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Attribute < Info + class << self + if RUBY_VERSION > "1.7.0" + def attr_reader_ref(symbol) + name = symbol.to_s + define_method(name) { + instance_variable_get("@#{name}") || + (refelement ? refelement.__send__(name) : nil) + } + end + else + def attr_reader_ref(symbol) + name = symbol.to_s + module_eval <<-EOS + def #{name} + @#{name} || (refelement ? refelement.#{name} : nil) + end + EOS + end + end + end + + attr_writer :use + attr_writer :form + attr_writer :name + attr_writer :type + attr_writer :local_simpletype + attr_writer :default + attr_writer :fixed + + attr_reader_ref :use + attr_reader_ref :form + attr_reader_ref :name + attr_reader_ref :type + attr_reader_ref :local_simpletype + attr_reader_ref :default + attr_reader_ref :fixed + + attr_accessor :ref + attr_accessor :arytype + + def initialize + super + @use = nil + @form = nil + @name = nil + @type = nil + @local_simpletype = nil + @default = nil + @fixed = nil + @ref = nil + @refelement = nil + @arytype = nil + end + + def refelement + @refelement ||= root.collect_attributes[@ref] + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when SimpleTypeName + @local_simpletype = SimpleType.new + @local_simpletype + end + end + + def parse_attr(attr, value) + case attr + when RefAttrName + @ref = value + when UseAttrName + @use = value.source + when FormAttrName + @form = value.source + when NameAttrName + if directelement? + @name = XSD::QName.new(targetnamespace, value.source) + else + @name = XSD::QName.new(nil, value.source) + end + when TypeAttrName + @type = value + when DefaultAttrName + @default = value.source + when FixedAttrName + @fixed = value.source + when ArrayTypeAttrName + @arytype = if value.namespace.nil? + XSD::QName.new(XSD::Namespace, value.source) + else + value + end + else + nil + end + end + +private + + def directelement? + parent.is_a?(Schema) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/choice.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/choice.rb new file mode 100644 index 00000000..f6d27fa3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/choice.rb @@ -0,0 +1,69 @@ +# WSDL4R - XMLSchema complexType definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Choice < Info + attr_reader :minoccurs + attr_reader :maxoccurs + attr_reader :elements + + def initialize + super() + @minoccurs = '1' + @maxoccurs = '1' + @elements = [] + end + + def targetnamespace + parent.targetnamespace + end + + def elementformdefault + parent.elementformdefault + end + + def <<(element) + @elements << element + end + + def parse_element(element) + case element + when AnyName + o = Any.new + @elements << o + o + when ElementName + o = Element.new + @elements << o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when MaxOccursAttrName + @maxoccurs = value.source + when MinOccursAttrName + @minoccurs = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/complexContent.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/complexContent.rb new file mode 100644 index 00000000..f7fb6c16 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/complexContent.rb @@ -0,0 +1,92 @@ +# WSDL4R - XMLSchema complexContent definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class ComplexContent < Info + attr_accessor :base + attr_reader :derivetype + attr_reader :content + attr_reader :attributes + + def initialize + super + @base = nil + @derivetype = nil + @content = nil + @attributes = XSD::NamedElements.new + @basetype = nil + end + + def targetnamespace + parent.targetnamespace + end + + def elementformdefault + parent.elementformdefault + end + + def basetype + @basetype ||= root.collect_complextypes[@base] + end + + def parse_element(element) + case element + when RestrictionName, ExtensionName + @derivetype = element.name + self + when AllName + if @derivetype.nil? + raise Parser::ElementConstraintError.new("base attr not found.") + end + @content = All.new + @content + when SequenceName + if @derivetype.nil? + raise Parser::ElementConstraintError.new("base attr not found.") + end + @content = Sequence.new + @content + when ChoiceName + if @derivetype.nil? + raise Parser::ElementConstraintError.new("base attr not found.") + end + @content = Choice.new + @content + when AttributeName + if @derivetype.nil? + raise Parser::ElementConstraintError.new("base attr not found.") + end + o = Attribute.new + @attributes << o + o + end + end + + def parse_attr(attr, value) + if @derivetype.nil? + return nil + end + case attr + when BaseAttrName + @base = value + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/complexType.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/complexType.rb new file mode 100644 index 00000000..dc9ec954 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/complexType.rb @@ -0,0 +1,139 @@ +# WSDL4R - XMLSchema complexType definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/xmlSchema/content' +require 'wsdl/xmlSchema/element' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class ComplexType < Info + attr_accessor :name + attr_accessor :complexcontent + attr_accessor :simplecontent + attr_reader :content + attr_accessor :final + attr_accessor :mixed + attr_reader :attributes + + def initialize(name = nil) + super() + @name = name + @complexcontent = nil + @simplecontent = nil + @content = nil + @final = nil + @mixed = false + @attributes = XSD::NamedElements.new + end + + def targetnamespace + # inner elements can be qualified + # parent.is_a?(WSDL::XMLSchema::Element) ? nil : parent.targetnamespace + parent.targetnamespace + end + + def elementformdefault + parent.elementformdefault + end + + AnyAsElement = Element.new(XSD::QName.new(nil, 'any'), XSD::AnyTypeName) + def each_element + if content + content.elements.each do |element| + if element.is_a?(Any) + yield(AnyAsElement) + else + yield(element) + end + end + end + end + + def find_element(name) + if content + content.elements.each do |element| + if element.is_a?(Any) + return AnyAsElement if name == AnyAsElement.name + else + return element if name == element.name + end + end + end + nil + end + + def find_element_by_name(name) + if content + content.elements.each do |element| + if element.is_a?(Any) + return AnyAsElement if name == AnyAsElement.name.name + else + return element if name == element.name.name + end + end + end + nil + end + + def sequence_elements=(elements) + @content = Sequence.new + elements.each do |element| + @content << element + end + end + + def all_elements=(elements) + @content = All.new + elements.each do |element| + @content << element + end + end + + def parse_element(element) + case element + when AllName + @content = All.new + when SequenceName + @content = Sequence.new + when ChoiceName + @content = Choice.new + when ComplexContentName + @complexcontent = ComplexContent.new + when SimpleContentName + @simplecontent = SimpleContent.new + when AttributeName + o = Attribute.new + @attributes << o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when FinalAttrName + @final = value.source + when MixedAttrName + @mixed = (value.source == 'true') + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/content.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/content.rb new file mode 100644 index 00000000..2f1dfb4b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/content.rb @@ -0,0 +1,96 @@ +# WSDL4R - XMLSchema complexType definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Content < Info + attr_accessor :final + attr_accessor :mixed + attr_accessor :type + attr_reader :contents + attr_reader :elements + + def initialize + super() + @final = nil + @mixed = false + @type = nil + @contents = [] + @elements = [] + end + + def targetnamespace + parent.targetnamespace + end + + def <<(content) + @contents << content + update_elements + end + + def each + @contents.each do |content| + yield content + end + end + + def parse_element(element) + case element + when AllName, SequenceName, ChoiceName + o = Content.new + o.type = element.name + @contents << o + o + when AnyName + o = Any.new + @contents << o + o + when ElementName + o = Element.new + @contents << o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when FinalAttrName + @final = value.source + when MixedAttrName + @mixed = (value.source == 'true') + else + nil + end + end + + def parse_epilogue + update_elements + end + +private + + def update_elements + @elements = [] + @contents.each do |content| + if content.is_a?(Element) + @elements << [content.name, content] + end + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/data.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/data.rb new file mode 100644 index 00000000..23ab1adf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/data.rb @@ -0,0 +1,80 @@ +# WSDL4R - XMLSchema data definitions. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/datatypes' +require 'wsdl/xmlSchema/annotation' +require 'wsdl/xmlSchema/schema' +require 'wsdl/xmlSchema/import' +require 'wsdl/xmlSchema/include' +require 'wsdl/xmlSchema/simpleType' +require 'wsdl/xmlSchema/simpleRestriction' +require 'wsdl/xmlSchema/simpleExtension' +require 'wsdl/xmlSchema/complexType' +require 'wsdl/xmlSchema/complexContent' +require 'wsdl/xmlSchema/simpleContent' +require 'wsdl/xmlSchema/any' +require 'wsdl/xmlSchema/element' +require 'wsdl/xmlSchema/all' +require 'wsdl/xmlSchema/choice' +require 'wsdl/xmlSchema/sequence' +require 'wsdl/xmlSchema/attribute' +require 'wsdl/xmlSchema/unique' +require 'wsdl/xmlSchema/enumeration' +require 'wsdl/xmlSchema/length' +require 'wsdl/xmlSchema/pattern' + +module WSDL +module XMLSchema + + +AllName = XSD::QName.new(XSD::Namespace, 'all') +AnnotationName = XSD::QName.new(XSD::Namespace, 'annotation') +AnyName = XSD::QName.new(XSD::Namespace, 'any') +AttributeName = XSD::QName.new(XSD::Namespace, 'attribute') +ChoiceName = XSD::QName.new(XSD::Namespace, 'choice') +ComplexContentName = XSD::QName.new(XSD::Namespace, 'complexContent') +ComplexTypeName = XSD::QName.new(XSD::Namespace, 'complexType') +ElementName = XSD::QName.new(XSD::Namespace, 'element') +EnumerationName = XSD::QName.new(XSD::Namespace, 'enumeration') +ExtensionName = XSD::QName.new(XSD::Namespace, 'extension') +ImportName = XSD::QName.new(XSD::Namespace, 'import') +IncludeName = XSD::QName.new(XSD::Namespace, 'include') +LengthName = XSD::QName.new(XSD::Namespace, 'length') +PatternName = XSD::QName.new(XSD::Namespace, 'pattern') +RestrictionName = XSD::QName.new(XSD::Namespace, 'restriction') +SequenceName = XSD::QName.new(XSD::Namespace, 'sequence') +SchemaName = XSD::QName.new(XSD::Namespace, 'schema') +SimpleContentName = XSD::QName.new(XSD::Namespace, 'simpleContent') +SimpleTypeName = XSD::QName.new(XSD::Namespace, 'simpleType') +UniqueName = XSD::QName.new(XSD::Namespace, 'unique') + +AttributeFormDefaultAttrName = XSD::QName.new(nil, 'attributeFormDefault') +BaseAttrName = XSD::QName.new(nil, 'base') +DefaultAttrName = XSD::QName.new(nil, 'default') +ElementFormDefaultAttrName = XSD::QName.new(nil, 'elementFormDefault') +FinalAttrName = XSD::QName.new(nil, 'final') +FixedAttrName = XSD::QName.new(nil, 'fixed') +FormAttrName = XSD::QName.new(nil, 'form') +IdAttrName = XSD::QName.new(nil, 'id') +MaxOccursAttrName = XSD::QName.new(nil, 'maxOccurs') +MinOccursAttrName = XSD::QName.new(nil, 'minOccurs') +MixedAttrName = XSD::QName.new(nil, 'mixed') +NameAttrName = XSD::QName.new(nil, 'name') +NamespaceAttrName = XSD::QName.new(nil, 'namespace') +NillableAttrName = XSD::QName.new(nil, 'nillable') +ProcessContentsAttrName = XSD::QName.new(nil, 'processContents') +RefAttrName = XSD::QName.new(nil, 'ref') +SchemaLocationAttrName = XSD::QName.new(nil, 'schemaLocation') +TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace') +TypeAttrName = XSD::QName.new(nil, 'type') +UseAttrName = XSD::QName.new(nil, 'use') +ValueAttrName = XSD::QName.new(nil, 'value') + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/element.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/element.rb new file mode 100644 index 00000000..fffb6485 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/element.rb @@ -0,0 +1,154 @@ +# WSDL4R - XMLSchema element definition for WSDL. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Element < Info + class << self + if RUBY_VERSION > "1.7.0" + def attr_reader_ref(symbol) + name = symbol.to_s + define_method(name) { + instance_variable_get("@#{name}") || + (refelement ? refelement.__send__(name) : nil) + } + end + else + def attr_reader_ref(symbol) + name = symbol.to_s + module_eval <<-EOS + def #{name} + @#{name} || (refelement ? refelement.#{name} : nil) + end + EOS + end + end + end + + attr_writer :name # required + attr_writer :form + attr_writer :type + attr_writer :local_simpletype + attr_writer :local_complextype + attr_writer :constraint + attr_writer :maxoccurs + attr_writer :minoccurs + attr_writer :nillable + + attr_reader_ref :name + attr_reader_ref :form + attr_reader_ref :type + attr_reader_ref :local_simpletype + attr_reader_ref :local_complextype + attr_reader_ref :constraint + attr_reader_ref :maxoccurs + attr_reader_ref :minoccurs + attr_reader_ref :nillable + + attr_accessor :ref + + def initialize(name = nil, type = nil) + super() + @name = name + @form = nil + @type = type + @local_simpletype = @local_complextype = nil + @constraint = nil + @maxoccurs = '1' + @minoccurs = '1' + @nillable = nil + @ref = nil + @refelement = nil + end + + def refelement + @refelement ||= (@ref ? root.collect_elements[@ref] : nil) + end + + def targetnamespace + parent.targetnamespace + end + + def elementformdefault + parent.elementformdefault + end + + def elementform + self.form.nil? ? parent.elementformdefault : self.form + end + + def parse_element(element) + case element + when SimpleTypeName + @local_simpletype = SimpleType.new + @local_simpletype + when ComplexTypeName + @type = nil + @local_complextype = ComplexType.new + @local_complextype + when UniqueName + @constraint = Unique.new + @constraint + else + nil + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + # namespace may be nil + if directelement? or elementform == 'qualified' + @name = XSD::QName.new(targetnamespace, value.source) + else + @name = XSD::QName.new(nil, value.source) + end + when FormAttrName + @form = value.source + when TypeAttrName + @type = value + when RefAttrName + @ref = value + when MaxOccursAttrName + if parent.is_a?(All) + if value.source != '1' + raise Parser::AttrConstraintError.new( + "cannot parse #{value} for #{attr}") + end + end + @maxoccurs = value.source + when MinOccursAttrName + if parent.is_a?(All) + unless ['0', '1'].include?(value.source) + raise Parser::AttrConstraintError.new( + "cannot parse #{value} for #{attr}") + end + end + @minoccurs = value.source + when NillableAttrName + @nillable = (value.source == 'true') + else + nil + end + end + +private + + def directelement? + parent.is_a?(Schema) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/enumeration.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/enumeration.rb new file mode 100644 index 00000000..5a164760 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/enumeration.rb @@ -0,0 +1,36 @@ +# WSDL4R - XMLSchema enumeration definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Enumeration < Info + def initialize + super + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when ValueAttrName + parent.enumeration << value.source + value.source + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/import.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/import.rb new file mode 100644 index 00000000..d3487af9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/import.rb @@ -0,0 +1,65 @@ +# WSDL4R - XMLSchema import definition. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/xmlSchema/importer' + + +module WSDL +module XMLSchema + + +class Import < Info + attr_reader :namespace + attr_reader :schemalocation + attr_reader :content + + def initialize + super + @namespace = nil + @schemalocation = nil + @content = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when NamespaceAttrName + @namespace = value.source + when SchemaLocationAttrName + @schemalocation = URI.parse(value.source) + if @schemalocation.relative? and !parent.location.nil? and + !parent.location.relative? + @schemalocation = parent.location + @schemalocation + end + if root.importedschema.key?(@schemalocation) + @content = root.importedschema[@schemalocation] + else + root.importedschema[@schemalocation] = nil # placeholder + @content = import(@schemalocation) + root.importedschema[@schemalocation] = @content + end + @schemalocation + else + nil + end + end + +private + + def import(location) + Importer.import(location, root) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/importer.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/importer.rb new file mode 100644 index 00000000..f57bfd97 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/importer.rb @@ -0,0 +1,87 @@ +# WSDL4R - XSD importer library. +# Copyright (C) 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'soap/httpconfigloader' +require 'wsdl/xmlSchema/parser' + + +module WSDL +module XMLSchema + + +class Importer + def self.import(location, originalroot = nil) + new.import(location, originalroot) + end + + def initialize + @web_client = nil + end + + def import(location, originalroot = nil) + unless location.is_a?(URI) + location = URI.parse(location) + end + content = parse(fetch(location), location, originalroot) + content.location = location + content + end + +private + + def parse(content, location, originalroot) + opt = { + :location => location, + :originalroot => originalroot + } + WSDL::XMLSchema::Parser.new(opt).parse(content) + end + + def fetch(location) + warn("importing: #{location}") if $DEBUG + content = nil + if location.scheme == 'file' or + (location.relative? and FileTest.exist?(location.path)) + content = File.open(location.path).read + elsif location.scheme and location.scheme.size == 1 and + FileTest.exist?(location.to_s) + # ToDo: remove this ugly workaround for a path with drive letter + # (D://foo/bar) + content = File.open(location.to_s).read + else + client = web_client.new(nil, "WSDL4R") + client.proxy = ::SOAP::Env::HTTP_PROXY + client.no_proxy = ::SOAP::Env::NO_PROXY + if opt = ::SOAP::Property.loadproperty(::SOAP::PropertyName) + ::SOAP::HTTPConfigLoader.set_options(client, + opt["client.protocol.http"]) + end + content = client.get_content(location) + end + content + end + + def web_client + @web_client ||= begin + require 'http-access2' + if HTTPAccess2::VERSION < "2.0" + raise LoadError.new("http-access/2.0 or later is required.") + end + HTTPAccess2::Client + rescue LoadError + warn("Loading http-access2 failed. Net/http is used.") if $DEBUG + require 'soap/netHttpClient' + ::SOAP::NetHttpClient + end + @web_client + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/include.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/include.rb new file mode 100644 index 00000000..af1ef942 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/include.rb @@ -0,0 +1,54 @@ +# WSDL4R - XMLSchema include definition. +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'wsdl/xmlSchema/importer' + + +module WSDL +module XMLSchema + + +class Include < Info + attr_reader :schemalocation + attr_reader :content + + def initialize + super + @schemalocation = nil + @content = nil + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when SchemaLocationAttrName + @schemalocation = URI.parse(value.source) + if @schemalocation.relative? + @schemalocation = parent.location + @schemalocation + end + @content = import(@schemalocation) + @schemalocation + else + nil + end + end + +private + + def import(location) + Importer.import(location) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/length.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/length.rb new file mode 100644 index 00000000..7f61602d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/length.rb @@ -0,0 +1,35 @@ +# WSDL4R - XMLSchema length definition for WSDL. +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Length < Info + def initialize + super + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when ValueAttrName + value.source + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/parser.rb new file mode 100644 index 00000000..057d9d9b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/parser.rb @@ -0,0 +1,166 @@ +# WSDL4R - WSDL XML Instance parser library. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'xsd/ns' +require 'xsd/charset' +require 'xsd/datatypes' +require 'xsd/xmlparser' +require 'wsdl/xmlSchema/data' + + +module WSDL +module XMLSchema + + +class Parser + include XSD + + class ParseError < Error; end + class FormatDecodeError < ParseError; end + class UnknownElementError < FormatDecodeError; end + class UnknownAttributeError < FormatDecodeError; end + class UnexpectedElementError < FormatDecodeError; end + class ElementConstraintError < FormatDecodeError; end + class AttributeConstraintError < FormatDecodeError; end + +private + + class ParseFrame + attr_reader :ns + attr_reader :name + attr_accessor :node + + private + + def initialize(ns, name, node) + @ns = ns + @name = name + @node = node + end + end + +public + + def initialize(opt = {}) + @parser = XSD::XMLParser.create_parser(self, opt) + @parsestack = nil + @lastnode = nil + @ignored = {} + @location = opt[:location] + @originalroot = opt[:originalroot] + end + + def parse(string_or_readable) + @parsestack = [] + @lastnode = nil + @textbuf = '' + @parser.do_parse(string_or_readable) + @lastnode + end + + def charset + @parser.charset + end + + def start_element(name, attrs) + lastframe = @parsestack.last + ns = parent = nil + if lastframe + ns = lastframe.ns.clone_ns + parent = lastframe.node + else + ns = XSD::NS.new + parent = nil + end + attrs = XSD::XMLParser.filter_ns(ns, attrs) + node = decode_tag(ns, name, attrs, parent) + @parsestack << ParseFrame.new(ns, name, node) + end + + def characters(text) + lastframe = @parsestack.last + if lastframe + # Need not to be cloned because character does not have attr. + ns = lastframe.ns + decode_text(ns, text) + else + p text if $DEBUG + end + end + + def end_element(name) + lastframe = @parsestack.pop + unless name == lastframe.name + raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'") + end + decode_tag_end(lastframe.ns, lastframe.node) + @lastnode = lastframe.node + end + +private + + def decode_tag(ns, name, attrs, parent) + o = nil + elename = ns.parse(name) + if !parent + if elename == SchemaName + o = Schema.parse_element(elename) + o.location = @location + else + raise UnknownElementError.new("unknown element: #{elename}") + end + o.root = @originalroot if @originalroot # o.root = o otherwise + else + if elename == AnnotationName + # only the first annotation element is allowed for each element. + o = Annotation.new + else + o = parent.parse_element(elename) + end + unless o + unless @ignored.key?(elename) + warn("ignored element: #{elename} of #{parent.class}") + @ignored[elename] = elename + end + o = Documentation.new # which accepts any element. + end + # node could be a pseudo element. pseudo element has its own parent. + o.root = parent.root + o.parent = parent if o.parent.nil? + end + attrs.each do |key, value| + attr_ele = ns.parse(key, true) + value_ele = ns.parse(value, true) + value_ele.source = value # for recovery; value may not be a QName + if attr_ele == IdAttrName + o.id = value_ele + else + unless o.parse_attr(attr_ele, value_ele) + unless @ignored.key?(attr_ele) + warn("ignored attr: #{attr_ele}") + @ignored[attr_ele] = attr_ele + end + end + end + end + o + end + + def decode_tag_end(ns, node) + node.parse_epilogue + end + + def decode_text(ns, text) + @textbuf << text + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/pattern.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/pattern.rb new file mode 100644 index 00000000..f826be45 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/pattern.rb @@ -0,0 +1,36 @@ +# WSDL4R - XMLSchema pattern definition for WSDL. +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Pattern < Info + def initialize + super + end + + def parse_element(element) + nil + end + + def parse_attr(attr, value) + case attr + when ValueAttrName + parent.pattern = /\A#{value.source}\z/n + value.source + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/schema.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/schema.rb new file mode 100644 index 00000000..ec97d07a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/schema.rb @@ -0,0 +1,143 @@ +# WSDL4R - XMLSchema schema definition for WSDL. +# Copyright (C) 2002, 2003-2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class Schema < Info + attr_reader :targetnamespace # required + attr_reader :complextypes + attr_reader :simpletypes + attr_reader :elements + attr_reader :attributes + attr_reader :imports + attr_accessor :attributeformdefault + attr_accessor :elementformdefault + + attr_reader :importedschema + + def initialize + super + @targetnamespace = nil + @complextypes = XSD::NamedElements.new + @simpletypes = XSD::NamedElements.new + @elements = XSD::NamedElements.new + @attributes = XSD::NamedElements.new + @imports = [] + @attributeformdefault = "unqualified" + @elementformdefault = "unqualified" + @importedschema = {} + @location = nil + @root = self + end + + def location + @location || (root.nil? ? nil : root.location) + end + + def location=(location) + @location = location + end + + def parse_element(element) + case element + when ImportName + o = Import.new + @imports << o + o + when IncludeName + o = Include.new + @imports << o + o + when ComplexTypeName + o = ComplexType.new + @complextypes << o + o + when SimpleTypeName + o = SimpleType.new + @simpletypes << o + o + when ElementName + o = Element.new + @elements << o + o + when AttributeName + o = Attribute.new + @attributes << o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when TargetNamespaceAttrName + @targetnamespace = value.source + when AttributeFormDefaultAttrName + @attributeformdefault = value.source + when ElementFormDefaultAttrName + @elementformdefault = value.source + else + nil + end + end + + def collect_attributes + result = XSD::NamedElements.new + result.concat(@attributes) + @imports.each do |import| + result.concat(import.content.collect_attributes) if import.content + end + result + end + + def collect_elements + result = XSD::NamedElements.new + result.concat(@elements) + @imports.each do |import| + result.concat(import.content.collect_elements) if import.content + end + result + end + + def collect_complextypes + result = XSD::NamedElements.new + result.concat(@complextypes) + @imports.each do |import| + result.concat(import.content.collect_complextypes) if import.content + end + result + end + + def collect_simpletypes + result = XSD::NamedElements.new + result.concat(@simpletypes) + @imports.each do |import| + result.concat(import.content.collect_simpletypes) if import.content + end + result + end + + def self.parse_element(element) + if element == SchemaName + Schema.new + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/sequence.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/sequence.rb new file mode 100644 index 00000000..823fa3b7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/sequence.rb @@ -0,0 +1,69 @@ +# WSDL4R - XMLSchema complexType definition for WSDL. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Sequence < Info + attr_reader :minoccurs + attr_reader :maxoccurs + attr_reader :elements + + def initialize + super() + @minoccurs = '1' + @maxoccurs = '1' + @elements = [] + end + + def targetnamespace + parent.targetnamespace + end + + def elementformdefault + parent.elementformdefault + end + + def <<(element) + @elements << element + end + + def parse_element(element) + case element + when AnyName + o = Any.new + @elements << o + o + when ElementName + o = Element.new + @elements << o + o + else + nil + end + end + + def parse_attr(attr, value) + case attr + when MaxOccursAttrName + @maxoccurs = value.source + when MinOccursAttrName + @minoccurs = value.source + else + nil + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleContent.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleContent.rb new file mode 100644 index 00000000..e1f35c88 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleContent.rb @@ -0,0 +1,65 @@ +# WSDL4R - XMLSchema simpleContent definition for WSDL. +# Copyright (C) 2004, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class SimpleContent < Info + attr_reader :restriction + attr_reader :extension + + def check_lexical_format(value) + check(value) + end + + def initialize + super + @restriction = nil + @extension = nil + end + + def base + content.base + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when RestrictionName + @restriction = SimpleRestriction.new + @restriction + when ExtensionName + @extension = SimpleExtension.new + @extension + end + end + +private + + def content + @restriction || @extension + end + + def check(value) + unless content.valid?(value) + raise XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'") + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleExtension.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleExtension.rb new file mode 100644 index 00000000..3c53a732 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleExtension.rb @@ -0,0 +1,54 @@ +# WSDL4R - XMLSchema simpleType extension definition for WSDL. +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class SimpleExtension < Info + attr_reader :base + attr_reader :attributes + + def initialize + super + @base = nil + @attributes = XSD::NamedElements.new + end + + def targetnamespace + parent.targetnamespace + end + + def valid?(value) + true + end + + def parse_element(element) + case element + when AttributeName + o = Attribute.new + @attributes << o + o + end + end + + def parse_attr(attr, value) + case attr + when BaseAttrName + @base = value + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleRestriction.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleRestriction.rb new file mode 100644 index 00000000..e8bf3ebf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleRestriction.rb @@ -0,0 +1,73 @@ +# WSDL4R - XMLSchema simpleContent restriction definition for WSDL. +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class SimpleRestriction < Info + attr_reader :base + attr_reader :enumeration + attr_accessor :length + attr_accessor :pattern + + def initialize + super + @base = nil + @enumeration = [] # NamedElements? + @length = nil + @pattern = nil + end + + def valid?(value) + return false unless check_restriction(value) + return false unless check_length(value) + return false unless check_pattern(value) + true + end + + def parse_element(element) + case element + when EnumerationName + Enumeration.new # just a parsing handler + when LengthName + Length.new # just a parsing handler + when PatternName + Pattern.new # just a parsing handler + end + end + + def parse_attr(attr, value) + case attr + when BaseAttrName + @base = value + end + end + +private + + def check_restriction(value) + @enumeration.empty? or @enumeration.include?(value) + end + + def check_length(value) + @length.nil? or value.size == @length + end + + def check_pattern(value) + @pattern.nil? or @pattern =~ value + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleType.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleType.rb new file mode 100644 index 00000000..e808c318 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/simpleType.rb @@ -0,0 +1,73 @@ +# WSDL4R - XMLSchema simpleType definition for WSDL. +# Copyright (C) 2004, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' +require 'xsd/namedelements' + + +module WSDL +module XMLSchema + + +class SimpleType < Info + attr_accessor :name + attr_reader :restriction + + def check_lexical_format(value) + if @restriction + check_restriction(value) + else + raise ArgumentError.new("incomplete simpleType") + end + end + + def base + if @restriction + @restriction.base + else + raise ArgumentError.new("incomplete simpleType") + end + end + + def initialize(name = nil) + super() + @name = name + @restriction = nil + end + + def targetnamespace + parent.targetnamespace + end + + def parse_element(element) + case element + when RestrictionName + @restriction = SimpleRestriction.new + @restriction + end + end + + def parse_attr(attr, value) + case attr + when NameAttrName + @name = XSD::QName.new(targetnamespace, value.source) + end + end + +private + + def check_restriction(value) + unless @restriction.valid?(value) + raise XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'") + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/unique.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/unique.rb new file mode 100644 index 00000000..837ff22b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/unique.rb @@ -0,0 +1,34 @@ +# WSDL4R - XMLSchema unique element. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'wsdl/info' + + +module WSDL +module XMLSchema + + +class Unique < Info + def initialize + super + end + + def parse_element(element) + # Accepts any element. + self + end + + def parse_attr(attr, value) + # Accepts any attribute. + true + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/xsd2ruby.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/xsd2ruby.rb new file mode 100644 index 00000000..afe5fc5a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/wsdl/xmlSchema/xsd2ruby.rb @@ -0,0 +1,107 @@ +# XSD4R - XSD to ruby mapping library. +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'wsdl/xmlSchema/importer' +require 'wsdl/soap/classDefCreator' + + +module WSDL +module XMLSchema + + +class XSD2Ruby + attr_accessor :location + attr_reader :opt + attr_accessor :logger + attr_accessor :basedir + + def run + unless @location + raise RuntimeError, "XML Schema location not given" + end + @xsd = import(@location) + @name = create_classname(@xsd) + create_file + end + +private + + def initialize + @location = nil + @opt = {} + @logger = Logger.new(STDERR) + @basedir = nil + @xsd = nil + @name = nil + end + + def create_file + create_classdef + end + + def create_classdef + @logger.info { "Creating class definition." } + @classdef_filename = @name + '.rb' + check_file(@classdef_filename) or return + write_file(@classdef_filename) do |f| + f << WSDL::SOAP::ClassDefCreator.new(@xsd).dump + end + end + + def write_file(filename) + if @basedir + filename = File.join(basedir, filename) + end + File.open(filename, "w") do |f| + yield f + end + end + + def check_file(filename) + if @basedir + filename = File.join(basedir, filename) + end + if FileTest.exist?(filename) + if @opt.key?('force') + @logger.warn { + "File '#{filename}' exists but overrides it." + } + true + else + @logger.warn { + "File '#{filename}' exists. #{$0} did not override it." + } + false + end + else + @logger.info { "Creates file '#{filename}'." } + true + end + end + + def create_classname(xsd) + name = nil + if xsd.targetnamespace + name = xsd.targetnamespace.scan(/[a-zA-Z0-9]+$/)[0] + end + if name.nil? + 'default' + else + XSD::CodeGen::GenSupport.safevarname(name) + end + end + + def import(location) + WSDL::XMLSchema::Importer.import(location) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/base64.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/base64.rb new file mode 100644 index 00000000..0fe5b824 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/base64.rb @@ -0,0 +1,81 @@ +=begin += xmlrpc/base64.rb +Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) + +Released under the same term of license as Ruby. + += Classes +* (()) + += XMLRPC::Base64 +== Description +This class is necessary for (('xmlrpc4r')) to determine that a string should +be transmitted base64-encoded and not as a raw-string. +You can use (({XMLRPC::Base64})) on the client and server-side as a +parameter and/or return-value. + +== Class Methods +--- XMLRPC::Base64.new( str, state = :dec ) + Creates a new (({XMLRPC::Base64})) instance with string ((|str|)) as the + internal string. When ((|state|)) is (({:dec})) it assumes that the + string ((|str|)) is not in base64 format (perhaps already decoded), + otherwise if ((|state|)) is (({:enc})) it decodes ((|str|)) + and stores it as the internal string. + +--- XMLRPC::Base64.decode( str ) + Decodes string ((|str|)) with base64 and returns that value. + +--- XMLRPC::Base64.encode( str ) + Encodes string ((|str|)) with base64 and returns that value. + +== Instance Methods +--- XMLRPC::Base64#decoded + Returns the internal string decoded. + +--- XMLRPC::Base64#encoded + Returns the internal string encoded with base64. + +=end + +module XMLRPC + +class Base64 + + def initialize(str, state = :dec) + case state + when :enc + @str = Base64.decode(str) + when :dec + @str = str + else + raise ArgumentError, "wrong argument; either :enc or :dec" + end + end + + def decoded + @str + end + + def encoded + Base64.encode(@str) + end + + + def Base64.decode(str) + str.gsub(/\s+/, "").unpack("m")[0] + end + + def Base64.encode(str) + [str].pack("m") + end + +end + + +end # module XMLRPC + + +=begin += History + $Id: base64.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/client.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/client.rb new file mode 100644 index 00000000..816926b7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/client.rb @@ -0,0 +1,619 @@ +=begin += xmlrpc/client.rb +Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) + +Released under the same term of license as Ruby. + += Classes +* (()) +* (()) + + += XMLRPC::Client +== Synopsis + require "xmlrpc/client" + + server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80) + begin + param = server.call("michael.add", 4, 5) + puts "4 + 5 = #{param}" + rescue XMLRPC::FaultException => e + puts "Error:" + puts e.faultCode + puts e.faultString + end + +or + + require "xmlrpc/client" + + server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80) + ok, param = server.call2("michael.add", 4, 5) + if ok then + puts "4 + 5 = #{param}" + else + puts "Error:" + puts param.faultCode + puts param.faultString + end + +== Description +Class (({XMLRPC::Client})) provides remote procedure calls to a XML-RPC server. +After setting the connection-parameters with (()) which +creates a new (({XMLRPC::Client})) instance, you can execute a remote procedure +by sending the (()) or (()) +message to this new instance. The given parameters indicate which method to +call on the remote-side and of course the parameters for the remote procedure. + +== Class Methods +--- XMLRPC::Client.new( host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, user=nil, password=nil, use_ssl=false, timeout =nil) + Creates an object which represents the remote XML-RPC server on the + given host ((|host|)). If the server is CGI-based, ((|path|)) is the + path to the CGI-script, which will be called, otherwise (in the + case of a standalone server) ((|path|)) should be (({"/RPC2"})). + ((|port|)) is the port on which the XML-RPC server listens. + If ((|proxy_host|)) is given, then a proxy server listening at + ((|proxy_host|)) is used. ((|proxy_port|)) is the port of the + proxy server. + + Default values for ((|host|)), ((|path|)) and ((|port|)) are 'localhost', '/RPC2' and + '80' respectively using SSL '443'. + + If ((|user|)) and ((|password|)) are given, each time a request is send, + a Authorization header is send. Currently only Basic Authentification is + implemented no Digest. + + If ((|use_ssl|)) is set to (({true})), comunication over SSL is enabled. + Note, that you need the SSL package from RAA installed. + + Parameter ((|timeout|)) is the time to wait for a XML-RPC response, defaults to 30. + +--- XMLRPC::Client.new2( uri, proxy=nil, timeout=nil) +--- XMLRPC::Client.new_from_uri( uri, proxy=nil, timeout=nil) +: uri + URI specifying protocol (http or https), host, port, path, user and password. + Example: https://user:password@host:port/path + +: proxy + Is of the form "host:port". + +: timeout + Defaults to 30. + +--- XMLRPC::Client.new3( hash={} ) +--- XMLRPC::Client.new_from_hash( hash={} ) + Parameter ((|hash|)) has following case-insensitive keys: + * host + * path + * port + * proxy_host + * proxy_port + * user + * password + * use_ssl + * timeout + + Calls (()) with the corresponding values. + +== Instance Methods +--- XMLRPC::Client#call( method, *args ) + Invokes the method named ((|method|)) with the parameters given by + ((|args|)) on the XML-RPC server. + The parameter ((|method|)) is converted into a (({String})) and should + be a valid XML-RPC method-name. + Each parameter of ((|args|)) must be of one of the following types, + where (({Hash})), (({Struct})) and (({Array})) can contain any of these listed ((:types:)): + * (({Fixnum})), (({Bignum})) + * (({TrueClass})), (({FalseClass})) ((({true})), (({false}))) + * (({String})), (({Symbol})) + * (({Float})) + * (({Hash})), (({Struct})) + * (({Array})) + * (({Date})), (({Time})), (({XMLRPC::DateTime})) + * (({XMLRPC::Base64})) + * A Ruby object which class includes XMLRPC::Marshallable (only if Config::ENABLE_MARSHALLABLE is (({true}))). + That object is converted into a hash, with one additional key/value pair "___class___" which contains the class name + for restoring later that object. + + The method returns the return-value from the RPC + ((-stands for Remote Procedure Call-)). + The type of the return-value is one of the above shown, + only that a (({Bignum})) is only allowed when it fits in 32-bit and + that a XML-RPC (('dateTime.iso8601')) type is always returned as + a ((<(({XMLRPC::DateTime}))|URL:datetime.html>)) object and + a (({Struct})) is never returned, only a (({Hash})), the same for a (({Symbol})), where + always a (({String})) is returned. + A (({XMLRPC::Base64})) is returned as a (({String})) from xmlrpc4r version 1.6.1 on. + + If the remote procedure returned a fault-structure, then a + (({XMLRPC::FaultException})) exception is raised, which has two accessor-methods + (({faultCode})) and (({faultString})) of type (({Integer})) and (({String})). + +--- XMLRPC::Client#call2( method, *args ) + The difference between this method and (()) is, that + this method do ((*not*)) raise a (({XMLRPC::FaultException})) exception. + The method returns an array of two values. The first value indicates if + the second value is a return-value ((({true}))) or an object of type + (({XMLRPC::FaultException})). + Both are explained in (()). + + Simple to remember: The "2" in "call2" denotes the number of values it returns. + +--- XMLRPC::Client#multicall( *methods ) + You can use this method to execute several methods on a XMLRPC server which supports + the multi-call extension. + Example: + + s.multicall( + ['michael.add', 3, 4], + ['michael.sub', 4, 5] + ) + # => [7, -1] + +--- XMLRPC::Client#multicall2( *methods ) + Same as (()), but returns like (()) two parameters + instead of raising an (({XMLRPC::FaultException})). + +--- XMLRPC::Client#proxy( prefix, *args ) + Returns an object of class (({XMLRPC::Client::Proxy})), initialized with + ((|prefix|)) and ((|args|)). A proxy object returned by this method behaves + like (()), i.e. a call on that object will raise a + (({XMLRPC::FaultException})) when a fault-structure is returned by that call. + +--- XMLRPC::Client#proxy2( prefix, *args ) + Almost the same like (()) only that a call on the returned + (({XMLRPC::Client::Proxy})) object behaves like (()), i.e. + a call on that object will return two parameters. + + + + +--- XMLRPC::Client#call_async(...) +--- XMLRPC::Client#call2_async(...) +--- XMLRPC::Client#multicall_async(...) +--- XMLRPC::Client#multicall2_async(...) +--- XMLRPC::Client#proxy_async(...) +--- XMLRPC::Client#proxy2_async(...) + In contrast to corresponding methods without "_async", these can be + called concurrently and use for each request a new connection, where the + non-asynchronous counterparts use connection-alive (one connection for all requests) + if possible. + + Note, that you have to use Threads to call these methods concurrently. + The following example calls two methods concurrently: + + Thread.new { + p client.call_async("michael.add", 4, 5) + } + + Thread.new { + p client.call_async("michael.div", 7, 9) + } + + +--- XMLRPC::Client#timeout +--- XMLRPC::Client#user +--- XMLRPC::Client#password + Return the corresponding attributes. + +--- XMLRPC::Client#timeout= (new_timeout) +--- XMLRPC::Client#user= (new_user) +--- XMLRPC::Client#password= (new_password) + Set the corresponding attributes. + + +--- XMLRPC::Client#set_writer( writer ) + Sets the XML writer to use for generating XML output. + Should be an instance of a class from module (({XMLRPC::XMLWriter})). + If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. + +--- XMLRPC::Client#set_parser( parser ) + Sets the XML parser to use for parsing XML documents. + Should be an instance of a class from module (({XMLRPC::XMLParser})). + If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used. + +--- XMLRPC::Client#cookie +--- XMLRPC::Client#cookie= (cookieString) + Get and set the HTTP Cookie header. + +--- XMLRPC::Client#http_header_extra= (additionalHeaders) + Set extra HTTP headers that are included in the request. + +--- XMLRPC::Client#http_header_extra + Access the via (()) assigned header. + +--- XMLRPC::Client#http_last_response + Returns the (({Net::HTTPResponse})) object of the last RPC. + += XMLRPC::Client::Proxy +== Synopsis + require "xmlrpc/client" + + server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80) + + michael = server.proxy("michael") + michael2 = server.proxy("michael", 4) + + # both calls should return the same value '9'. + p michael.add(4,5) + p michael2.add(5) + +== Description +Class (({XMLRPC::Client::Proxy})) makes XML-RPC calls look nicer! +You can call any method onto objects of that class - the object handles +(({method_missing})) and will forward the method call to a XML-RPC server. +Don't use this class directly, but use instead method (()) or +(()). + +== Class Methods +--- XMLRPC::Client::Proxy.new( server, prefix, args=[], meth=:call, delim="." ) + Creates an object which provides (({method_missing})). + + ((|server|)) must be of type (({XMLRPC::Client})), which is the XML-RPC server to be used + for a XML-RPC call. ((|prefix|)) and ((|delim|)) will be prepended to the methodname + called onto this object. + + Parameter ((|meth|)) is the method (call, call2, call_async, call2_async) to use for + a RPC. + + ((|args|)) are arguments which are automatically given + to every XML-RPC call before the arguments provides through (({method_missing})). + +== Instance Methods +Every method call is forwarded to the XML-RPC server defined in (()). + +Note: Inherited methods from class (({Object})) cannot be used as XML-RPC names, because they get around +(({method_missing})). + + + += History + $Id: client.rb 16907 2008-06-07 16:54:15Z shyouhei $ + +=end + + + +require "xmlrpc/parser" +require "xmlrpc/create" +require "xmlrpc/config" +require "xmlrpc/utils" # ParserWriterChooseMixin +require "net/http" + +module XMLRPC + + class Client + + USER_AGENT = "XMLRPC::Client (Ruby #{RUBY_VERSION})" + + include ParserWriterChooseMixin + include ParseContentType + + + # Constructors ------------------------------------------------------------------- + + def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, + user=nil, password=nil, use_ssl=nil, timeout=nil) + + @http_header_extra = nil + @http_last_response = nil + @cookie = nil + + @host = host || "localhost" + @path = path || "/RPC2" + @proxy_host = proxy_host + @proxy_port = proxy_port + @proxy_host ||= 'localhost' if @proxy_port != nil + @proxy_port ||= 8080 if @proxy_host != nil + @use_ssl = use_ssl || false + @timeout = timeout || 30 + + if use_ssl + require "net/https" + @port = port || 443 + else + @port = port || 80 + end + + @user, @password = user, password + + set_auth + + # convert ports to integers + @port = @port.to_i if @port != nil + @proxy_port = @proxy_port.to_i if @proxy_port != nil + + # HTTP object for synchronous calls + Net::HTTP.version_1_2 + @http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) + @http.use_ssl = @use_ssl if @use_ssl + @http.read_timeout = @timeout + @http.open_timeout = @timeout + + @parser = nil + @create = nil + end + + + class << self + + def new2(uri, proxy=nil, timeout=nil) + if match = /^([^:]+):\/\/(([^@]+)@)?([^\/]+)(\/.*)?$/.match(uri) + proto = match[1] + user, passwd = (match[3] || "").split(":") + host, port = match[4].split(":") + path = match[5] + + if proto != "http" and proto != "https" + raise "Wrong protocol specified. Only http or https allowed!" + end + + else + raise "Wrong URI as parameter!" + end + + proxy_host, proxy_port = (proxy || "").split(":") + + self.new(host, path, port, proxy_host, proxy_port, user, passwd, (proto == "https"), timeout) + end + + alias new_from_uri new2 + + def new3(hash={}) + + # convert all keys into lowercase strings + h = {} + hash.each { |k,v| h[k.to_s.downcase] = v } + + self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'], h['user'], h['password'], + h['use_ssl'], h['timeout']) + end + + alias new_from_hash new3 + + end + + + # Attribute Accessors ------------------------------------------------------------------- + + # add additional HTTP headers to the request + attr_accessor :http_header_extra + + # makes last HTTP response accessible + attr_reader :http_last_response + + # Cookie support + attr_accessor :cookie + + + attr_reader :timeout, :user, :password + + def timeout=(new_timeout) + @timeout = new_timeout + @http.read_timeout = @timeout + @http.open_timeout = @timeout + end + + def user=(new_user) + @user = new_user + set_auth + end + + def password=(new_password) + @password = new_password + set_auth + end + + # Call methods -------------------------------------------------------------- + + def call(method, *args) + ok, param = call2(method, *args) + if ok + param + else + raise param + end + end + + def call2(method, *args) + request = create().methodCall(method, *args) + data = do_rpc(request, false) + parser().parseMethodResponse(data) + end + + def call_async(method, *args) + ok, param = call2_async(method, *args) + if ok + param + else + raise param + end + end + + def call2_async(method, *args) + request = create().methodCall(method, *args) + data = do_rpc(request, true) + parser().parseMethodResponse(data) + end + + + # Multicall methods -------------------------------------------------------------- + + def multicall(*methods) + ok, params = multicall2(*methods) + if ok + params + else + raise params + end + end + + def multicall2(*methods) + gen_multicall(methods, false) + end + + def multicall_async(*methods) + ok, params = multicall2_async(*methods) + if ok + params + else + raise params + end + end + + def multicall2_async(*methods) + gen_multicall(methods, true) + end + + + # Proxy generating methods ------------------------------------------ + + def proxy(prefix=nil, *args) + Proxy.new(self, prefix, args, :call) + end + + def proxy2(prefix=nil, *args) + Proxy.new(self, prefix, args, :call2) + end + + def proxy_async(prefix=nil, *args) + Proxy.new(self, prefix, args, :call_async) + end + + def proxy2_async(prefix=nil, *args) + Proxy.new(self, prefix, args, :call2_async) + end + + + private # ---------------------------------------------------------- + + def set_auth + if @user.nil? + @auth = nil + else + a = "#@user" + a << ":#@password" if @password != nil + @auth = ("Basic " + [a].pack("m")).chomp + end + end + + def do_rpc(request, async=false) + header = { + "User-Agent" => USER_AGENT, + "Content-Type" => "text/xml; charset=utf-8", + "Content-Length" => request.size.to_s, + "Connection" => (async ? "close" : "keep-alive") + } + + header["Cookie"] = @cookie if @cookie + header.update(@http_header_extra) if @http_header_extra + + if @auth != nil + # add authorization header + header["Authorization"] = @auth + end + + resp = nil + @http_last_response = nil + + if async + # use a new HTTP object for each call + Net::HTTP.version_1_2 + http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) + http.use_ssl = @use_ssl if @use_ssl + http.read_timeout = @timeout + http.open_timeout = @timeout + + # post request + http.start { + resp = http.post2(@path, request, header) + } + else + # reuse the HTTP object for each call => connection alive is possible + # we must start connection explicitely first time so that http.request + # does not assume that we don't want keepalive + @http.start if not @http.started? + + # post request + resp = @http.post2(@path, request, header) + end + + @http_last_response = resp + + data = resp.body + + if resp.code == "401" + # Authorization Required + raise "Authorization failed.\nHTTP-Error: #{resp.code} #{resp.message}" + elsif resp.code[0,1] != "2" + raise "HTTP-Error: #{resp.code} #{resp.message}" + end + + ct = parse_content_type(resp["Content-Type"]).first + if ct != "text/xml" + if ct == "text/html" + raise "Wrong content-type (received '#{ct}' but expected 'text/xml'): \n#{data}" + else + raise "Wrong content-type (received '#{ct}' but expected 'text/xml')" + end + end + + expected = resp["Content-Length"] || "" + if data.nil? or data.size == 0 + raise "Wrong size. Was #{data.size}, should be #{expected}" + elsif expected != "" and expected.to_i != data.size and resp["Transfer-Encoding"].nil? + raise "Wrong size. Was #{data.size}, should be #{expected}" + end + + c = resp["Set-Cookie"] + @cookie = c if c + + return data + end + + def gen_multicall(methods=[], async=false) + meth = :call2 + meth = :call2_async if async + + ok, params = self.send(meth, "system.multicall", + methods.collect {|m| {'methodName' => m[0], 'params' => m[1..-1]} } + ) + + if ok + params = params.collect do |param| + if param.is_a? Array + param[0] + elsif param.is_a? Hash + XMLRPC::FaultException.new(param["faultCode"], param["faultString"]) + else + raise "Wrong multicall return value" + end + end + end + + return ok, params + end + + + + class Proxy + + def initialize(server, prefix, args=[], meth=:call, delim=".") + @server = server + @prefix = prefix ? prefix + delim : "" + @args = args + @meth = meth + end + + def method_missing(mid, *args) + pre = @prefix + mid.to_s + arg = @args + args + @server.send(@meth, pre, *arg) + end + + end # class Proxy + + end # class Client + +end # module XMLRPC + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/config.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/config.rb new file mode 100644 index 00000000..52f7340a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/config.rb @@ -0,0 +1,40 @@ +# +# $Id: config.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# Configuration file for XML-RPC for Ruby +# + +module XMLRPC + + module Config + + DEFAULT_WRITER = XMLWriter::Simple # or XMLWriter::XMLParser + + # available parser: + # * XMLParser::NQXMLTreeParser + # * XMLParser::NQXMLStreamParser + # * XMLParser::XMLTreeParser + # * XMLParser::XMLStreamParser (fastest) + # * XMLParser::REXMLStreamParser + # * XMLParser::XMLScanStreamParser + DEFAULT_PARSER = XMLParser::REXMLStreamParser + + # enable tag + ENABLE_NIL_CREATE = false + ENABLE_NIL_PARSER = false + + # allows integers greater than 32-bit if true + ENABLE_BIGINT = false + + # enable marshalling ruby objects which include XMLRPC::Marshallable + ENABLE_MARSHALLING = true + + # enable multiCall extension by default + ENABLE_MULTICALL = false + + # enable Introspection extension by default + ENABLE_INTROSPECTION = false + + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/create.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/create.rb new file mode 100644 index 00000000..0b007c56 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/create.rb @@ -0,0 +1,290 @@ +# +# Creates XML-RPC call/response documents +# +# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) +# +# $Id: create.rb 11820 2007-02-23 03:47:59Z knu $ +# + +require "date" +require "xmlrpc/base64" + +module XMLRPC + + module XMLWriter + + class Abstract + def ele(name, *children) + element(name, nil, *children) + end + + def tag(name, txt) + element(name, nil, text(txt)) + end + end + + + class Simple < Abstract + + def document_to_str(doc) + doc + end + + def document(*params) + params.join("") + end + + def pi(name, *params) + "" + end + + def element(name, attrs, *children) + raise "attributes not yet implemented" unless attrs.nil? + if children.empty? + "<#{name}/>" + else + "<#{name}>" + children.join("") + "" + end + end + + def text(txt) + cleaned = txt.dup + cleaned.gsub!(/&/, '&') + cleaned.gsub!(//, '>') + cleaned + end + + end # class Simple + + + class XMLParser < Abstract + + def initialize + require "xmltreebuilder" + end + + def document_to_str(doc) + doc.to_s + end + + def document(*params) + XML::SimpleTree::Document.new(*params) + end + + def pi(name, *params) + XML::SimpleTree::ProcessingInstruction.new(name, *params) + end + + def element(name, attrs, *children) + XML::SimpleTree::Element.new(name, attrs, *children) + end + + def text(txt) + XML::SimpleTree::Text.new(txt) + end + + end # class XMLParser + + Classes = [Simple, XMLParser] + + # yields an instance of each installed XML writer + def self.each_installed_writer + XMLRPC::XMLWriter::Classes.each do |klass| + begin + yield klass.new + rescue LoadError + end + end + end + + end # module XMLWriter + + class Create + + def initialize(xml_writer = nil) + @writer = xml_writer || Config::DEFAULT_WRITER.new + end + + + def methodCall(name, *params) + name = name.to_s + + if name !~ /[a-zA-Z0-9_.:\/]+/ + raise ArgumentError, "Wrong XML-RPC method-name" + end + + parameter = params.collect do |param| + @writer.ele("param", conv2value(param)) + end + + tree = @writer.document( + @writer.pi("xml", 'version="1.0"'), + @writer.ele("methodCall", + @writer.tag("methodName", name), + @writer.ele("params", *parameter) + ) + ) + + @writer.document_to_str(tree) + "\n" + end + + + + # + # generates a XML-RPC methodResponse document + # + # if is_ret == false then the params array must + # contain only one element, which is a structure + # of a fault return-value. + # + # if is_ret == true then a normal + # return-value of all the given params is created. + # + def methodResponse(is_ret, *params) + + if is_ret + resp = params.collect do |param| + @writer.ele("param", conv2value(param)) + end + + resp = [@writer.ele("params", *resp)] + else + if params.size != 1 or params[0] === XMLRPC::FaultException + raise ArgumentError, "no valid fault-structure given" + end + resp = @writer.ele("fault", conv2value(params[0].to_h)) + end + + + tree = @writer.document( + @writer.pi("xml", 'version="1.0"'), + @writer.ele("methodResponse", resp) + ) + + @writer.document_to_str(tree) + "\n" + end + + + + ##################################### + private + ##################################### + + # + # converts a Ruby object into + # a XML-RPC tag + # + def conv2value(param) + + val = case param + when Fixnum + @writer.tag("i4", param.to_s) + + when Bignum + if Config::ENABLE_BIGINT + @writer.tag("i4", param.to_s) + else + if param >= -(2**31) and param <= (2**31-1) + @writer.tag("i4", param.to_s) + else + raise "Bignum is too big! Must be signed 32-bit integer!" + end + end + when TrueClass, FalseClass + @writer.tag("boolean", param ? "1" : "0") + + when String + @writer.tag("string", param) + + when Symbol + @writer.tag("string", param.to_s) + + when NilClass + if Config::ENABLE_NIL_CREATE + @writer.ele("nil") + else + raise "Wrong type NilClass. Not allowed!" + end + + when Float + @writer.tag("double", param.to_s) + + when Struct + h = param.members.collect do |key| + value = param[key] + @writer.ele("member", + @writer.tag("name", key.to_s), + conv2value(value) + ) + end + + @writer.ele("struct", *h) + + when Hash + # TODO: can a Hash be empty? + + h = param.collect do |key, value| + @writer.ele("member", + @writer.tag("name", key.to_s), + conv2value(value) + ) + end + + @writer.ele("struct", *h) + + when Array + # TODO: can an Array be empty? + a = param.collect {|v| conv2value(v) } + + @writer.ele("array", + @writer.ele("data", *a) + ) + + when Time, Date, ::DateTime + @writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S")) + + when XMLRPC::DateTime + @writer.tag("dateTime.iso8601", + format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a)) + + when XMLRPC::Base64 + @writer.tag("base64", param.encoded) + + else + if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable + # convert Ruby object into Hash + ret = {"___class___" => param.class.name} + param.instance_variables.each {|v| + name = v[1..-1] + val = param.instance_variable_get(v) + + if val.nil? + ret[name] = val if Config::ENABLE_NIL_CREATE + else + ret[name] = val + end + } + return conv2value(ret) + else + ok, pa = wrong_type(param) + if ok + return conv2value(pa) + else + raise "Wrong type!" + end + end + end + + @writer.ele("value", val) + end + + def wrong_type(value) + false + end + + + end # class Create + +end # module XMLRPC + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/datetime.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/datetime.rb new file mode 100644 index 00000000..86342c20 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/datetime.rb @@ -0,0 +1,142 @@ +=begin += xmlrpc/datetime.rb +Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) + +Released under the same term of license as Ruby. + += Classes +* (()) + += XMLRPC::DateTime +== Description +This class is important to handle XMLRPC (('dateTime.iso8601')) values, +correcly, because normal UNIX-dates (class (({Date}))) only handle dates +from year 1970 on, and class (({Time})) handles dates without the time +component. (({XMLRPC::DateTime})) is able to store a XMLRPC +(('dateTime.iso8601')) value correctly. + +== Class Methods +--- XMLRPC::DateTime.new( year, month, day, hour, min, sec ) + Creates a new (({XMLRPC::DateTime})) instance with the + parameters ((|year|)), ((|month|)), ((|day|)) as date and + ((|hour|)), ((|min|)), ((|sec|)) as time. + Raises (({ArgumentError})) if a parameter is out of range, or ((|year|)) is not + of type (({Integer})). + +== Instance Methods +--- XMLRPC::DateTime#year +--- XMLRPC::DateTime#month +--- XMLRPC::DateTime#day +--- XMLRPC::DateTime#hour +--- XMLRPC::DateTime#min +--- XMLRPC::DateTime#sec + Return the value of the specified date/time component. + +--- XMLRPC::DateTime#mon + Alias for (()). + +--- XMLRPC::DateTime#year=( value ) +--- XMLRPC::DateTime#month=( value ) +--- XMLRPC::DateTime#day=( value ) +--- XMLRPC::DateTime#hour=( value ) +--- XMLRPC::DateTime#min=( value ) +--- XMLRPC::DateTime#sec=( value ) + Set ((|value|)) as the new date/time component. + Raises (({ArgumentError})) if ((|value|)) is out of range, or in the case + of (({XMLRPC::DateTime#year=})) if ((|value|)) is not of type (({Integer})). + +--- XMLRPC::DateTime#mon=( value ) + Alias for (()). + +--- XMLRPC::DateTime#to_time + Return a (({Time})) object of the date/time which (({self})) represents. + If the (('year')) is below 1970, this method returns (({nil})), + because (({Time})) cannot handle years below 1970. + The used timezone is GMT. + +--- XMLRPC::DateTime#to_date + Return a (({Date})) object of the date which (({self})) represents. + The (({Date})) object do ((*not*)) contain the time component (only date). + +--- XMLRPC::DateTime#to_a + Returns all date/time components in an array. + Returns (({[year, month, day, hour, min, sec]})). +=end + +require "date" + +module XMLRPC + +class DateTime + + attr_reader :year, :month, :day, :hour, :min, :sec + + def year= (value) + raise ArgumentError, "date/time out of range" unless value.is_a? Integer + @year = value + end + + def month= (value) + raise ArgumentError, "date/time out of range" unless (1..12).include? value + @month = value + end + + def day= (value) + raise ArgumentError, "date/time out of range" unless (1..31).include? value + @day = value + end + + def hour= (value) + raise ArgumentError, "date/time out of range" unless (0..24).include? value + @hour = value + end + + def min= (value) + raise ArgumentError, "date/time out of range" unless (0..59).include? value + @min = value + end + + def sec= (value) + raise ArgumentError, "date/time out of range" unless (0..59).include? value + @sec = value + end + + alias mon month + alias mon= month= + + + def initialize(year, month, day, hour, min, sec) + self.year, self.month, self.day = year, month, day + self.hour, self.min, self.sec = hour, min, sec + end + + def to_time + if @year >= 1970 + Time.gm(*to_a) + else + nil + end + end + + def to_date + Date.new(*to_a[0,3]) + end + + def to_a + [@year, @month, @day, @hour, @min, @sec] + end + + def ==(o) + Array(self) == Array(o) + end + +end + + +end # module XMLRPC + + +=begin += History + $Id: datetime.rb 11708 2007-02-12 23:01:19Z shyouhei $ +=end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/httpserver.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/httpserver.rb new file mode 100644 index 00000000..d98db896 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/httpserver.rb @@ -0,0 +1,178 @@ +# +# Implements a simple HTTP-server by using John W. Small's (jsmall@laser.net) +# ruby-generic-server. +# +# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) +# +# $Id: httpserver.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# + + +require "gserver" + +class HttpServer < GServer + + ## + # handle_obj specifies the object, that receives calls to request_handler + # and ip_auth_handler + def initialize(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4, + stdlog = $stdout, audit = true, debug = true) + @handler = handle_obj + super(port, host, maxConnections, stdlog, audit, debug) + end + +private + + # Constants ----------------------------------------------- + + CRLF = "\r\n" + HTTP_PROTO = "HTTP/1.0" + SERVER_NAME = "HttpServer (Ruby #{RUBY_VERSION})" + + DEFAULT_HEADER = { + "Server" => SERVER_NAME + } + + ## + # Mapping of status code and error message + # + StatusCodeMapping = { + 200 => "OK", + 400 => "Bad Request", + 403 => "Forbidden", + 405 => "Method Not Allowed", + 411 => "Length Required", + 500 => "Internal Server Error" + } + + # Classes ------------------------------------------------- + + class Request + attr_reader :data, :header, :method, :path, :proto + + def initialize(data, method=nil, path=nil, proto=nil) + @header, @data = Table.new, data + @method, @path, @proto = method, path, proto + end + + def content_length + len = @header['Content-Length'] + return nil if len.nil? + return len.to_i + end + + end + + class Response + attr_reader :header + attr_accessor :body, :status, :status_message + + def initialize(status=200) + @status = status + @status_message = nil + @header = Table.new + end + end + + + ## + # a case-insensitive Hash class for HTTP header + # + class Table + include Enumerable + + def initialize(hash={}) + @hash = hash + update(hash) + end + + def [](key) + @hash[key.to_s.capitalize] + end + + def []=(key, value) + @hash[key.to_s.capitalize] = value + end + + def update(hash) + hash.each {|k,v| self[k] = v} + self + end + + def each + @hash.each {|k,v| yield k.capitalize, v } + end + + def writeTo(port) + each { |k,v| port << "#{k}: #{v}" << CRLF } + end + end # class Table + + + # Helper Methods ------------------------------------------ + + def http_header(header=nil) + new_header = Table.new(DEFAULT_HEADER) + new_header.update(header) unless header.nil? + + new_header["Connection"] = "close" + new_header["Date"] = http_date(Time.now) + + new_header + end + + def http_date( aTime ) + aTime.gmtime.strftime( "%a, %d %b %Y %H:%M:%S GMT" ) + end + + def http_resp(status_code, status_message=nil, header=nil, body=nil) + status_message ||= StatusCodeMapping[status_code] + + str = "" + str << "#{HTTP_PROTO} #{status_code} #{status_message}" << CRLF + http_header(header).writeTo(str) + str << CRLF + str << body unless body.nil? + str + end + + # Main Serve Loop ----------------------------------------- + + def serve(io) + # perform IP authentification + unless @handler.ip_auth_handler(io) + io << http_resp(403, "Forbidden") + return + end + + # parse first line + if io.gets =~ /^(\S+)\s+(\S+)\s+(\S+)/ + request = Request.new(io, $1, $2, $3) + else + io << http_resp(400, "Bad Request") + return + end + + # parse HTTP headers + while (line=io.gets) !~ /^(\n|\r)/ + if line =~ /^([\w-]+):\s*(.*)$/ + request.header[$1] = $2.strip + end + end + + io.binmode + response = Response.new + + # execute request handler + @handler.request_handler(request, response) + + # write response back to the client + io << http_resp(response.status, response.status_message, + response.header, response.body) + + rescue Exception => e + io << http_resp(500, "Internal Server Error") + end + +end # class HttpServer + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/marshal.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/marshal.rb new file mode 100644 index 00000000..ba8c720a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/marshal.rb @@ -0,0 +1,76 @@ +# +# Marshalling of XML-RPC methodCall and methodResponse +# +# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) +# +# $Id: marshal.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# + +require "xmlrpc/parser" +require "xmlrpc/create" +require "xmlrpc/config" +require "xmlrpc/utils" + +module XMLRPC + + class Marshal + include ParserWriterChooseMixin + + # class methods ------------------------------- + + class << self + + def dump_call( methodName, *params ) + new.dump_call( methodName, *params ) + end + + def dump_response( param ) + new.dump_response( param ) + end + + def load_call( stringOrReadable ) + new.load_call( stringOrReadable ) + end + + def load_response( stringOrReadable ) + new.load_response( stringOrReadable ) + end + + alias dump dump_response + alias load load_response + + end # class self + + # instance methods ---------------------------- + + def initialize( parser = nil, writer = nil ) + set_parser( parser ) + set_writer( writer ) + end + + def dump_call( methodName, *params ) + create.methodCall( methodName, *params ) + end + + def dump_response( param ) + create.methodResponse( ! param.kind_of?( XMLRPC::FaultException ) , param ) + end + + ## + # returns [ methodname, params ] + # + def load_call( stringOrReadable ) + parser.parseMethodCall( stringOrReadable ) + end + + ## + # returns paramOrFault + # + def load_response( stringOrReadable ) + parser.parseMethodResponse( stringOrReadable )[1] + end + + end # class Marshal + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/parser.rb new file mode 100644 index 00000000..5c0d9a45 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/parser.rb @@ -0,0 +1,813 @@ +# +# Parser for XML-RPC call and response +# +# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) +# +# $Id: parser.rb 16907 2008-06-07 16:54:15Z shyouhei $ +# + + +require "date" +require "xmlrpc/base64" +require "xmlrpc/datetime" + + +# add some methods to NQXML::Node +module NQXML + class Node + + def removeChild(node) + @children.delete(node) + end + def childNodes + @children + end + def hasChildNodes + not @children.empty? + end + def [] (index) + @children[index] + end + + def nodeType + if @entity.instance_of? NQXML::Text then :TEXT + elsif @entity.instance_of? NQXML::Comment then :COMMENT + #elsif @entity.instance_of? NQXML::Element then :ELEMENT + elsif @entity.instance_of? NQXML::Tag then :ELEMENT + else :ELSE + end + end + + def nodeValue + #TODO: error when wrong Entity-type + @entity.text + end + def nodeName + #TODO: error when wrong Entity-type + @entity.name + end + end # class Node +end # module NQXML + +module XMLRPC + + class FaultException < StandardError + attr_reader :faultCode, :faultString + + alias message faultString + + def initialize(faultCode, faultString) + @faultCode = faultCode + @faultString = faultString + end + + # returns a hash + def to_h + {"faultCode" => @faultCode, "faultString" => @faultString} + end + end + + module Convert + def self.int(str) + str.to_i + end + + def self.boolean(str) + case str + when "0" then false + when "1" then true + else + raise "RPC-value of type boolean is wrong" + end + end + + def self.double(str) + str.to_f + end + + def self.dateTime(str) + case str + when /^(-?\d\d\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(?:Z|([+-])(\d\d):?(\d\d))?$/ + a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i} + if $7 + ofs = $8.to_i*3600 + $9.to_i*60 + ofs = -ofs if $7=='+' + utc = Time.utc(*a) + ofs + a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ] + end + XMLRPC::DateTime.new(*a) + when /^(-?\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(Z|([+-]\d\d):(\d\d))?$/ + a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i} + if a[0] < 70 + a[0] += 2000 + else + a[0] += 1900 + end + if $7 + ofs = $8.to_i*3600 + $9.to_i*60 + ofs = -ofs if $7=='+' + utc = Time.utc(*a) + ofs + a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ] + end + XMLRPC::DateTime.new(*a) + else + raise "wrong dateTime.iso8601 format " + str + end + end + + def self.base64(str) + XMLRPC::Base64.decode(str) + end + + def self.struct(hash) + # convert to marhalled object + klass = hash["___class___"] + if klass.nil? or Config::ENABLE_MARSHALLING == false + hash + else + begin + mod = Module + klass.split("::").each {|const| mod = mod.const_get(const.strip)} + + obj = mod.allocate + + hash.delete "___class___" + hash.each {|key, value| + obj.instance_variable_set("@#{ key }", value) if key =~ /^([\w_][\w_0-9]*)$/ + } + obj + rescue + hash + end + end + end + + def self.fault(hash) + if hash.kind_of? Hash and hash.size == 2 and + hash.has_key? "faultCode" and hash.has_key? "faultString" and + hash["faultCode"].kind_of? Integer and hash["faultString"].kind_of? String + + XMLRPC::FaultException.new(hash["faultCode"], hash["faultString"]) + else + raise "wrong fault-structure: #{hash.inspect}" + end + end + + end # module Convert + + module XMLParser + + class AbstractTreeParser + + def parseMethodResponse(str) + methodResponse_document(createCleanedTree(str)) + end + + def parseMethodCall(str) + methodCall_document(createCleanedTree(str)) + end + + private + + # + # remove all whitespaces but in the tags i4, int, boolean.... + # and all comments + # + def removeWhitespacesAndComments(node) + remove = [] + childs = node.childNodes.to_a + childs.each do |nd| + case _nodeType(nd) + when :TEXT + # TODO: add nil? + unless %w(i4 int boolean string double dateTime.iso8601 base64).include? node.nodeName + + if node.nodeName == "value" + if not node.childNodes.to_a.detect {|n| _nodeType(n) == :ELEMENT}.nil? + remove << nd if nd.nodeValue.strip == "" + end + else + remove << nd if nd.nodeValue.strip == "" + end + end + when :COMMENT + remove << nd + else + removeWhitespacesAndComments(nd) + end + end + + remove.each { |i| node.removeChild(i) } + end + + + def nodeMustBe(node, name) + cmp = case name + when Array + name.include?(node.nodeName) + when String + name == node.nodeName + else + raise "error" + end + + if not cmp then + raise "wrong xml-rpc (name)" + end + + node + end + + # + # returns, when successfully the only child-node + # + def hasOnlyOneChild(node, name=nil) + if node.childNodes.to_a.size != 1 + raise "wrong xml-rpc (size)" + end + if name != nil then + nodeMustBe(node.firstChild, name) + end + end + + + def assert(b) + if not b then + raise "assert-fail" + end + end + + # the node `node` has empty string or string + def text_zero_one(node) + nodes = node.childNodes.to_a.size + + if nodes == 1 + text(node.firstChild) + elsif nodes == 0 + "" + else + raise "wrong xml-rpc (size)" + end + end + + + def integer(node) + #TODO: check string for float because to_i returnsa + # 0 when wrong string + nodeMustBe(node, %w(i4 int)) + hasOnlyOneChild(node) + + Convert.int(text(node.firstChild)) + end + + def boolean(node) + nodeMustBe(node, "boolean") + hasOnlyOneChild(node) + + Convert.boolean(text(node.firstChild)) + end + + def v_nil(node) + nodeMustBe(node, "nil") + assert( node.childNodes.to_a.size == 0 ) + nil + end + + def string(node) + nodeMustBe(node, "string") + text_zero_one(node) + end + + def double(node) + #TODO: check string for float because to_f returnsa + # 0.0 when wrong string + nodeMustBe(node, "double") + hasOnlyOneChild(node) + + Convert.double(text(node.firstChild)) + end + + def dateTime(node) + nodeMustBe(node, "dateTime.iso8601") + hasOnlyOneChild(node) + + Convert.dateTime( text(node.firstChild) ) + end + + def base64(node) + nodeMustBe(node, "base64") + #hasOnlyOneChild(node) + + Convert.base64(text_zero_one(node)) + end + + def member(node) + nodeMustBe(node, "member") + assert( node.childNodes.to_a.size == 2 ) + + [ name(node[0]), value(node[1]) ] + end + + def name(node) + nodeMustBe(node, "name") + #hasOnlyOneChild(node) + text_zero_one(node) + end + + def array(node) + nodeMustBe(node, "array") + hasOnlyOneChild(node, "data") + data(node.firstChild) + end + + def data(node) + nodeMustBe(node, "data") + + node.childNodes.to_a.collect do |val| + value(val) + end + end + + def param(node) + nodeMustBe(node, "param") + hasOnlyOneChild(node, "value") + value(node.firstChild) + end + + def methodResponse(node) + nodeMustBe(node, "methodResponse") + hasOnlyOneChild(node, %w(params fault)) + child = node.firstChild + + case child.nodeName + when "params" + [ true, params(child,false) ] + when "fault" + [ false, fault(child) ] + else + raise "unexpected error" + end + + end + + def methodName(node) + nodeMustBe(node, "methodName") + hasOnlyOneChild(node) + text(node.firstChild) + end + + def params(node, call=true) + nodeMustBe(node, "params") + + if call + node.childNodes.to_a.collect do |n| + param(n) + end + else # response (only one param) + hasOnlyOneChild(node) + param(node.firstChild) + end + end + + def fault(node) + nodeMustBe(node, "fault") + hasOnlyOneChild(node, "value") + f = value(node.firstChild) + Convert.fault(f) + end + + + + # _nodeType is defined in the subclass + def text(node) + assert( _nodeType(node) == :TEXT ) + assert( node.hasChildNodes == false ) + assert( node.nodeValue != nil ) + + node.nodeValue.to_s + end + + def struct(node) + nodeMustBe(node, "struct") + + hash = {} + node.childNodes.to_a.each do |me| + n, v = member(me) + hash[n] = v + end + + Convert.struct(hash) + end + + + def value(node) + nodeMustBe(node, "value") + nodes = node.childNodes.to_a.size + if nodes == 0 + return "" + elsif nodes > 1 + raise "wrong xml-rpc (size)" + end + + child = node.firstChild + + case _nodeType(child) + when :TEXT + text_zero_one(node) + when :ELEMENT + case child.nodeName + when "i4", "int" then integer(child) + when "boolean" then boolean(child) + when "string" then string(child) + when "double" then double(child) + when "dateTime.iso8601" then dateTime(child) + when "base64" then base64(child) + when "struct" then struct(child) + when "array" then array(child) + when "nil" + if Config::ENABLE_NIL_PARSER + v_nil(child) + else + raise "wrong/unknown XML-RPC type 'nil'" + end + else + raise "wrong/unknown XML-RPC type" + end + else + raise "wrong type of node" + end + + end + + def methodCall(node) + nodeMustBe(node, "methodCall") + assert( (1..2).include?( node.childNodes.to_a.size ) ) + name = methodName(node[0]) + + if node.childNodes.to_a.size == 2 then + pa = params(node[1]) + else # no parameters given + pa = [] + end + [name, pa] + end + + end # module TreeParserMixin + + class AbstractStreamParser + def parseMethodResponse(str) + parser = @parser_class.new + parser.parse(str) + raise "No valid method response!" if parser.method_name != nil + if parser.fault != nil + # is a fault structure + [false, parser.fault] + else + # is a normal return value + raise "Missing return value!" if parser.params.size == 0 + raise "Too many return values. Only one allowed!" if parser.params.size > 1 + [true, parser.params[0]] + end + end + + def parseMethodCall(str) + parser = @parser_class.new + parser.parse(str) + raise "No valid method call - missing method name!" if parser.method_name.nil? + [parser.method_name, parser.params] + end + end + + module StreamParserMixin + attr_reader :params + attr_reader :method_name + attr_reader :fault + + def initialize(*a) + super(*a) + @params = [] + @values = [] + @val_stack = [] + + @names = [] + @name = [] + + @structs = [] + @struct = {} + + @method_name = nil + @fault = nil + + @data = nil + end + + def startElement(name, attrs=[]) + @data = nil + case name + when "value" + @value = nil + when "nil" + raise "wrong/unknown XML-RPC type 'nil'" unless Config::ENABLE_NIL_PARSER + @value = :nil + when "array" + @val_stack << @values + @values = [] + when "struct" + @names << @name + @name = [] + + @structs << @struct + @struct = {} + end + end + + def endElement(name) + @data ||= "" + case name + when "string" + @value = @data + when "i4", "int" + @value = Convert.int(@data) + when "boolean" + @value = Convert.boolean(@data) + when "double" + @value = Convert.double(@data) + when "dateTime.iso8601" + @value = Convert.dateTime(@data) + when "base64" + @value = Convert.base64(@data) + when "value" + @value = @data if @value.nil? + @values << (@value == :nil ? nil : @value) + when "array" + @value = @values + @values = @val_stack.pop + when "struct" + @value = Convert.struct(@struct) + + @name = @names.pop + @struct = @structs.pop + when "name" + @name[0] = @data + when "member" + @struct[@name[0]] = @values.pop + + when "param" + @params << @values[0] + @values = [] + + when "fault" + @fault = Convert.fault(@values[0]) + + when "methodName" + @method_name = @data + end + + @data = nil + end + + def character(data) + if @data + @data << data + else + @data = data + end + end + + end # module StreamParserMixin + + # --------------------------------------------------------------------------- + class XMLStreamParser < AbstractStreamParser + def initialize + require "xmlparser" + @parser_class = Class.new(::XMLParser) { + include StreamParserMixin + } + end + end # class XMLStreamParser + # --------------------------------------------------------------------------- + class NQXMLStreamParser < AbstractStreamParser + def initialize + require "nqxml/streamingparser" + @parser_class = XMLRPCParser + end + + class XMLRPCParser + include StreamParserMixin + + def parse(str) + parser = NQXML::StreamingParser.new(str) + parser.each do |ele| + case ele + when NQXML::Text + @data = ele.text + #character(ele.text) + when NQXML::Tag + if ele.isTagEnd + endElement(ele.name) + else + startElement(ele.name, ele.attrs) + end + end + end # do + end # method parse + end # class XMLRPCParser + + end # class NQXMLStreamParser + # --------------------------------------------------------------------------- + class XMLTreeParser < AbstractTreeParser + + def initialize + require "xmltreebuilder" + + # The new XMLParser library (0.6.2+) uses a slightly different DOM implementation. + # The following code removes the differences between both versions. + if defined? XML::DOM::Builder + return if defined? XML::DOM::Node::DOCUMENT # code below has been already executed + klass = XML::DOM::Node + klass.const_set("DOCUMENT", klass::DOCUMENT_NODE) + klass.const_set("TEXT", klass::TEXT_NODE) + klass.const_set("COMMENT", klass::COMMENT_NODE) + klass.const_set("ELEMENT", klass::ELEMENT_NODE) + end + end + + private + + def _nodeType(node) + tp = node.nodeType + if tp == XML::SimpleTree::Node::TEXT then :TEXT + elsif tp == XML::SimpleTree::Node::COMMENT then :COMMENT + elsif tp == XML::SimpleTree::Node::ELEMENT then :ELEMENT + else :ELSE + end + end + + + def methodResponse_document(node) + assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT ) + hasOnlyOneChild(node, "methodResponse") + + methodResponse(node.firstChild) + end + + def methodCall_document(node) + assert( node.nodeType == XML::SimpleTree::Node::DOCUMENT ) + hasOnlyOneChild(node, "methodCall") + + methodCall(node.firstChild) + end + + def createCleanedTree(str) + doc = XML::SimpleTreeBuilder.new.parse(str) + doc.documentElement.normalize + removeWhitespacesAndComments(doc) + doc + end + + end # class XMLParser + # --------------------------------------------------------------------------- + class NQXMLTreeParser < AbstractTreeParser + + def initialize + require "nqxml/treeparser" + end + + private + + def _nodeType(node) + node.nodeType + end + + def methodResponse_document(node) + methodResponse(node) + end + + def methodCall_document(node) + methodCall(node) + end + + def createCleanedTree(str) + doc = ::NQXML::TreeParser.new(str).document.rootNode + removeWhitespacesAndComments(doc) + doc + end + + end # class NQXMLTreeParser + # --------------------------------------------------------------------------- + class REXMLStreamParser < AbstractStreamParser + def initialize + require "rexml/document" + @parser_class = StreamListener + end + + class StreamListener + include StreamParserMixin + + alias :tag_start :startElement + alias :tag_end :endElement + alias :text :character + alias :cdata :character + + def method_missing(*a) + # ignore + end + + def parse(str) + parser = REXML::Document.parse_stream(str, self) + end + end + + end + # --------------------------------------------------------------------------- + class XMLScanStreamParser < AbstractStreamParser + def initialize + require "xmlscan/parser" + @parser_class = XMLScanParser + end + + class XMLScanParser + include StreamParserMixin + + Entities = { + "lt" => "<", + "gt" => ">", + "amp" => "&", + "quot" => '"', + "apos" => "'" + } + + def parse(str) + parser = XMLScan::XMLParser.new(self) + parser.parse(str) + end + + alias :on_stag :startElement + alias :on_etag :endElement + + def on_stag_end(name); end + + def on_stag_end_empty(name) + startElement(name) + endElement(name) + end + + def on_chardata(str) + character(str) + end + + def on_cdata(str) + character(str) + end + + def on_entityref(ent) + str = Entities[ent] + if str + character(str) + else + raise "unknown entity" + end + end + + def on_charref(code) + character(code.chr) + end + + def on_charref_hex(code) + character(code.chr) + end + + def method_missing(*a) + end + + # TODO: call/implement? + # valid_name? + # valid_chardata? + # valid_char? + # parse_error + + end + end + # --------------------------------------------------------------------------- + XMLParser = XMLTreeParser + NQXMLParser = NQXMLTreeParser + + Classes = [XMLStreamParser, XMLTreeParser, + NQXMLStreamParser, NQXMLTreeParser, + REXMLStreamParser, XMLScanStreamParser] + + # yields an instance of each installed parser + def self.each_installed_parser + XMLRPC::XMLParser::Classes.each do |klass| + begin + yield klass.new + rescue LoadError + end + end + end + + end # module XMLParser + + +end # module XMLRPC + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/server.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/server.rb new file mode 100644 index 00000000..d2974313 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/server.rb @@ -0,0 +1,780 @@ +=begin += xmlrpc/server.rb +Copyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de) + +Released under the same term of license as Ruby. + += Classes +* (()) +* (()) +* (()) +* (()) +* (()) + += XMLRPC::BasicServer +== Description +Is the base class for all XML-RPC server-types (CGI, standalone). +You can add handler and set a default handler. +Do not use this server, as this is/should be an abstract class. + +=== How the method to call is found +The arity (number of accepted arguments) of a handler (method or (({Proc})) object) is +compared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)). +A handler is only called if it accepts the number of arguments, otherwise the search +for another handler will go on. When at the end no handler was found, +the (()) will be called. +With this technique it is possible to do overloading by number of parameters, but +only for (({Proc})) handler, because you cannot define two methods of the same name in +the same class. + + +== Class Methods +--- XMLRPC::BasicServer.new( class_delim="." ) + Creates a new (({XMLRPC::BasicServer})) instance, which should not be + done, because (({XMLRPC::BasicServer})) is an abstract class. This + method should be called from a subclass indirectly by a (({super})) call + in the method (({initialize})). The paramter ((|class_delim|)) is used + in (()) when an object is + added as handler, to delimit the object-prefix and the method-name. + +== Instance Methods +--- XMLRPC::BasicServer#add_handler( name, signature=nil, help=nil ) { aBlock } + Adds ((|aBlock|)) to the list of handlers, with ((|name|)) as the name of the method. + Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified, + where ((|signature|)) is either an Array containing strings each representing a type of it's + signature (the first is the return value) or an Array of Arrays if the method has multiple + signatures. Value type-names are "int, boolean, double, string, dateTime.iso8601, base64, array, struct". + + Parameter ((|help|)) is a String with informations about how to call this method etc. + + A handler method or code-block can return the types listed at + (()). + When a method fails, it can tell it the client by throwing an + (({XMLRPC::FaultException})) like in this example: + s.add_handler("michael.div") do |a,b| + if b == 0 + raise XMLRPC::FaultException.new(1, "division by zero") + else + a / b + end + end + The client gets in the case of (({b==0})) an object back of type + (({XMLRPC::FaultException})) that has a ((|faultCode|)) and ((|faultString|)) + field. + +--- XMLRPC::BasicServer#add_handler( prefix, obj ) + This is the second form of (()). + To add an object write: + server.add_handler("michael", MyHandlerClass.new) + All public methods of (({MyHandlerClass})) are accessible to + the XML-RPC clients by (('michael."name of method"')). This is + where the ((|class_delim|)) in (()) + has it's role, a XML-RPC method-name is defined by + ((|prefix|)) + ((|class_delim|)) + (('"name of method"')). + +--- XMLRPC::BasicServer#add_handler( interface, obj ) + This is the third form of (()). + + Use (({XMLRPC::interface})) to generate an ServiceInterface object, which + represents an interface (with signature and help text) for a handler class. + + Parameter ((|interface|)) must be of type (({XMLRPC::ServiceInterface})). + Adds all methods of ((|obj|)) which are defined in ((|interface|)) to the + server. + + This is the recommended way of adding services to a server! + + +--- XMLRPC::BasicServer#get_default_handler + Returns the default-handler, which is called when no handler for + a method-name is found. + It is a (({Proc})) object or (({nil})). + +--- XMLRPC::BasicServer#set_default_handler ( &handler ) + Sets ((|handler|)) as the default-handler, which is called when + no handler for a method-name is found. ((|handler|)) is a code-block. + The default-handler is called with the (XML-RPC) method-name as first argument, and + the other arguments are the parameters given by the client-call. + + If no block is specified the default of (({XMLRPC::BasicServer})) is used, which raises a + XMLRPC::FaultException saying "method missing". + + +--- XMLRPC::BasicServer#set_writer( writer ) + Sets the XML writer to use for generating XML output. + Should be an instance of a class from module (({XMLRPC::XMLWriter})). + If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. + +--- XMLRPC::BasicServer#set_parser( parser ) + Sets the XML parser to use for parsing XML documents. + Should be an instance of a class from module (({XMLRPC::XMLParser})). + If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used. + +--- XMLRPC::BasicServer#add_introspection + Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp", + where only the first one works. + +--- XMLRPC::BasicServer#add_multicall + Adds the multi-call handler "system.multicall". + +--- XMLRPC::BasicServer#get_service_hook + Returns the service-hook, which is called on each service request (RPC) unless it's (({nil})). + +--- XMLRPC::BasicServer#set_service_hook ( &handler ) + A service-hook is called for each service request (RPC). + You can use a service-hook for example to wrap existing methods and catch exceptions of them or + convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter + ((|handler|)) . + + The service-hook is called with a (({Proc})) object and with the parameters for this (({Proc})). + An example: + + server.set_service_hook {|obj, *args| + begin + ret = obj.call(*args) # call the original service-method + # could convert the return value + resuce + # rescue exceptions + end + } + +=end + + + +require "xmlrpc/parser" +require "xmlrpc/create" +require "xmlrpc/config" +require "xmlrpc/utils" # ParserWriterChooseMixin + + + +module XMLRPC + + +class BasicServer + + include ParserWriterChooseMixin + include ParseContentType + + ERR_METHOD_MISSING = 1 + ERR_UNCAUGHT_EXCEPTION = 2 + ERR_MC_WRONG_PARAM = 3 + ERR_MC_MISSING_PARAMS = 4 + ERR_MC_MISSING_METHNAME = 5 + ERR_MC_RECURSIVE_CALL = 6 + ERR_MC_WRONG_PARAM_PARAMS = 7 + ERR_MC_EXPECTED_STRUCT = 8 + + + def initialize(class_delim=".") + @handler = [] + @default_handler = nil + @service_hook = nil + + @class_delim = class_delim + @create = nil + @parser = nil + + add_multicall if Config::ENABLE_MULTICALL + add_introspection if Config::ENABLE_INTROSPECTION + end + + def add_handler(prefix, obj_or_signature=nil, help=nil, &block) + if block_given? + # proc-handler + @handler << [prefix, block, obj_or_signature, help] + else + if prefix.kind_of? String + # class-handler + raise ArgumentError, "Expected non-nil value" if obj_or_signature.nil? + @handler << [prefix + @class_delim, obj_or_signature] + elsif prefix.kind_of? XMLRPC::Service::BasicInterface + # class-handler with interface + # add all methods + @handler += prefix.get_methods(obj_or_signature, @class_delim) + else + raise ArgumentError, "Wrong type for parameter 'prefix'" + end + end + self + end + + def get_service_hook + @service_hook + end + + def set_service_hook(&handler) + @service_hook = handler + self + end + + def get_default_handler + @default_handler + end + + def set_default_handler (&handler) + @default_handler = handler + self + end + + def add_multicall + add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs| + unless arrStructs.is_a? Array + raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, "system.multicall expects an array") + end + + arrStructs.collect {|call| + if call.is_a? Hash + methodName = call["methodName"] + params = call["params"] + + if params.nil? + multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params") + elsif methodName.nil? + multicall_fault(ERR_MC_MISSING_METHNAME, "Missing methodName") + else + if methodName == "system.multicall" + multicall_fault(ERR_MC_RECURSIVE_CALL, "Recursive system.multicall forbidden") + else + unless params.is_a? Array + multicall_fault(ERR_MC_WRONG_PARAM_PARAMS, "Parameter params have to be an Array") + else + ok, val = call_method(methodName, *params) + if ok + # correct return value + [val] + else + # exception + multicall_fault(val.faultCode, val.faultString) + end + end + end + end + + else + multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct") + end + } + end # end add_handler + self + end + + def add_introspection + add_handler("system.listMethods",%w(array), "List methods available on this XML-RPC server") do + methods = [] + @handler.each do |name, obj| + if obj.kind_of? Proc + methods << name + else + obj.methods.each {|meth| methods << name + meth} + end + end + methods + end + + add_handler("system.methodSignature", %w(array string), "Returns method signature") do |meth| + sigs = [] + @handler.each do |name, obj, sig| + if obj.kind_of? Proc and sig != nil and name == meth + if sig[0].kind_of? Array + # sig contains multiple signatures, e.g. [["array"], ["array", "string"]] + sig.each {|s| sigs << s} + else + # sig is a single signature, e.g. ["array"] + sigs << sig + end + end + end + sigs.uniq! || sigs # remove eventually duplicated signatures + end + + add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth| + help = nil + @handler.each do |name, obj, sig, hlp| + if obj.kind_of? Proc and name == meth + help = hlp + break + end + end + help || "" + end + + self + end + + + + def process(data) + method, params = parser().parseMethodCall(data) + handle(method, *params) + end + + private # -------------------------------------------------------------- + + def multicall_fault(nr, str) + {"faultCode" => nr, "faultString" => str} + end + + # + # method dispatch + # + def dispatch(methodname, *args) + for name, obj in @handler + if obj.kind_of? Proc + next unless methodname == name + else + next unless methodname =~ /^#{name}(.+)$/ + next unless obj.respond_to? $1 + obj = obj.method($1) + end + + if check_arity(obj, args.size) + if @service_hook.nil? + return obj.call(*args) + else + return @service_hook.call(obj, *args) + end + end + end + + if @default_handler.nil? + raise XMLRPC::FaultException.new(ERR_METHOD_MISSING, "Method #{methodname} missing or wrong number of parameters!") + else + @default_handler.call(methodname, *args) + end + end + + + # + # returns true, if the arity of "obj" matches + # + def check_arity(obj, n_args) + ary = obj.arity + + if ary >= 0 + n_args == ary + else + n_args >= (ary+1).abs + end + end + + + + def call_method(methodname, *args) + begin + [true, dispatch(methodname, *args)] + rescue XMLRPC::FaultException => e + [false, e] + rescue Exception => e + [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, "Uncaught exception #{e.message} in method #{methodname}")] + end + end + + # + # + # + def handle(methodname, *args) + create().methodResponse(*call_method(methodname, *args)) + end + + +end + + +=begin += XMLRPC::CGIServer +== Synopsis + require "xmlrpc/server" + + s = XMLRPC::CGIServer.new + + s.add_handler("michael.add") do |a,b| + a + b + end + + s.add_handler("michael.div") do |a,b| + if b == 0 + raise XMLRPC::FaultException.new(1, "division by zero") + else + a / b + end + end + + s.set_default_handler do |name, *args| + raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + + " or wrong number of parameters!") + end + + s.serve + +== Description +Implements a CGI-based XML-RPC server. + +== Superclass +(()) + +== Class Methods +--- XMLRPC::CGIServer.new( *a ) + Creates a new (({XMLRPC::CGIServer})) instance. All parameters given + are by-passed to (()). You can only create + ((*one*)) (({XMLRPC::CGIServer})) instance, because more than one makes + no sense. + +== Instance Methods +--- XMLRPC::CGIServer#serve + Call this after you have added all you handlers to the server. + This method processes a XML-RPC methodCall and sends the answer + back to the client. + Make sure that you don't write to standard-output in a handler, or in + any other part of your program, this would case a CGI-based server to fail! +=end + +class CGIServer < BasicServer + @@obj = nil + + def CGIServer.new(*a) + @@obj = super(*a) if @@obj.nil? + @@obj + end + + def initialize(*a) + super(*a) + end + + def serve + catch(:exit_serve) { + length = ENV['CONTENT_LENGTH'].to_i + + http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST" + http_error(400, "Bad Request") unless parse_content_type(ENV['CONTENT_TYPE']).first == "text/xml" + http_error(411, "Length Required") unless length > 0 + + # TODO: do we need a call to binmode? + $stdin.binmode if $stdin.respond_to? :binmode + data = $stdin.read(length) + + http_error(400, "Bad Request") if data.nil? or data.size != length + + http_write(process(data), "Content-type" => "text/xml; charset=utf-8") + } + end + + + private + + def http_error(status, message) + err = "#{status} #{message}" + msg = <<-"MSGEND" + + + #{err} + + +

    #{err}

    +

    Unexpected error occured while processing XML-RPC request!

    + + + MSGEND + + http_write(msg, "Status" => err, "Content-type" => "text/html") + throw :exit_serve # exit from the #serve method + end + + def http_write(body, header) + h = {} + header.each {|key, value| h[key.to_s.capitalize] = value} + h['Status'] ||= "200 OK" + h['Content-length'] ||= body.size.to_s + + str = "" + h.each {|key, value| str << "#{key}: #{value}\r\n"} + str << "\r\n#{body}" + + print str + end + +end + +=begin += XMLRPC::ModRubyServer +== Description +Implements a XML-RPC server, which works with Apache mod_ruby. + +Use it in the same way as CGIServer! + +== Superclass +(()) +=end + +class ModRubyServer < BasicServer + + def initialize(*a) + @ap = Apache::request + super(*a) + end + + def serve + catch(:exit_serve) { + header = {} + @ap.headers_in.each {|key, value| header[key.capitalize] = value} + + length = header['Content-length'].to_i + + http_error(405, "Method Not Allowed") unless @ap.request_method == "POST" + http_error(400, "Bad Request") unless parse_content_type(header['Content-type']).first == "text/xml" + http_error(411, "Length Required") unless length > 0 + + # TODO: do we need a call to binmode? + @ap.binmode + data = @ap.read(length) + + http_error(400, "Bad Request") if data.nil? or data.size != length + + http_write(process(data), 200, "Content-type" => "text/xml; charset=utf-8") + } + end + + + private + + def http_error(status, message) + err = "#{status} #{message}" + msg = <<-"MSGEND" + + + #{err} + + +

    #{err}

    +

    Unexpected error occured while processing XML-RPC request!

    + + + MSGEND + + http_write(msg, status, "Status" => err, "Content-type" => "text/html") + throw :exit_serve # exit from the #serve method + end + + def http_write(body, status, header) + h = {} + header.each {|key, value| h[key.to_s.capitalize] = value} + h['Status'] ||= "200 OK" + h['Content-length'] ||= body.size.to_s + + h.each {|key, value| @ap.headers_out[key] = value } + @ap.content_type = h["Content-type"] + @ap.status = status.to_i + @ap.send_http_header + + @ap.print body + end + +end + +=begin += XMLRPC::Server +== Synopsis + require "xmlrpc/server" + + s = XMLRPC::Server.new(8080) + + s.add_handler("michael.add") do |a,b| + a + b + end + + s.add_handler("michael.div") do |a,b| + if b == 0 + raise XMLRPC::FaultException.new(1, "division by zero") + else + a / b + end + end + + s.set_default_handler do |name, *args| + raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + + " or wrong number of parameters!") + end + + s.serve + +== Description +Implements a standalone XML-RPC server. The method (({serve}))) is left if a SIGHUP is sent to the +program. + +== Superclass +(()) + +== Class Methods +--- XMLRPC::Server.new( port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a ) + Creates a new (({XMLRPC::Server})) instance, which is a XML-RPC server listening on + port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost. + The server is not started, to start it you have to call (()). + + Parameters ((|audit|)) and ((|debug|)) are obsolete! + + All additionally given parameters in ((|*a|)) are by-passed to (()). + +== Instance Methods +--- XMLRPC::Server#serve + Call this after you have added all you handlers to the server. + This method starts the server to listen for XML-RPC requests and answer them. + +--- XMLRPC::Server#shutdown + Stops and shuts the server down. + +=end + +class WEBrickServlet < BasicServer; end # forward declaration + +class Server < WEBrickServlet + + def initialize(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a) + super(*a) + require 'webrick' + @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections, + :Logger => WEBrick::Log.new(stdlog)) + @server.mount("/", self) + end + + def serve + if RUBY_PLATFORM =~ /mingw|mswin32/ + signals = [1] + else + signals = %w[INT TERM HUP] + end + signals.each { |signal| trap(signal) { @server.shutdown } } + + @server.start + end + + def shutdown + @server.shutdown + end + +end + +=begin += XMLRPC::WEBrickServlet +== Synopsis + + require "webrick" + require "xmlrpc/server" + + s = XMLRPC::WEBrickServlet.new + s.add_handler("michael.add") do |a,b| + a + b + end + + s.add_handler("michael.div") do |a,b| + if b == 0 + raise XMLRPC::FaultException.new(1, "division by zero") + else + a / b + end + end + + s.set_default_handler do |name, *args| + raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + + " or wrong number of parameters!") + end + + httpserver = WEBrick::HTTPServer.new(:Port => 8080) + httpserver.mount("/RPC2", s) + trap("HUP") { httpserver.shutdown } # use 1 instead of "HUP" on Windows + httpserver.start + +== Instance Methods + +--- XMLRPC::WEBrickServlet#set_valid_ip( *ip_addr ) + Specifies the valid IP addresses that are allowed to connect to the server. + Each IP is either a (({String})) or a (({Regexp})). + +--- XMLRPC::WEBrickServlet#get_valid_ip + Return the via method (()) specified + valid IP addresses. + +== Description +Implements a servlet for use with WEBrick, a pure Ruby (HTTP-) server framework. + +== Superclass +(()) + +=end + +class WEBrickServlet < BasicServer + def initialize(*a) + super + require "webrick/httpstatus" + @valid_ip = nil + end + + # deprecated from WEBrick/1.2.2. + # but does not break anything. + def require_path_info? + false + end + + def get_instance(config, *options) + # TODO: set config & options + self + end + + def set_valid_ip(*ip_addr) + if ip_addr.size == 1 and ip_addr[0].nil? + @valid_ip = nil + else + @valid_ip = ip_addr + end + end + + def get_valid_ip + @valid_ip + end + + def service(request, response) + + if @valid_ip + raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip } + end + + if request.request_method != "POST" + raise WEBrick::HTTPStatus::MethodNotAllowed, + "unsupported method `#{request.request_method}'." + end + + if parse_content_type(request['Content-type']).first != "text/xml" + raise WEBrick::HTTPStatus::BadRequest + end + + length = (request['Content-length'] || 0).to_i + + raise WEBrick::HTTPStatus::LengthRequired unless length > 0 + + data = request.body + + if data.nil? or data.size != length + raise WEBrick::HTTPStatus::BadRequest + end + + resp = process(data) + if resp.nil? or resp.size <= 0 + raise WEBrick::HTTPStatus::InternalServerError + end + + response.status = 200 + response['Content-Length'] = resp.size + response['Content-Type'] = "text/xml; charset=utf-8" + response.body = resp + end +end + + +end # module XMLRPC + + +=begin += History + $Id: server.rb 16966 2008-06-07 19:56:11Z shyouhei $ +=end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/utils.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/utils.rb new file mode 100644 index 00000000..ca74b885 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xmlrpc/utils.rb @@ -0,0 +1,165 @@ +# +# Defines ParserWriterChooseMixin, which makes it possible to choose a +# different XML writer and/or XML parser then the default one. +# The Mixin is used in client.rb (class Client) and server.rb (class +# BasicServer) +# +# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) +# +# $Id: utils.rb 16907 2008-06-07 16:54:15Z shyouhei $ +# + +module XMLRPC + + # + # This module enables a user-class to be marshalled + # by XML-RPC for Ruby into a Hash, with one additional + # key/value pair "___class___" => ClassName + # + module Marshallable + end + + + module ParserWriterChooseMixin + + def set_writer(writer) + @create = Create.new(writer) + self + end + + def set_parser(parser) + @parser = parser + self + end + + private + + def create + # if set_writer was not already called then call it now + if @create.nil? then + set_writer(Config::DEFAULT_WRITER.new) + end + @create + end + + def parser + # if set_parser was not already called then call it now + if @parser.nil? then + set_parser(Config::DEFAULT_PARSER.new) + end + @parser + end + + end # module ParserWriterChooseMixin + + + module Service + + # + # base class for Service Interface definitions, used + # by BasicServer#add_handler + # + + class BasicInterface + attr_reader :prefix, :methods + + def initialize(prefix) + @prefix = prefix + @methods = [] + end + + def add_method(sig, help=nil, meth_name=nil) + mname = nil + sig = [sig] if sig.kind_of? String + + sig = sig.collect do |s| + name, si = parse_sig(s) + raise "Wrong signatures!" if mname != nil and name != mname + mname = name + si + end + + @methods << [mname, meth_name || mname, sig, help] + end + + private # --------------------------------- + + def parse_sig(sig) + # sig is a String + if sig =~ /^\s*(\w+)\s+([^(]+)(\(([^)]*)\))?\s*$/ + params = [$1] + name = $2.strip + $4.split(",").each {|i| params << i.strip} if $4 != nil + return name, params + else + raise "Syntax error in signature" + end + end + + end # class BasicInterface + + # + # class which wraps a Service Interface definition, used + # by BasicServer#add_handler + # + class Interface < BasicInterface + def initialize(prefix, &p) + raise "No interface specified" if p.nil? + super(prefix) + instance_eval(&p) + end + + def get_methods(obj, delim=".") + prefix = @prefix + delim + @methods.collect { |name, meth, sig, help| + [prefix + name, obj.method(meth).to_proc, sig, help] + } + end + + private # --------------------------------- + + def meth(*a) + add_method(*a) + end + + end # class Interface + + class PublicInstanceMethodsInterface < BasicInterface + def initialize(prefix) + super(prefix) + end + + def get_methods(obj, delim=".") + prefix = @prefix + delim + obj.class.public_instance_methods(false).collect { |name| + [prefix + name, obj.method(name).to_proc, nil, nil] + } + end + end + + + end # module Service + + + # + # short-form to create a Service::Interface + # + def self.interface(prefix, &p) + Service::Interface.new(prefix, &p) + end + + # short-cut for creating a PublicInstanceMethodsInterface + def self.iPIMethods(prefix) + Service::PublicInstanceMethodsInterface.new(prefix) + end + + + module ParseContentType + def parse_content_type(str) + a, *b = str.split(";") + return a.strip.downcase, *b + end + end + +end # module XMLRPC + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/charset.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/charset.rb new file mode 100644 index 00000000..15d5500f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/charset.rb @@ -0,0 +1,187 @@ +# XSD4R - Charset handling library. +# Copyright (C) 2001, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module XSD + + +module Charset + @internal_encoding = $KCODE + + class XSDError < StandardError; end + class CharsetError < XSDError; end + class UnknownCharsetError < CharsetError; end + class CharsetConversionError < CharsetError; end + +public + + ### + ## Maps + # + EncodingConvertMap = {} + def Charset.init + EncodingConvertMap[['UTF8', 'X_ISO8859_1']] = + Proc.new { |str| str.unpack('U*').pack('C*') } + EncodingConvertMap[['X_ISO8859_1', 'UTF8']] = + Proc.new { |str| str.unpack('C*').pack('U*') } + begin + require 'xsd/iconvcharset' + @internal_encoding = 'UTF8' + sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' : + 'shift_jis' + EncodingConvertMap[['UTF8', 'EUC' ]] = + Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "utf-8", str) } + EncodingConvertMap[['EUC' , 'UTF8']] = + Proc.new { |str| IconvCharset.safe_iconv("utf-8", "euc-jp", str) } + EncodingConvertMap[['EUC' , 'SJIS']] = + Proc.new { |str| IconvCharset.safe_iconv(sjtag, "euc-jp", str) } + EncodingConvertMap[['UTF8', 'SJIS']] = + Proc.new { |str| IconvCharset.safe_iconv(sjtag, "utf-8", str) } + EncodingConvertMap[['SJIS', 'UTF8']] = + Proc.new { |str| IconvCharset.safe_iconv("utf-8", sjtag, str) } + EncodingConvertMap[['SJIS', 'EUC' ]] = + Proc.new { |str| IconvCharset.safe_iconv("euc-jp", sjtag, str) } + rescue LoadError + begin + require 'nkf' + EncodingConvertMap[['EUC' , 'SJIS']] = + Proc.new { |str| NKF.nkf('-sXm0', str) } + EncodingConvertMap[['SJIS', 'EUC' ]] = + Proc.new { |str| NKF.nkf('-eXm0', str) } + rescue LoadError + end + + begin + require 'uconv' + @internal_encoding = 'UTF8' + EncodingConvertMap[['UTF8', 'EUC' ]] = Uconv.method(:u8toeuc) + EncodingConvertMap[['UTF8', 'SJIS']] = Uconv.method(:u8tosjis) + EncodingConvertMap[['EUC' , 'UTF8']] = Uconv.method(:euctou8) + EncodingConvertMap[['SJIS', 'UTF8']] = Uconv.method(:sjistou8) + rescue LoadError + end + end + end + self.init + + CharsetMap = { + 'NONE' => 'us-ascii', + 'EUC' => 'euc-jp', + 'SJIS' => 'shift_jis', + 'UTF8' => 'utf-8', + 'X_ISO_8859_1' => 'iso-8859-1', + 'X_UNKNOWN' => nil, + } + + + ### + ## handlers + # + def Charset.encoding + @internal_encoding + end + + def Charset.encoding=(encoding) + warn("xsd charset is set to #{encoding}") if $DEBUG + @internal_encoding = encoding + end + + def Charset.xml_encoding_label + charset_label(@internal_encoding) + end + + def Charset.encoding_to_xml(str, charset) + encoding_conv(str, @internal_encoding, charset_str(charset)) + end + + def Charset.encoding_from_xml(str, charset) + encoding_conv(str, charset_str(charset), @internal_encoding) + end + + def Charset.encoding_conv(str, enc_from, enc_to) + if enc_from == enc_to or enc_from == 'NONE' or enc_to == 'NONE' + str + elsif converter = EncodingConvertMap[[enc_from, enc_to]] + converter.call(str) + else + raise CharsetConversionError.new( + "Converter not found: #{enc_from} -> #{enc_to}") + end + end + + def Charset.charset_label(encoding) + CharsetMap[encoding.upcase] + end + + def Charset.charset_str(label) + if CharsetMap.respond_to?(:key) + CharsetMap.key(label.downcase) || 'X_UNKNOWN' + else + CharsetMap.index(label.downcase) || 'X_UNKNOWN' + end + end + + # us_ascii = '[\x00-\x7F]' + us_ascii = '[\x9\xa\xd\x20-\x7F]' # XML 1.0 restricted. + USASCIIRegexp = Regexp.new("\\A#{us_ascii}*\\z", nil, "NONE") + + twobytes_euc = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])' + threebytes_euc = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])' + character_euc = "(?:#{us_ascii}|#{twobytes_euc}|#{threebytes_euc})" + EUCRegexp = Regexp.new("\\A#{character_euc}*\\z", nil, "NONE") + + # onebyte_sjis = '[\x00-\x7F\xA1-\xDF]' + onebyte_sjis = '[\x9\xa\xd\x20-\x7F\xA1-\xDF]' # XML 1.0 restricted. + twobytes_sjis = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])' + character_sjis = "(?:#{onebyte_sjis}|#{twobytes_sjis})" + SJISRegexp = Regexp.new("\\A#{character_sjis}*\\z", nil, "NONE") + + # 0xxxxxxx + # 110yyyyy 10xxxxxx + twobytes_utf8 = '(?:[\xC0-\xDF][\x80-\xBF])' + # 1110zzzz 10yyyyyy 10xxxxxx + threebytes_utf8 = '(?:[\xE0-\xEF][\x80-\xBF][\x80-\xBF])' + # 11110uuu 10uuuzzz 10yyyyyy 10xxxxxx + fourbytes_utf8 = '(?:[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF])' + character_utf8 = + "(?:#{us_ascii}|#{twobytes_utf8}|#{threebytes_utf8}|#{fourbytes_utf8})" + UTF8Regexp = Regexp.new("\\A#{character_utf8}*\\z", nil, "NONE") + + def Charset.is_us_ascii(str) + USASCIIRegexp =~ str + end + + def Charset.is_utf8(str) + UTF8Regexp =~ str + end + + def Charset.is_euc(str) + EUCRegexp =~ str + end + + def Charset.is_sjis(str) + SJISRegexp =~ str + end + + def Charset.is_ces(str, code = $KCODE) + case code + when 'NONE' + is_us_ascii(str) + when 'UTF8' + is_utf8(str) + when 'EUC' + is_euc(str) + when 'SJIS' + is_sjis(str) + else + raise UnknownCharsetError.new("Unknown charset: #{code}") + end + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen.rb new file mode 100644 index 00000000..d820ebf1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen.rb @@ -0,0 +1,12 @@ +# XSD4R - Generating code library +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/moduledef' +require 'xsd/codegen/classdef' +require 'xsd/codegen/methoddef' diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/classdef.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/classdef.rb new file mode 100644 index 00000000..9eb1ce66 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/classdef.rb @@ -0,0 +1,203 @@ +# XSD4R - Generating class definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/moduledef' +require 'xsd/codegen/methoddef' + + +module XSD +module CodeGen + + +class ClassDef < ModuleDef + include GenSupport + + def initialize(name, baseclass = nil) + super(name) + @baseclass = baseclass + @classvar = [] + @attrdef = [] + end + + def def_classvar(var, value) + var = var.sub(/\A@@/, "") + unless safevarname?(var) + raise ArgumentError.new("#{var} seems to be unsafe") + end + @classvar << [var, value] + end + + def def_attr(attrname, writable = true, varname = nil) + unless safevarname?(varname || attrname) + raise ArgumentError.new("#{varname || attrname} seems to be unsafe") + end + @attrdef << [attrname, writable, varname] + end + + def dump + buf = "" + unless @requirepath.empty? + buf << dump_requirepath + end + buf << dump_emptyline unless buf.empty? + package = @name.split(/::/)[0..-2] + buf << dump_package_def(package) unless package.empty? + buf << dump_comment if @comment + buf << dump_class_def + spacer = false + unless @classvar.empty? + spacer = true + buf << dump_classvar + end + unless @const.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_const + end + unless @code.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_code + end + unless @attrdef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_attributes + end + unless @methoddef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_methods + end + buf << dump_class_def_end + buf << dump_package_def_end(package) unless package.empty? + buf.gsub(/^\s+$/, '') + end + +private + + def dump_class_def + name = @name.to_s.split(/::/) + if @baseclass + format("class #{name.last} < #{@baseclass}") + else + format("class #{name.last}") + end + end + + def dump_class_def_end + str = format("end") + end + + def dump_classvar + dump_static( + @classvar.collect { |var, value| + %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)}) + }.join("\n") + ) + end + + def dump_attributes + str = "" + @attrdef.each do |attrname, writable, varname| + varname ||= attrname + if attrname == varname + str << format(dump_accessor(attrname, writable), 2) + end + end + @attrdef.each do |attrname, writable, varname| + varname ||= attrname + if attrname != varname + str << "\n" unless str.empty? + str << format(dump_attribute(attrname, writable, varname), 2) + end + end + str + end + + def dump_accessor(attrname, writable) + if writable + "attr_accessor :#{attrname}" + else + "attr_reader :#{attrname}" + end + end + + def dump_attribute(attrname, writable, varname) + str = nil + mr = MethodDef.new(attrname) + mr.definition = "@#{varname}" + str = mr.dump + if writable + mw = MethodDef.new(attrname + "=", 'value') + mw.definition = "@#{varname} = value" + str << "\n" + mw.dump + end + str + end +end + + +end +end + + +if __FILE__ == $0 + require 'xsd/codegen/classdef' + include XSD::CodeGen + c = ClassDef.new("Foo::Bar::HobbitName", String) + c.def_require("foo/bar") + c.comment = <<-EOD + foo + bar + baz + EOD + c.def_const("FOO", 1) + c.def_classvar("@@foo", "var".dump) + c.def_classvar("baz", "1".dump) + c.def_attr("Foo", true, "foo") + c.def_attr("bar") + c.def_attr("baz", true) + c.def_attr("Foo2", true, "foo2") + c.def_attr("foo3", false, "foo3") + c.def_method("foo") do + <<-EOD + foo.bar = 1 +\tbaz.each do |ele| +\t ele + end + EOD + end + c.def_method("baz", "qux") do + <<-EOD + [1, 2, 3].each do |i| + p i + end + EOD + end + + m = MethodDef.new("qux", "quxx", "quxxx") do + <<-EOD + p quxx + quxxx + EOD + end + m.comment = "hello world\n123" + c.add_method(m) + c.def_code <<-EOD + Foo.new + Bar.z + EOD + c.def_code <<-EOD + Foo.new + Bar.z + EOD + c.def_privatemethod("foo", "baz", "*arg", "&block") + + puts c.dump +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/commentdef.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/commentdef.rb new file mode 100644 index 00000000..c9493a13 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/commentdef.rb @@ -0,0 +1,34 @@ +# XSD4R - Generating comment definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' + + +module XSD +module CodeGen + + +module CommentDef + include GenSupport + + attr_accessor :comment + +private + + def dump_comment + if /\A#/ =~ @comment + format(@comment) + else + format(@comment).gsub(/^/, '# ') + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/gensupport.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/gensupport.rb new file mode 100644 index 00000000..1e85d366 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/gensupport.rb @@ -0,0 +1,166 @@ +# XSD4R - Code generation support +# Copyright (C) 2004, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module XSD +module CodeGen + +# from the file 'keywords' in 1.9. +KEYWORD = {} +%w( +__LINE__ +__FILE__ +BEGIN +END +alias +and +begin +break +case +class +def +defined? +do +else +elsif +end +ensure +false +for +if +in +module +next +nil +not +or +redo +rescue +retry +return +self +super +then +true +undef +unless +until +when +while +yield +).each { |k| KEYWORD[k] = nil } + +module GenSupport + def capitalize(target) + target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') } + end + module_function :capitalize + + def uncapitalize(target) + target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') } + end + module_function :uncapitalize + + def safeconstname(name) + safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele| + GenSupport.capitalize(ele) + }.join + if /^[A-Z]/ !~ safename or keyword?(safename) + safename = "C_#{safename}" + end + safename + end + module_function :safeconstname + + def safeconstname?(name) + /\A[A-Z][a-zA-Z0-9_]*\z/ =~ name and !keyword?(name) + end + module_function :safeconstname? + + def safemethodname(name) + safename = name.scan(/[a-zA-Z0-9_]+/).join('_') + safename = uncapitalize(safename) + if /^[a-z]/ !~ safename + safename = "m_#{safename}" + end + safename + end + module_function :safemethodname + + def safemethodname?(name) + /\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\z/ =~ name + end + module_function :safemethodname? + + def safevarname(name) + safename = uncapitalize(name.scan(/[a-zA-Z0-9_]+/).join('_')) + if /^[a-z]/ !~ safename or keyword?(safename) + "v_#{safename}" + else + safename + end + end + module_function :safevarname + + def safevarname?(name) + /\A[a-z_][a-zA-Z0-9_]*\z/ =~ name and !keyword?(name) + end + module_function :safevarname? + + def keyword?(word) + KEYWORD.key?(word) + end + module_function :keyword? + + def format(str, indent = nil) + str = trim_eol(str) + str = trim_indent(str) + if indent + str.gsub(/^/, " " * indent) + else + str + end + end + +private + + def trim_eol(str) + str.collect { |line| + line.sub(/\r?\n\z/, "") + "\n" + }.join + end + + def trim_indent(str) + indent = nil + str = str.collect { |line| untab(line) }.join + str.each do |line| + head = line.index(/\S/) + if !head.nil? and (indent.nil? or head < indent) + indent = head + end + end + return str unless indent + str.collect { |line| + line.sub(/^ {0,#{indent}}/, "") + }.join + end + + def untab(line, ts = 8) + while pos = line.index(/\t/) + line = line.sub(/\t/, " " * (ts - (pos % ts))) + end + line + end + + def dump_emptyline + "\n" + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/methoddef.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/methoddef.rb new file mode 100644 index 00000000..15892fc5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/methoddef.rb @@ -0,0 +1,63 @@ +# XSD4R - Generating method definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/commentdef' + + +module XSD +module CodeGen + + +class MethodDef + include GenSupport + include CommentDef + + attr_accessor :definition + + def initialize(name, *params) + unless safemethodname?(name) + raise ArgumentError.new("name '#{name}' seems to be unsafe") + end + @name = name + @params = params + @comment = nil + @definition = yield if block_given? + end + + def dump + buf = "" + buf << dump_comment if @comment + buf << dump_method_def + buf << dump_definition if @definition and !@definition.empty? + buf << dump_method_def_end + buf + end + +private + + def dump_method_def + if @params.empty? + format("def #{@name}") + else + format("def #{@name}(#{@params.join(", ")})") + end + end + + def dump_method_def_end + format("end") + end + + def dump_definition + format(@definition, 2) + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/moduledef.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/moduledef.rb new file mode 100644 index 00000000..744af2ff --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/codegen/moduledef.rb @@ -0,0 +1,191 @@ +# XSD4R - Generating module definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/methoddef' +require 'xsd/codegen/commentdef' + + +module XSD +module CodeGen + + +class ModuleDef + include GenSupport + include CommentDef + + def initialize(name) + @name = name + @comment = nil + @const = [] + @code = [] + @requirepath = [] + @methoddef = [] + end + + def def_require(path) + @requirepath << path + end + + def def_const(const, value) + unless safeconstname?(const) + raise ArgumentError.new("#{const} seems to be unsafe") + end + @const << [const, value] + end + + def def_code(code) + @code << code + end + + def def_method(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, :public) + end + alias def_publicmethod def_method + + def def_protectedmethod(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, + :protected) + end + + def def_privatemethod(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, :private) + end + + def add_method(m, visibility = :public) + @methoddef << [visibility, m] + end + + def dump + buf = "" + unless @requirepath.empty? + buf << dump_requirepath + end + buf << dump_emptyline unless buf.empty? + package = @name.split(/::/)[0..-2] + buf << dump_package_def(package) unless package.empty? + buf << dump_comment if @comment + buf << dump_module_def + spacer = false + unless @const.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_const + end + unless @code.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_code + end + unless @methoddef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_methods + end + buf << dump_module_def_end + buf << dump_package_def_end(package) unless package.empty? + buf.gsub(/^\s+$/, '') + end + +private + + def dump_requirepath + format( + @requirepath.collect { |path| + %Q(require '#{path}') + }.join("\n") + ) + end + + def dump_const + dump_static( + @const.sort.collect { |var, value| + %Q(#{var} = #{dump_value(value)}) + }.join("\n") + ) + end + + def dump_code + dump_static(@code.join("\n")) + end + + def dump_static(str) + format(str, 2) + end + + def dump_methods + methods = {} + @methoddef.each do |visibility, method| + (methods[visibility] ||= []) << method + end + str = "" + [:public, :protected, :private].each do |visibility| + if methods[visibility] + str << "\n" unless str.empty? + str << visibility.to_s << "\n\n" unless visibility == :public + str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n") + end + end + str + end + + def dump_value(value) + if value.respond_to?(:to_src) + value.to_src + else + value + end + end + + def dump_package_def(package) + format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n" + end + + def dump_package_def_end(package) + "\n\n" + format(package.collect { |ele| "end" }.join("; ")) + end + + def dump_module_def + name = @name.to_s.split(/::/) + format("module #{name.last}") + end + + def dump_module_def_end + format("end") + end +end + + +end +end + + +if __FILE__ == $0 + require 'xsd/codegen/moduledef' + include XSD::CodeGen + m = ModuleDef.new("Foo::Bar::HobbitName") + m.def_require("foo/bar") + m.def_require("baz") + m.comment = <<-EOD + foo + bar + baz + EOD + m.def_method("foo") do + <<-EOD + foo.bar = 1 + baz.each do |ele| + ele + 1 + end + EOD + end + m.def_method("baz", "qux") + #m.def_protectedmethod("aaa") + m.def_privatemethod("bbb") + puts m.dump +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/datatypes.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/datatypes.rb new file mode 100644 index 00000000..bbe6c857 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/datatypes.rb @@ -0,0 +1,1269 @@ +# XSD4R - XML Schema Datatype implementation. +# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'xsd/charset' +require 'uri' + + +### +## XMLSchamaDatatypes general definitions. +# +module XSD + + +Namespace = 'http://www.w3.org/2001/XMLSchema' +InstanceNamespace = 'http://www.w3.org/2001/XMLSchema-instance' + +AttrType = 'type' +NilValue = 'true' + +AnyTypeLiteral = 'anyType' +AnySimpleTypeLiteral = 'anySimpleType' +NilLiteral = 'nil' +StringLiteral = 'string' +BooleanLiteral = 'boolean' +DecimalLiteral = 'decimal' +FloatLiteral = 'float' +DoubleLiteral = 'double' +DurationLiteral = 'duration' +DateTimeLiteral = 'dateTime' +TimeLiteral = 'time' +DateLiteral = 'date' +GYearMonthLiteral = 'gYearMonth' +GYearLiteral = 'gYear' +GMonthDayLiteral = 'gMonthDay' +GDayLiteral = 'gDay' +GMonthLiteral = 'gMonth' +HexBinaryLiteral = 'hexBinary' +Base64BinaryLiteral = 'base64Binary' +AnyURILiteral = 'anyURI' +QNameLiteral = 'QName' + +NormalizedStringLiteral = 'normalizedString' +#3.3.2 token +#3.3.3 language +#3.3.4 NMTOKEN +#3.3.5 NMTOKENS +#3.3.6 Name +#3.3.7 NCName +#3.3.8 ID +#3.3.9 IDREF +#3.3.10 IDREFS +#3.3.11 ENTITY +#3.3.12 ENTITIES +IntegerLiteral = 'integer' +NonPositiveIntegerLiteral = 'nonPositiveInteger' +NegativeIntegerLiteral = 'negativeInteger' +LongLiteral = 'long' +IntLiteral = 'int' +ShortLiteral = 'short' +ByteLiteral = 'byte' +NonNegativeIntegerLiteral = 'nonNegativeInteger' +UnsignedLongLiteral = 'unsignedLong' +UnsignedIntLiteral = 'unsignedInt' +UnsignedShortLiteral = 'unsignedShort' +UnsignedByteLiteral = 'unsignedByte' +PositiveIntegerLiteral = 'positiveInteger' + +AttrTypeName = QName.new(InstanceNamespace, AttrType) +AttrNilName = QName.new(InstanceNamespace, NilLiteral) + +AnyTypeName = QName.new(Namespace, AnyTypeLiteral) +AnySimpleTypeName = QName.new(Namespace, AnySimpleTypeLiteral) + +class Error < StandardError; end +class ValueSpaceError < Error; end + + +### +## The base class of all datatypes with Namespace. +# +class NSDBase + @@types = [] + + attr_accessor :type + + def self.inherited(klass) + @@types << klass + end + + def self.types + @@types + end + + def initialize + end + + def init(type) + @type = type + end +end + + +### +## The base class of XSD datatypes. +# +class XSDAnySimpleType < NSDBase + include XSD + Type = QName.new(Namespace, AnySimpleTypeLiteral) + + # @data represents canonical space (ex. Integer: 123). + attr_reader :data + # @is_nil represents this data is nil or not. + attr_accessor :is_nil + + def initialize(value = nil) + init(Type, value) + end + + # true or raise + def check_lexical_format(value) + screen_data(value) + true + end + + # set accepts a string which follows lexical space (ex. String: "+123"), or + # an object which follows canonical space (ex. Integer: 123). + def set(value) + if value.nil? + @is_nil = true + @data = nil + _set(nil) + else + @is_nil = false + _set(screen_data(value)) + end + end + + # to_s creates a string which follows lexical space (ex. String: "123"). + def to_s() + if @is_nil + "" + else + _to_s + end + end + +private + + def init(type, value) + super(type) + set(value) + end + + # raises ValueSpaceError if check failed + def screen_data(value) + value + end + + def _set(value) + @data = value + end + + def _to_s + @data.to_s + end +end + +class XSDNil < XSDAnySimpleType + Type = QName.new(Namespace, NilLiteral) + Value = 'true' + + def initialize(value = nil) + init(Type, value) + end +end + + +### +## Primitive datatypes. +# +class XSDString < XSDAnySimpleType + Type = QName.new(Namespace, StringLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + unless XSD::Charset.is_ces(value, XSD::Charset.encoding) + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + value + end +end + +class XSDBoolean < XSDAnySimpleType + Type = QName.new(Namespace, BooleanLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + if value.is_a?(String) + str = value.strip + if str == 'true' || str == '1' + true + elsif str == 'false' || str == '0' + false + else + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + else + value ? true : false + end + end +end + +class XSDDecimal < XSDAnySimpleType + Type = QName.new(Namespace, DecimalLiteral) + + def initialize(value = nil) + init(Type, value) + end + + def nonzero? + (@number != '0') + end + +private + + def screen_data(d) + if d.is_a?(String) + # Integer("00012") => 10 in Ruby. + d.sub!(/^([+\-]?)0*(?=\d)/, "\\1") + end + screen_data_str(d) + end + + def screen_data_str(str) + /^([+\-]?)(\d*)(?:\.(\d*)?)?$/ =~ str.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + sign = $1 || '+' + int_part = $2 + frac_part = $3 + int_part = '0' if int_part.empty? + frac_part = frac_part ? frac_part.sub(/0+$/, '') : '' + point = - frac_part.size + number = int_part + frac_part + # normalize + if sign == '+' + sign = '' + elsif sign == '-' + if number == '0' + sign = '' + end + end + [sign, point, number] + end + + def _set(data) + if data.nil? + @sign = @point = @number = @data = nil + return + end + @sign, @point, @number = data + @data = _to_s + @data.freeze + end + + # 0.0 -> 0; right? + def _to_s + str = @number.dup + if @point.nonzero? + str[@number.size + @point, 0] = '.' + end + @sign + str + end +end + +module FloatConstants + NaN = 0.0/0.0 + POSITIVE_INF = +1.0/0.0 + NEGATIVE_INF = -1.0/0.0 + POSITIVE_ZERO = +1.0/POSITIVE_INF + NEGATIVE_ZERO = -1.0/POSITIVE_INF + MIN_POSITIVE_SINGLE = 2.0 ** -149 +end + +class XSDFloat < XSDAnySimpleType + include FloatConstants + Type = QName.new(Namespace, FloatLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + # "NaN".to_f => 0 in some environment. libc? + if value.is_a?(Float) + return narrow32bit(value) + end + str = value.to_s.strip + if str == 'NaN' + NaN + elsif str == 'INF' + POSITIVE_INF + elsif str == '-INF' + NEGATIVE_INF + else + if /^[+\-\.\deE]+$/ !~ str + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + # Float("-1.4E") might fail on some system. + str << '0' if /e$/i =~ str + begin + return narrow32bit(Float(str)) + rescue ArgumentError + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + end + end + + def _to_s + if @data.nan? + 'NaN' + elsif @data.infinite? == 1 + 'INF' + elsif @data.infinite? == -1 + '-INF' + else + sign = XSDFloat.positive?(@data) ? '+' : '-' + sign + sprintf("%.10g", @data.abs).sub(/[eE]([+-])?0+/) { 'e' + $1 } + end + end + + # Convert to single-precision 32-bit floating point value. + def narrow32bit(f) + if f.nan? || f.infinite? + f + elsif f.abs < MIN_POSITIVE_SINGLE + XSDFloat.positive?(f) ? POSITIVE_ZERO : NEGATIVE_ZERO + else + f + end + end + + def self.positive?(value) + (1 / value) > 0.0 + end +end + +# Ruby's Float is double-precision 64-bit floating point value. +class XSDDouble < XSDAnySimpleType + include FloatConstants + Type = QName.new(Namespace, DoubleLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + # "NaN".to_f => 0 in some environment. libc? + if value.is_a?(Float) + return value + end + str = value.to_s.strip + if str == 'NaN' + NaN + elsif str == 'INF' + POSITIVE_INF + elsif str == '-INF' + NEGATIVE_INF + else + begin + return Float(str) + rescue ArgumentError + # '1.4e' cannot be parsed on some architecture. + if /e\z/i =~ str + begin + return Float(str + '0') + rescue ArgumentError + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + else + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + end + end + end + + def _to_s + if @data.nan? + 'NaN' + elsif @data.infinite? == 1 + 'INF' + elsif @data.infinite? == -1 + '-INF' + else + sign = (1 / @data > 0.0) ? '+' : '-' + sign + sprintf("%.16g", @data.abs).sub(/[eE]([+-])?0+/) { 'e' + $1 } + end + end +end + +class XSDDuration < XSDAnySimpleType + Type = QName.new(Namespace, DurationLiteral) + + attr_accessor :sign + attr_accessor :year + attr_accessor :month + attr_accessor :day + attr_accessor :hour + attr_accessor :min + attr_accessor :sec + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + /^([+\-]?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/ =~ value.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8))) + # Should we allow 'PT5S' here? + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + sign = $1 + year = $2.to_i + month = $3.to_i + day = $4.to_i + hour = $6.to_i + min = $7.to_i + sec = $8 ? XSDDecimal.new($8) : 0 + [sign, year, month, day, hour, min, sec] + end + + def _set(data) + if data.nil? + @sign = @year = @month = @day = @hour = @min = @sec = @data = nil + return + end + @sign, @year, @month, @day, @hour, @min, @sec = data + @data = _to_s + @data.freeze + end + + def _to_s + str = '' + str << @sign if @sign + str << 'P' + l = '' + l << "#{ @year }Y" if @year.nonzero? + l << "#{ @month }M" if @month.nonzero? + l << "#{ @day }D" if @day.nonzero? + r = '' + r << "#{ @hour }H" if @hour.nonzero? + r << "#{ @min }M" if @min.nonzero? + r << "#{ @sec }S" if @sec.nonzero? + str << l + if l.empty? + str << "0D" + end + unless r.empty? + str << "T" << r + end + str + end +end + + +require 'rational' +require 'date' + +module XSDDateTimeImpl + SecInDay = 86400 # 24 * 60 * 60 + + def to_obj(klass) + if klass == Time + to_time + elsif klass == Date + to_date + elsif klass == DateTime + to_datetime + else + nil + end + end + + def to_time + begin + if @data.offset * SecInDay == Time.now.utc_offset + d = @data + usec = (d.sec_fraction * SecInDay * 1000000).round + Time.local(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec) + else + d = @data.newof + usec = (d.sec_fraction * SecInDay * 1000000).round + Time.gm(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec) + end + rescue ArgumentError + nil + end + end + + def to_date + Date.new0(@data.class.jd_to_ajd(@data.jd, 0, 0), 0, @data.start) + end + + def to_datetime + data + end + + def tz2of(str) + /^(?:Z|(?:([+\-])(\d\d):(\d\d))?)$/ =~ str + sign = $1 + hour = $2.to_i + min = $3.to_i + + of = case sign + when '+' + of = +(hour.to_r * 60 + min) / 1440 # 24 * 60 + when '-' + of = -(hour.to_r * 60 + min) / 1440 # 24 * 60 + else + 0 + end + of + end + + def of2tz(offset) + diffmin = offset * 24 * 60 + if diffmin.zero? + 'Z' + else + ((diffmin < 0) ? '-' : '+') << format('%02d:%02d', + (diffmin.abs / 60.0).to_i, (diffmin.abs % 60.0).to_i) + end + end + + def screen_data(t) + # convert t to a DateTime as an internal representation. + if t.respond_to?(:to_datetime) # 1.9 or later + t.to_datetime + elsif t.is_a?(DateTime) + t + elsif t.is_a?(Date) + t = screen_data_str(t) + t <<= 12 if t.year < 0 + t + elsif t.is_a?(Time) + jd = DateTime.civil_to_jd(t.year, t.mon, t.mday, DateTime::ITALY) + fr = DateTime.time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) + + t.usec.to_r / 1000000 / SecInDay + of = t.utc_offset.to_r / SecInDay + DateTime.new0(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY) + else + screen_data_str(t) + end + end + + def add_tz(s) + s + of2tz(@data.offset) + end +end + +class XSDDateTime < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, DateTimeLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + if $1 == '0000' + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + year = $1.to_i + if year < 0 + year += 1 + end + mon = $2.to_i + mday = $3.to_i + hour = $4.to_i + min = $5.to_i + sec = $6.to_i + secfrac = $7 + zonestr = $8 + data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr)) + if secfrac + diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay + data += diffday + # FYI: new0 and jd_to_rjd are not necessary to use if you don't have + # exceptional reason. + end + [data, secfrac] + end + + def _set(data) + if data.nil? + @data = @secfrac = nil + return + end + @data, @secfrac = data + end + + def _to_s + year = (@data.year > 0) ? @data.year : @data.year - 1 + s = format('%.4d-%02d-%02dT%02d:%02d:%02d', + year, @data.mon, @data.mday, @data.hour, @data.min, @data.sec) + if @data.sec_fraction.nonzero? + if @secfrac + s << ".#{ @secfrac }" + else + s << sprintf("%.16f", + (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') + end + end + add_tz(s) + end +end + +class XSDTime < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, TimeLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + hour = $1.to_i + min = $2.to_i + sec = $3.to_i + secfrac = $4 + zonestr = $5 + data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr)) + if secfrac + diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay + data += diffday + end + [data, secfrac] + end + + def _set(data) + if data.nil? + @data = @secfrac = nil + return + end + @data, @secfrac = data + end + + def _to_s + s = format('%02d:%02d:%02d', @data.hour, @data.min, @data.sec) + if @data.sec_fraction.nonzero? + if @secfrac + s << ".#{ @secfrac }" + else + s << sprintf("%.16f", + (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') + end + end + add_tz(s) + end +end + +class XSDDate < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, DateLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^([+\-]?\d{4,})-(\d\d)-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + year = $1.to_i + if year < 0 + year += 1 + end + mon = $2.to_i + mday = $3.to_i + zonestr = $4 + DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr)) + end + + def _to_s + year = (@data.year > 0) ? @data.year : @data.year - 1 + s = format('%.4d-%02d-%02d', year, @data.mon, @data.mday) + add_tz(s) + end +end + +class XSDGYearMonth < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, GYearMonthLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^([+\-]?\d{4,})-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + year = $1.to_i + if year < 0 + year += 1 + end + mon = $2.to_i + zonestr = $3 + DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr)) + end + + def _to_s + year = (@data.year > 0) ? @data.year : @data.year - 1 + s = format('%.4d-%02d', year, @data.mon) + add_tz(s) + end +end + +class XSDGYear < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, GYearLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^([+\-]?\d{4,})(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + year = $1.to_i + if year < 0 + year += 1 + end + zonestr = $2 + DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr)) + end + + def _to_s + year = (@data.year > 0) ? @data.year : @data.year - 1 + s = format('%.4d', year) + add_tz(s) + end +end + +class XSDGMonthDay < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, GMonthDayLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^(\d\d)-(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + mon = $1.to_i + mday = $2.to_i + zonestr = $3 + DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr)) + end + + def _to_s + s = format('%02d-%02d', @data.mon, @data.mday) + add_tz(s) + end +end + +class XSDGDay < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, GDayLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + mday = $1.to_i + zonestr = $2 + DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr)) + end + + def _to_s + s = format('%02d', @data.mday) + add_tz(s) + end +end + +class XSDGMonth < XSDAnySimpleType + include XSDDateTimeImpl + Type = QName.new(Namespace, GMonthLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(t) + /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") + end + mon = $1.to_i + zonestr = $2 + DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr)) + end + + def _to_s + s = format('%02d', @data.mon) + add_tz(s) + end +end + +class XSDHexBinary < XSDAnySimpleType + Type = QName.new(Namespace, HexBinaryLiteral) + + # String in Ruby could be a binary. + def initialize(value = nil) + init(Type, value) + end + + def set_encoded(value) + if /^[0-9a-fA-F]*$/ !~ value + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + @data = String.new(value).strip + @is_nil = false + end + + def string + [@data].pack("H*") + end + +private + + def screen_data(value) + value.unpack("H*")[0].tr('a-f', 'A-F') + end +end + +class XSDBase64Binary < XSDAnySimpleType + Type = QName.new(Namespace, Base64BinaryLiteral) + + # String in Ruby could be a binary. + def initialize(value = nil) + init(Type, value) + end + + def set_encoded(value) + if /^[A-Za-z0-9+\/=]*$/ !~ value + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + @data = String.new(value).strip + @is_nil = false + end + + def string + @data.unpack("m")[0] + end + +private + + def screen_data(value) + [value].pack("m").strip + end +end + +class XSDAnyURI < XSDAnySimpleType + Type = QName.new(Namespace, AnyURILiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + begin + URI.parse(value.to_s.strip) + rescue URI::InvalidURIError + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + end +end + +class XSDQName < XSDAnySimpleType + Type = QName.new(Namespace, QNameLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + /^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip + unless Regexp.last_match + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + prefix = $1 + localpart = $2 + [prefix, localpart] + end + + def _set(data) + if data.nil? + @prefix = @localpart = @data = nil + return + end + @prefix, @localpart = data + @data = _to_s + @data.freeze + end + + def _to_s + if @prefix + "#{ @prefix }:#{ @localpart }" + else + "#{ @localpart }" + end + end +end + + +### +## Derived types +# +class XSDNormalizedString < XSDString + Type = QName.new(Namespace, NormalizedStringLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data(value) + if /[\t\r\n]/ =~ value + raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") + end + super + end +end + +class XSDInteger < XSDDecimal + Type = QName.new(Namespace, IntegerLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def screen_data_str(str) + begin + data = Integer(str) + rescue ArgumentError + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + unless validate(data) + raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") + end + data + end + + def _set(value) + @data = value + end + + def _to_s() + @data.to_s + end + + def validate(v) + max = maxinclusive + min = mininclusive + (max.nil? or v <= max) and (min.nil? or v >= min) + end + + def maxinclusive + nil + end + + def mininclusive + nil + end + + PositiveMinInclusive = 1 + def positive(v) + PositiveMinInclusive <= v + end +end + +class XSDNonPositiveInteger < XSDInteger + Type = QName.new(Namespace, NonPositiveIntegerLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + 0 + end + + def mininclusive + nil + end +end + +class XSDNegativeInteger < XSDNonPositiveInteger + Type = QName.new(Namespace, NegativeIntegerLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + -1 + end + + def mininclusive + nil + end +end + +class XSDLong < XSDInteger + Type = QName.new(Namespace, LongLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +9223372036854775807 + end + + def mininclusive + -9223372036854775808 + end +end + +class XSDInt < XSDLong + Type = QName.new(Namespace, IntLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +2147483647 + end + + def mininclusive + -2147483648 + end +end + +class XSDShort < XSDInt + Type = QName.new(Namespace, ShortLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +32767 + end + + def mininclusive + -32768 + end +end + +class XSDByte < XSDShort + Type = QName.new(Namespace, ByteLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +127 + end + + def mininclusive + -128 + end +end + +class XSDNonNegativeInteger < XSDInteger + Type = QName.new(Namespace, NonNegativeIntegerLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + nil + end + + def mininclusive + 0 + end +end + +class XSDUnsignedLong < XSDNonNegativeInteger + Type = QName.new(Namespace, UnsignedLongLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +18446744073709551615 + end + + def mininclusive + 0 + end +end + +class XSDUnsignedInt < XSDUnsignedLong + Type = QName.new(Namespace, UnsignedIntLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +4294967295 + end + + def mininclusive + 0 + end +end + +class XSDUnsignedShort < XSDUnsignedInt + Type = QName.new(Namespace, UnsignedShortLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +65535 + end + + def mininclusive + 0 + end +end + +class XSDUnsignedByte < XSDUnsignedShort + Type = QName.new(Namespace, UnsignedByteLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + +255 + end + + def mininclusive + 0 + end +end + +class XSDPositiveInteger < XSDNonNegativeInteger + Type = QName.new(Namespace, PositiveIntegerLiteral) + + def initialize(value = nil) + init(Type, value) + end + +private + + def maxinclusive + nil + end + + def mininclusive + 1 + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/datatypes1999.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/datatypes1999.rb new file mode 100644 index 00000000..c7d6479e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/datatypes1999.rb @@ -0,0 +1,20 @@ +# XSD4R - XML Schema Datatype 1999 support +# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/datatypes' + + +module XSD + Namespace.replace('http://www.w3.org/1999/XMLSchema') + InstanceNamespace.replace('http://www.w3.org/1999/XMLSchema-instance') + AnyTypeLiteral.replace('ur-type') + AnySimpleTypeLiteral.replace('ur-type') + NilLiteral.replace('null') + NilValue.replace('1') + DateTimeLiteral.replace('timeInstant') +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/iconvcharset.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/iconvcharset.rb new file mode 100644 index 00000000..7e629d56 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/iconvcharset.rb @@ -0,0 +1,33 @@ +# XSD4R - Charset handling with iconv. +# Copyright (C) 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'iconv' + + +module XSD + + +class IconvCharset + def self.safe_iconv(to, from, str) + iconv = Iconv.new(to, from) + out = "" + begin + out << iconv.iconv(str) + rescue Iconv::IllegalSequence => e + out << e.success + ch, str = e.failed.split(//, 2) + out << '?' + warn("Failed to convert #{ch}") + retry + end + return out + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/mapping.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/mapping.rb new file mode 100644 index 00000000..06d30d4c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/mapping.rb @@ -0,0 +1,42 @@ +# XSD4R - XML Mapping for Ruby +# Copyright (C) 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require "soap/parser" +require 'soap/encodingstyle/literalHandler' +require "soap/generator" +require "soap/mapping" +require "soap/mapping/wsdlliteralregistry" + + +module XSD + + +module Mapping + MappingRegistry = SOAP::Mapping::WSDLLiteralRegistry.new + MappingOpt = {:default_encodingstyle => SOAP::LiteralNamespace} + + def self.obj2xml(obj, elename = nil, io = nil) + if !elename.nil? and !elename.is_a?(XSD::QName) + elename = XSD::QName.new(nil, elename) + end + elename ||= XSD::QName.new(nil, SOAP::Mapping.name2elename(obj.class.to_s)) + soap = SOAP::Mapping.obj2soap(obj, MappingRegistry) + soap.elename = elename + generator = SOAP::SOAPGenerator.new(MappingOpt) + generator.generate(soap, io) + end + + def self.xml2obj(stream) + parser = SOAP::Parser.new(MappingOpt) + soap = parser.parse(stream) + SOAP::Mapping.soap2obj(soap, MappingRegistry) + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/namedelements.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/namedelements.rb new file mode 100644 index 00000000..a13396bb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/namedelements.rb @@ -0,0 +1,95 @@ +# XSD4R - WSDL named element collection. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module XSD + + +class NamedElements + include Enumerable + + def initialize + @elements = [] + @cache = {} + end + + def dup + o = NamedElements.new + o.elements = @elements.dup + o + end + + def freeze + super + @elements.freeze + self + end + + def empty? + size == 0 + end + + def size + @elements.size + end + + def [](idx) + if idx.is_a?(Numeric) + @elements[idx] + else + @cache[idx] ||= @elements.find { |item| item.name == idx } + end + end + + def find_name(name) + @elements.find { |item| item.name.name == name } + end + + def keys + collect { |element| element.name } + end + + def each + @elements.each do |element| + yield(element) + end + end + + def <<(rhs) + @elements << rhs + self + end + + def delete(rhs) + @elements.delete(rhs) + end + + def +(rhs) + o = NamedElements.new + o.elements = @elements + rhs.elements + o + end + + def concat(rhs) + @elements.concat(rhs.elements) + self + end + + Empty = NamedElements.new.freeze + +protected + + def elements=(rhs) + @elements = rhs + end + + def elements + @elements + end +end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/ns.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/ns.rb new file mode 100644 index 00000000..53eeae71 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/ns.rb @@ -0,0 +1,140 @@ +# XSD4R - XML Schema Namespace library +# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/datatypes' + + +module XSD + + +class NS + class Assigner + def initialize + @count = 0 + end + + def assign(ns) + @count += 1 + "n#{@count}" + end + end + + attr_reader :default_namespace + + class FormatError < Error; end + +public + + def initialize(tag2ns = {}) + @tag2ns = tag2ns + @assigner = nil + @ns2tag = {} + @tag2ns.each do |tag, ns| + @ns2tag[ns] = tag + end + @default_namespace = nil + end + + def assign(ns, tag = nil) + if (tag == '') + @default_namespace = ns + tag + else + @assigner ||= Assigner.new + tag ||= @assigner.assign(ns) + @ns2tag[ns] = tag + @tag2ns[tag] = ns + tag + end + end + + def assigned?(ns) + @default_namespace == ns or @ns2tag.key?(ns) + end + + def assigned_tag?(tag) + @tag2ns.key?(tag) + end + + def clone_ns + cloned = NS.new(@tag2ns.dup) + cloned.assigner = @assigner + cloned.assign(@default_namespace, '') if @default_namespace + cloned + end + + def name(name) + if (name.namespace == @default_namespace) + name.name + elsif @ns2tag.key?(name.namespace) + "#{@ns2tag[name.namespace]}:#{name.name}" + else + raise FormatError.new("namespace: #{name.namespace} not defined yet") + end + end + + def compare(ns, name, rhs) + if (ns == @default_namespace) + return true if (name == rhs) + end + @tag2ns.each do |assigned_tag, assigned_ns| + if assigned_ns == ns && "#{assigned_tag}:#{name}" == rhs + return true + end + end + false + end + + # $1 and $2 are necessary. + ParseRegexp = Regexp.new('^([^:]+)(?::(.+))?$') + + def parse(str, local = false) + if ParseRegexp =~ str + if (name = $2) and (ns = @tag2ns[$1]) + return XSD::QName.new(ns, name) + end + end + XSD::QName.new(local ? nil : @default_namespace, str) + end + + # For local attribute key parsing + # + # => + # {}bar, {urn:a}baz + def parse_local(elem) + ParseRegexp =~ elem + if $2 + ns = @tag2ns[$1] + name = $2 + if !ns + raise FormatError.new("unknown namespace qualifier: #{$1}") + end + elsif $1 + ns = nil + name = $1 + else + raise FormatError.new("illegal element format: #{elem}") + end + XSD::QName.new(ns, name) + end + + def each_ns + @ns2tag.each do |ns, tag| + yield(ns, tag) + end + end + +protected + + def assigner=(assigner) + @assigner = assigner + end +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/qname.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/qname.rb new file mode 100644 index 00000000..bb9763a6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/qname.rb @@ -0,0 +1,78 @@ +# XSD4R - XML QName definition. +# Copyright (C) 2002, 2003, 2004 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module XSD + + +class QName + attr_accessor :namespace + attr_accessor :name + attr_accessor :source + + def initialize(namespace = nil, name = nil) + @namespace = namespace + @name = name + @source = nil + end + + def dup_name(name) + XSD::QName.new(@namespace, name) + end + + def dump + ns = @namespace.nil? ? 'nil' : @namespace.dump + name = @name.nil? ? 'nil' : @name.dump + "XSD::QName.new(#{ns}, #{name})" + end + + def match(rhs) + if rhs.namespace and (rhs.namespace != @namespace) + return false + end + if rhs.name and (rhs.name != @name) + return false + end + true + end + + def ==(rhs) + !rhs.nil? and @namespace == rhs.namespace and @name == rhs.name + end + + def ===(rhs) + (self == rhs) + end + + def eql?(rhs) + (self == rhs) + end + + def hash + @namespace.hash ^ @name.hash + end + + def to_s + "{#{ namespace }}#{ name }" + end + + def inspect + sprintf("#<%s:0x%x %s>", self.class.name, __id__, + "{#{ namespace }}#{ name }") + end + + NormalizedNameRegexp = /^\{([^}]*)\}(.*)$/ + def parse(str) + NormalizedNameRegexp =~ str + self.new($1, $2) + end + + EMPTY = QName.new.freeze +end + + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser.rb new file mode 100644 index 00000000..e79e36c5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser.rb @@ -0,0 +1,61 @@ +# XSD4R - XML Instance parser library. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/xmlparser/parser' + + +module XSD + + +module XMLParser + def create_parser(host, opt) + XSD::XMLParser::Parser.create_parser(host, opt) + end + module_function :create_parser + + # $1 is necessary. + NSParseRegexp = Regexp.new('^xmlns:?(.*)$') + + def filter_ns(ns, attrs) + return attrs if attrs.nil? or attrs.empty? + newattrs = {} + attrs.each do |key, value| + if (NSParseRegexp =~ key) + # '' means 'default namespace'. + tag = $1 || '' + ns.assign(value, tag) + else + newattrs[key] = value + end + end + newattrs + end + module_function :filter_ns +end + + +end + + +# Try to load XML processor. +loaded = false +[ + 'xsd/xmlparser/xmlparser', + 'xsd/xmlparser/xmlscanner', + 'xsd/xmlparser/rexmlparser', +].each do |lib| + begin + require lib + loaded = true + break + rescue LoadError + end +end +unless loaded + raise RuntimeError.new("XML processor module not found.") +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/parser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/parser.rb new file mode 100644 index 00000000..ad01d55a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/parser.rb @@ -0,0 +1,96 @@ +# XSD4R - XML Instance parser library. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/qname' +require 'xsd/ns' +require 'xsd/charset' + + +module XSD +module XMLParser + + +class Parser + class ParseError < Error; end + class FormatDecodeError < ParseError; end + class UnknownElementError < FormatDecodeError; end + class UnknownAttributeError < FormatDecodeError; end + class UnexpectedElementError < FormatDecodeError; end + class ElementConstraintError < FormatDecodeError; end + + @@parser_factory = nil + + def self.factory + @@parser_factory + end + + def self.create_parser(host, opt = {}) + @@parser_factory.new(host, opt) + end + + def self.add_factory(factory) + if $DEBUG + puts "Set #{ factory } as XML processor." + end + @@parser_factory = factory + end + +public + + attr_accessor :charset + + def initialize(host, opt = {}) + @host = host + @charset = opt[:charset] || nil + end + + def parse(string_or_readable) + @textbuf = '' + prologue + do_parse(string_or_readable) + epilogue + end + +private + + def do_parse(string_or_readable) + raise NotImplementError.new( + 'Method do_parse must be defined in derived class.') + end + + def start_element(name, attrs) + @host.start_element(name, attrs) + end + + def characters(text) + @host.characters(text) + end + + def end_element(name) + @host.end_element(name) + end + + def prologue + end + + def epilogue + end + + def xmldecl_encoding=(charset) + if @charset.nil? + @charset = charset + else + # Definition in a stream (like HTTP) has a priority. + p "encoding definition: #{ charset } is ignored." if $DEBUG + end + end +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/rexmlparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/rexmlparser.rb new file mode 100644 index 00000000..61da9aaf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/rexmlparser.rb @@ -0,0 +1,54 @@ +# XSD4R - REXMLParser XML parser library. +# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/xmlparser' +require 'rexml/streamlistener' +require 'rexml/document' + + +module XSD +module XMLParser + + +class REXMLParser < XSD::XMLParser::Parser + include REXML::StreamListener + + def do_parse(string_or_readable) + source = nil + source = REXML::SourceFactory.create_from(string_or_readable) + source.encoding = charset if charset + # Listener passes a String in utf-8. + @charset = 'utf-8' + REXML::Document.parse_stream(source, self) + end + + def epilogue + end + + def tag_start(name, attrs) + start_element(name, attrs) + end + + def tag_end(name) + end_element(name) + end + + def text(text) + characters(text) + end + + def xmldecl(version, encoding, standalone) + # Version should be checked. + end + + add_factory(self) +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/xmlparser.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/xmlparser.rb new file mode 100644 index 00000000..6db914cd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/xmlparser.rb @@ -0,0 +1,50 @@ +# XSD4R - XMLParser XML parser library. +# Copyright (C) 2001, 2003 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/xmlparser' +require 'xml/parser' + + +module XSD +module XMLParser + + +class XMLParser < XSD::XMLParser::Parser + class Listener < XML::Parser + begin + require 'xml/encoding-ja' + include XML::Encoding_ja + rescue LoadError + # uconv may not be installed. + end + end + + def do_parse(string_or_readable) + # XMLParser passes a String in utf-8. + @charset = 'utf-8' + @parser = Listener.new + @parser.parse(string_or_readable) do |type, name, data| + case type + when XML::Parser::START_ELEM + start_element(name, data) + when XML::Parser::END_ELEM + end_element(name) + when XML::Parser::CDATA + characters(data) + else + raise FormatDecodeError.new("Unexpected XML: #{ type }/#{ name }/#{ data }.") + end + end + end + + add_factory(self) +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/xmlscanner.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/xmlscanner.rb new file mode 100644 index 00000000..c80dc239 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/xsd/xmlparser/xmlscanner.rb @@ -0,0 +1,147 @@ +# XSD4R - XMLScan XML parser library. +# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi . + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/xmlparser' +require 'xmlscan/scanner' + + +module XSD +module XMLParser + + +class XMLScanner < XSD::XMLParser::Parser + include XMLScan::Visitor + + def do_parse(string_or_readable) + @attrs = {} + @curattr = nil + @scanner = XMLScan::XMLScanner.new(self) + @scanner.kcode = XSD::Charset.charset_str(charset) if charset + @scanner.parse(string_or_readable) + end + + def scanner_kcode=(charset) + @scanner.kcode = XSD::Charset.charset_str(charset) if charset + self.xmldecl_encoding = charset + end + + ENTITY_REF_MAP = { + 'lt' => '<', + 'gt' => '>', + 'amp' => '&', + 'quot' => '"', + 'apos' => '\'' + } + + def parse_error(msg) + raise ParseError.new(msg) + end + + def wellformed_error(msg) + raise NotWellFormedError.new(msg) + end + + def valid_error(msg) + raise NotValidError.new(msg) + end + + def warning(msg) + p msg if $DEBUG + end + + # def on_xmldecl; end + + def on_xmldecl_version(str) + # 1.0 expected. + end + + def on_xmldecl_encoding(str) + self.scanner_kcode = str + end + + # def on_xmldecl_standalone(str); end + + # def on_xmldecl_other(name, value); end + + # def on_xmldecl_end; end + + # def on_doctype(root, pubid, sysid); end + + # def on_prolog_space(str); end + + # def on_comment(str); end + + # def on_pi(target, pi); end + + def on_chardata(str) + characters(str) + end + + # def on_cdata(str); end + + def on_etag(name) + end_element(name) + end + + def on_entityref(ref) + characters(ENTITY_REF_MAP[ref]) + end + + def on_charref(code) + characters([code].pack('U')) + end + + def on_charref_hex(code) + on_charref(code) + end + + # def on_start_document; end + + # def on_end_document; end + + def on_stag(name) + @attrs = {} + end + + def on_attribute(name) + @attrs[name] = @curattr = '' + end + + def on_attr_value(str) + @curattr << str + end + + def on_attr_entityref(ref) + @curattr << ENTITY_REF_MAP[ref] + end + + def on_attr_charref(code) + @curattr << [code].pack('U') + end + + def on_attr_charref_hex(code) + on_attr_charref(code) + end + + # def on_attribute_end(name); end + + def on_stag_end_empty(name) + on_stag_end(name) + on_etag(name) + end + + def on_stag_end(name) + start_element(name, @attrs) + end + + add_factory(self) +end + + +end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml.rb new file mode 100644 index 00000000..fe8092aa --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml.rb @@ -0,0 +1,440 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +# $Id: yaml.rb 17246 2008-06-15 13:12:40Z shyouhei $ +# +# = yaml.rb: top-level module with methods for loading and parsing YAML documents +# +# Author:: why the lucky stiff +# + +require 'stringio' +require 'yaml/error' +require 'yaml/syck' +require 'yaml/tag' +require 'yaml/stream' +require 'yaml/constants' + +# == YAML +# +# YAML(tm) (rhymes with 'camel') is a +# straightforward machine parsable data serialization format designed for +# human readability and interaction with scripting languages such as Perl +# and Python. YAML is optimized for data serialization, formatted +# dumping, configuration files, log files, Internet messaging and +# filtering. This specification describes the YAML information model and +# serialization format. Together with the Unicode standard for characters, it +# provides all the information necessary to understand YAML Version 1.0 +# and construct computer programs to process it. +# +# See http://yaml.org/ for more information. For a quick tutorial, please +# visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes). +# +# == About This Library +# +# The YAML 1.0 specification outlines four stages of YAML loading and dumping. +# This library honors all four of those stages, although data is really only +# available to you in three stages. +# +# The four stages are: native, representation, serialization, and presentation. +# +# The native stage refers to data which has been loaded completely into Ruby's +# own types. (See +YAML::load+.) +# +# The representation stage means data which has been composed into +# +YAML::BaseNode+ objects. In this stage, the document is available as a +# tree of node objects. You can perform YPath queries and transformations +# at this level. (See +YAML::parse+.) +# +# The serialization stage happens inside the parser. The YAML parser used in +# Ruby is called Syck. Serialized nodes are available in the extension as +# SyckNode structs. +# +# The presentation stage is the YAML document itself. This is accessible +# to you as a string. (See +YAML::dump+.) +# +# For more information about the various information models, see Chapter +# 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269). +# +# The YAML module provides quick access to the most common loading (YAML::load) +# and dumping (YAML::dump) tasks. This module also provides an API for registering +# global types (YAML::add_domain_type). +# +# == Example +# +# A simple round-trip (load and dump) of an object. +# +# require "yaml" +# +# test_obj = ["dogs", "cats", "badgers"] +# +# yaml_obj = YAML::dump( test_obj ) +# # -> --- +# - dogs +# - cats +# - badgers +# ruby_obj = YAML::load( yaml_obj ) +# # => ["dogs", "cats", "badgers"] +# ruby_obj == test_obj +# # => true +# +# To register your custom types with the global resolver, use +add_domain_type+. +# +# YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val| +# Widget.new( val ) +# end +# +module YAML + + Resolver = YAML::Syck::Resolver + DefaultResolver = YAML::Syck::DefaultResolver + DefaultResolver.use_types_at( @@tagged_classes ) + GenericResolver = YAML::Syck::GenericResolver + Parser = YAML::Syck::Parser + Emitter = YAML::Syck::Emitter + + # Returns a new default parser + def YAML.parser; Parser.new.set_resolver( YAML.resolver ); end + # Returns a new generic parser + def YAML.generic_parser; Parser.new.set_resolver( GenericResolver ); end + # Returns the default resolver + def YAML.resolver; DefaultResolver; end + # Returns a new default emitter + def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end + + # + # Converts _obj_ to YAML and writes the YAML result to _io_. + # + # File.open( 'animals.yaml', 'w' ) do |out| + # YAML.dump( ['badger', 'elephant', 'tiger'], out ) + # end + # + # If no _io_ is provided, a string containing the dumped YAML + # is returned. + # + # YAML.dump( :locked ) + # #=> "--- :locked" + # + def YAML.dump( obj, io = nil ) + obj.to_yaml( io || io2 = StringIO.new ) + io || ( io2.rewind; io2.read ) + end + + # + # Load a document from the current _io_ stream. + # + # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) } + # #=> ['badger', 'elephant', 'tiger'] + # + # Can also load from a string. + # + # YAML.load( "--- :locked" ) + # #=> :locked + # + def YAML.load( io ) + yp = parser.load( io ) + end + + # + # Load a document from the file located at _filepath_. + # + # YAML.load_file( 'animals.yaml' ) + # #=> ['badger', 'elephant', 'tiger'] + # + def YAML.load_file( filepath ) + File.open( filepath ) do |f| + load( f ) + end + end + + # + # Parse the first document from the current _io_ stream + # + # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) } + # #=> #, + # #, + # #]> + # + # Can also load from a string. + # + # YAML.parse( "--- :locked" ) + # #=> # + # + def YAML.parse( io ) + yp = generic_parser.load( io ) + end + + # + # Parse a document from the file located at _filepath_. + # + # YAML.parse_file( 'animals.yaml' ) + # #=> #, + # #, + # #]> + # + def YAML.parse_file( filepath ) + File.open( filepath ) do |f| + parse( f ) + end + end + + # + # Calls _block_ with each consecutive document in the YAML + # stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.each_document( yf ) do |ydoc| + # ## ydoc contains the single object + # ## from the YAML document + # end + # end + # + def YAML.each_document( io, &block ) + yp = parser.load_documents( io, &block ) + end + + # + # Calls _block_ with each consecutive document in the YAML + # stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.load_documents( yf ) do |ydoc| + # ## ydoc contains the single object + # ## from the YAML document + # end + # end + # + def YAML.load_documents( io, &doc_proc ) + YAML.each_document( io, &doc_proc ) + end + + # + # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for + # each consecutive document in the YAML stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.each_node( yf ) do |ydoc| + # ## ydoc contains a tree of nodes + # ## from the YAML document + # end + # end + # + def YAML.each_node( io, &doc_proc ) + yp = generic_parser.load_documents( io, &doc_proc ) + end + + # + # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for + # each consecutive document in the YAML stream contained in _io_. + # + # File.open( 'many-docs.yaml' ) do |yf| + # YAML.parse_documents( yf ) do |ydoc| + # ## ydoc contains a tree of nodes + # ## from the YAML document + # end + # end + # + def YAML.parse_documents( io, &doc_proc ) + YAML.each_node( io, &doc_proc ) + end + + # + # Loads all documents from the current _io_ stream, + # returning a +YAML::Stream+ object containing all + # loaded documents. + # + def YAML.load_stream( io ) + d = nil + parser.load_documents( io ) do |doc| + d = YAML::Stream.new if not d + d.add( doc ) + end + return d + end + + # + # Returns a YAML stream containing each of the items in +objs+, + # each having their own document. + # + # YAML.dump_stream( 0, [], {} ) + # #=> --- 0 + # --- [] + # --- {} + # + def YAML.dump_stream( *objs ) + d = YAML::Stream.new + objs.each do |doc| + d.add( doc ) + end + d.emit + end + + # + # Add a global handler for a YAML domain type. + # + def YAML.add_domain_type( domain, type_tag, &transfer_proc ) + resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc ) + end + + # + # Add a transfer method for a builtin type + # + def YAML.add_builtin_type( type_tag, &transfer_proc ) + resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc ) + end + + # + # Add a transfer method for a builtin type + # + def YAML.add_ruby_type( type_tag, &transfer_proc ) + resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc ) + end + + # + # Add a private document type + # + def YAML.add_private_type( type_re, &transfer_proc ) + resolver.add_type( "x-private:" + type_re, transfer_proc ) + end + + # + # Detect typing of a string + # + def YAML.detect_implicit( val ) + resolver.detect_implicit( val ) + end + + # + # Convert a type_id to a taguri + # + def YAML.tagurize( val ) + resolver.tagurize( val ) + end + + # + # Apply a transfer method to a Ruby object + # + def YAML.transfer( type_id, obj ) + resolver.transfer( YAML.tagurize( type_id ), obj ) + end + + # + # Apply any implicit a node may qualify for + # + def YAML.try_implicit( obj ) + YAML.transfer( YAML.detect_implicit( obj ), obj ) + end + + # + # Method to extract colon-seperated type and class, returning + # the type and the constant of the class + # + def YAML.read_type_class( type, obj_class ) + scheme, domain, type, tclass = type.split( ':', 4 ) + tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass + return [ type, obj_class ] + end + + # + # Allocate blank object + # + def YAML.object_maker( obj_class, val ) + if Hash === val + o = obj_class.allocate + val.each_pair { |k,v| + o.instance_variable_set("@#{k}", v) + } + o + else + raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect + end + end + + # + # Allocate an Emitter if needed + # + def YAML.quick_emit( oid, opts = {}, &e ) + out = + if opts.is_a? YAML::Emitter + opts + else + emitter.reset( opts ) + end + oid = + case oid when Fixnum, NilClass; oid + else oid = "#{oid.object_id}-#{oid.hash}" + end + out.emit( oid, &e ) + end + +end + +require 'yaml/rubytypes' +require 'yaml/types' + +module Kernel + # + # ryan:: You know how Kernel.p is a really convenient way to dump ruby + # structures? The only downside is that it's not as legible as + # YAML. + # + # _why:: (listening) + # + # ryan:: I know you don't want to urinate all over your users' namespaces. + # But, on the other hand, convenience of dumping for debugging is, + # IMO, a big YAML use case. + # + # _why:: Go nuts! Have a pony parade! + # + # ryan:: Either way, I certainly will have a pony parade. + # + + # Prints any supplied _objects_ out in YAML. Intended as + # a variation on +Kernel::p+. + # + # S = Struct.new(:name, :state) + # s = S['dave', 'TX'] + # y s + # + # _produces:_ + # + # --- !ruby/struct:S + # name: dave + # state: TX + # + def y( object, *objects ) + objects.unshift object + puts( if objects.length == 1 + YAML::dump( *objects ) + else + YAML::dump_stream( *objects ) + end ) + end + private :y +end + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/baseemitter.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/baseemitter.rb new file mode 100644 index 00000000..1aef1527 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/baseemitter.rb @@ -0,0 +1,247 @@ +# +# BaseEmitter +# + +require 'yaml/constants' +require 'yaml/encoding' +require 'yaml/error' + +module YAML + + module BaseEmitter + + def options( opt = nil ) + if opt + @options[opt] || YAML::DEFAULTS[opt] + else + @options + end + end + + def options=( opt ) + @options = opt + end + + # + # Emit binary data + # + def binary_base64( value ) + self << "!binary " + self.node_text( [value].pack("m"), '|' ) + end + + # + # Emit plain, normal flowing text + # + def node_text( value, block = nil ) + @seq_map = false + valx = value.dup + unless block + block = + if options(:UseBlock) + '|' + elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/ + '|' + else + '>' + end + + indt = $&.to_i if block =~ /\d+/ + if valx =~ /(\A\n*[ \t#]|^---\s+)/ + indt = options(:Indent) unless indt.to_i > 0 + block += indt.to_s + end + + block += + if valx =~ /\n\Z\n/ + "+" + elsif valx =~ /\Z\n/ + "" + else + "-" + end + end + block += "\n" + if block[0] == ?" + esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || "" + valx = fold( YAML::escape( valx, esc_skip ) + "\"" ).chomp + self << '"' + indent_text( valx, indt, false ) + else + if block[0] == ?> + valx = fold( valx ) + end + #p [block, indt] + self << block + indent_text( valx, indt ) + end + end + + # + # Emit a simple, unqouted string + # + def simple( value ) + @seq_map = false + self << value.to_s + end + + # + # Emit double-quoted string + # + def double( value ) + "\"#{YAML.escape( value )}\"" + end + + # + # Emit single-quoted string + # + def single( value ) + "'#{value}'" + end + + # + # Write a text block with the current indent + # + def indent_text( text, mod, first_line = true ) + return "" if text.to_s.empty? + spacing = indent( mod ) + text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line + return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" ) + end + + # + # Write a current indent + # + def indent( mod = nil ) + #p [ self.id, level, mod, :INDENT ] + if level <= 0 + mod ||= 0 + else + mod ||= options(:Indent) + mod += ( level - 1 ) * options(:Indent) + end + return " " * mod + end + + # + # Add indent to the buffer + # + def indent! + self << indent + end + + # + # Folding paragraphs within a column + # + def fold( value ) + value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do |s| + $1 || $2 + ( $3 || "\n" ) + end + end + + # + # Quick mapping + # + def map( type, &e ) + val = Mapping.new + e.call( val ) + self << "#{type} " if type.length.nonzero? + + # + # Empty hashes + # + if val.length.zero? + self << "{}" + @seq_map = false + else + # FIXME + # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? + # @headless = 1 + # end + + defkey = @options.delete( :DefaultKey ) + if defkey + seq_map_shortcut + self << "= : " + defkey.to_yaml( :Emitter => self ) + end + + # + # Emit the key and value + # + val.each { |v| + seq_map_shortcut + if v[0].is_complex_yaml? + self << "? " + end + v[0].to_yaml( :Emitter => self ) + if v[0].is_complex_yaml? + self << "\n" + indent! + end + self << ": " + v[1].to_yaml( :Emitter => self ) + } + end + end + + def seq_map_shortcut + # FIXME: seq_map needs to work with the new anchoring system + # if @seq_map + # @anchor_extras[@buffer.length - 1] = "\n" + indent + # @seq_map = false + # else + self << "\n" + indent! + # end + end + + # + # Quick sequence + # + def seq( type, &e ) + @seq_map = false + val = Sequence.new + e.call( val ) + self << "#{type} " if type.length.nonzero? + + # + # Empty arrays + # + if val.length.zero? + self << "[]" + else + # FIXME + # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? + # @headless = 1 + # end + + # + # Emit the key and value + # + val.each { |v| + self << "\n" + indent! + self << "- " + @seq_map = true if v.class == Hash + v.to_yaml( :Emitter => self ) + } + end + end + + end + + # + # Emitter helper classes + # + class Mapping < Array + def add( k, v ) + push [k, v] + end + end + + class Sequence < Array + def add( v ) + push v + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/basenode.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/basenode.rb new file mode 100644 index 00000000..5439903f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/basenode.rb @@ -0,0 +1,216 @@ +# +# YAML::BaseNode class +# +require 'yaml/ypath' + +module YAML + + # + # YAML Generic Model container + # + module BaseNode + + # + # Search for YPath entry and return + # qualified nodes. + # + def select( ypath_str ) + matches = match_path( ypath_str ) + + # + # Create a new generic view of the elements selected + # + if matches + result = [] + matches.each { |m| + result.push m.last + } + YAML.transfer( 'seq', result ) + end + end + + # + # Search for YPath entry and return + # transformed nodes. + # + def select!( ypath_str ) + matches = match_path( ypath_str ) + + # + # Create a new generic view of the elements selected + # + if matches + result = [] + matches.each { |m| + result.push m.last.transform + } + result + end + end + + # + # Search for YPath entry and return a list of + # qualified paths. + # + def search( ypath_str ) + matches = match_path( ypath_str ) + + if matches + matches.collect { |m| + path = [] + m.each_index { |i| + path.push m[i] if ( i % 2 ).zero? + } + "/" + path.compact.join( "/" ) + } + end + end + + def at( seg ) + if Hash === @value + self[seg] + elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i] + @value[seg.to_i] + end + end + + # + # YPath search returning a complete depth array + # + def match_path( ypath_str ) + depth = 0 + matches = [] + YPath.each_path( ypath_str ) do |ypath| + seg = match_segment( ypath, 0 ) + matches += seg if seg + end + matches.uniq + end + + # + # Search a node for a single YPath segment + # + def match_segment( ypath, depth ) + deep_nodes = [] + seg = ypath.segments[ depth ] + if seg == "/" + unless String === @value + idx = -1 + @value.collect { |v| + idx += 1 + if Hash === @value + match_init = [v[0].transform, v[1]] + match_deep = v[1].match_segment( ypath, depth ) + else + match_init = [idx, v] + match_deep = v.match_segment( ypath, depth ) + end + if match_deep + match_deep.each { |m| + deep_nodes.push( match_init + m ) + } + end + } + end + depth += 1 + seg = ypath.segments[ depth ] + end + match_nodes = + case seg + when "." + [[nil, self]] + when ".." + [["..", nil]] + when "*" + if @value.is_a? Enumerable + idx = -1 + @value.collect { |h| + idx += 1 + if Hash === @value + [h[0].transform, h[1]] + else + [idx, h] + end + } + end + else + if seg =~ /^"(.*)"$/ + seg = $1 + elsif seg =~ /^'(.*)'$/ + seg = $1 + end + if ( v = at( seg ) ) + [[ seg, v ]] + end + end + return deep_nodes unless match_nodes + pred = ypath.predicates[ depth ] + if pred + case pred + when /^\.=/ + pred = $' # ' + match_nodes.reject! { |n| + n.last.value != pred + } + else + match_nodes.reject! { |n| + n.last.at( pred ).nil? + } + end + end + return match_nodes + deep_nodes unless ypath.segments.length > depth + 1 + + #puts "DEPTH: #{depth + 1}" + deep_nodes = [] + match_nodes.each { |n| + if n[1].is_a? BaseNode + match_deep = n[1].match_segment( ypath, depth + 1 ) + if match_deep + match_deep.each { |m| + deep_nodes.push( n + m ) + } + end + else + deep_nodes = [] + end + } + deep_nodes = nil if deep_nodes.length == 0 + deep_nodes + end + + # + # We want the node to act like as Hash + # if it is. + # + def []( *key ) + if Hash === @value + v = @value.detect { |k,| k.transform == key.first } + v[1] if v + elsif Array === @value + @value.[]( *key ) + end + end + + def children + if Hash === @value + @value.values.collect { |c| c[1] } + elsif Array === @value + @value + end + end + + def children_with_index + if Hash === @value + @value.keys.collect { |i| [self[i], i] } + elsif Array === @value + i = -1; @value.collect { |v| i += 1; [v, i] } + end + end + + def emit + transform.to_yaml + end + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/constants.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/constants.rb new file mode 100644 index 00000000..fb833d30 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/constants.rb @@ -0,0 +1,45 @@ +# +# Constants used throughout the library +# +module YAML + + # + # Constants + # + VERSION = '0.60' + SUPPORTED_YAML_VERSIONS = ['1.0'] + + # + # Parser tokens + # + WORD_CHAR = 'A-Za-z0-9' + PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". ' + NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f' + ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]' + INDICATOR_CHAR = '*&!|\\\\^@%{}[]=' + SPACE_INDICATORS = '-#:,?' + RESTRICTED_INDICATORS = '#:,}]' + DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?" + DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})" + ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a + \x08 \t \n \v \f \r \x0e \x0f + \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 + \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f + } + UNESCAPES = { + 'a' => "\x07", 'b' => "\x08", 't' => "\x09", + 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c", + 'r' => "\x0d", 'e' => "\x1b", '\\' => '\\', + } + + # + # Default settings + # + DEFAULTS = { + :Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0', + :SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false, + :WidthType => 'absolute', :BestWidth => 80, + :UseBlock => false, :UseFold => false, :Encoding => :None + } + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/dbm.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/dbm.rb new file mode 100644 index 00000000..87d60092 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/dbm.rb @@ -0,0 +1,111 @@ +require 'yaml' +require 'dbm' +# +# YAML + DBM = YDBM +# - Same interface as DBM class +# +module YAML + +class DBM < ::DBM + VERSION = "0.1" + def []( key ) + fetch( key ) + end + def []=( key, val ) + store( key, val ) + end + def fetch( keystr, ifnone = nil ) + begin + val = super( keystr ) + return YAML::load( val ) if String === val + rescue IndexError + end + if block_given? + yield keystr + else + ifnone + end + end + def index( keystr ) + super( keystr.to_yaml ) + end + def values_at( *keys ) + keys.collect { |k| fetch( k ) } + end + def delete( key ) + v = super( key ) + if String === v + v = YAML::load( v ) + end + v + end + def delete_if + del_keys = keys.dup + del_keys.delete_if { |k| yield( k, fetch( k ) ) == false } + del_keys.each { |k| delete( k ) } + self + end + def reject + hsh = self.to_hash + hsh.reject { |k,v| yield k, v } + end + def each_pair + keys.each { |k| yield k, fetch( k ) } + self + end + def each_value + super { |v| yield YAML::load( v ) } + self + end + def values + super.collect { |v| YAML::load( v ) } + end + def has_value?( val ) + each_value { |v| return true if v == val } + return false + end + def invert + h = {} + keys.each { |k| h[ self.fetch( k ) ] = k } + h + end + def replace( hsh ) + clear + update( hsh ) + end + def shift + a = super + a[1] = YAML::load( a[1] ) if a + a + end + def select( *keys ) + if block_given? + self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact + else + values_at( *keys ) + end + end + def store( key, val ) + super( key, val.to_yaml ) + val + end + def update( hsh ) + hsh.keys.each do |k| + self.store( k, hsh.fetch( k ) ) + end + self + end + def to_a + a = [] + keys.each { |k| a.push [ k, self.fetch( k ) ] } + a + end + def to_hash + h = {} + keys.each { |k| h[ k ] = self.fetch( k ) } + h + end + alias :each :each_pair +end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/encoding.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/encoding.rb new file mode 100644 index 00000000..37f5cfda --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/encoding.rb @@ -0,0 +1,33 @@ +# +# Handle Unicode-to-Internal conversion +# + +module YAML + + # + # Escape the string, condensing common escapes + # + def YAML.escape( value, skip = "" ) + value.gsub( /\\/, "\\\\\\" ). + gsub( /"/, "\\\"" ). + gsub( /([\x00-\x1f])/ ) do |x| + skip[x] || ESCAPES[ x.unpack("C")[0] ] + end + end + + # + # Unescape the condenses escapes + # + def YAML.unescape( value ) + value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { |x| + if $3 + ["#$3".hex ].pack('U*') + elsif $2 + [$2].pack( "H2" ) + else + UNESCAPES[$1] + end + } + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/error.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/error.rb new file mode 100644 index 00000000..15865a9a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/error.rb @@ -0,0 +1,34 @@ +# +# Error messages and exception class +# + +module YAML + + # + # Error messages + # + + ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements" + ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash" + ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'" + ERROR_MANY_EXPLICIT = "More than one explicit transfer" + ERROR_MANY_IMPLICIT = "More than one implicit request" + ERROR_NO_ANCHOR = "No anchor for alias '%s'" + ERROR_BAD_ANCHOR = "Invalid anchor: %s" + ERROR_MANY_ANCHOR = "More than one anchor" + ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias" + ERROR_BAD_ALIAS = "Invalid alias: %s" + ERROR_MANY_ALIAS = "More than one alias" + ERROR_ZERO_INDENT = "Can't use zero as an indentation width" + ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s" + ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s" + + # + # YAML Error classes + # + + class Error < StandardError; end + class ParseError < Error; end + class TypeError < StandardError; end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/loader.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/loader.rb new file mode 100644 index 00000000..eb0709e1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/loader.rb @@ -0,0 +1,14 @@ +# +# YAML::Loader class +# .. type handling .. +# +module YAML + class Loader + TRANSFER_DOMAINS = { + 'yaml.org,2002' => {}, + 'ruby.yaml.org,2002' => {} + } + PRIVATE_TYPES = {} + IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ] + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/rubytypes.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/rubytypes.rb new file mode 100644 index 00000000..dc6bb335 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/rubytypes.rb @@ -0,0 +1,408 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +require 'date' + +class Class + def to_yaml( opts = {} ) + raise TypeError, "can't dump anonymous class %s" % self.class + end +end + +class Object + yaml_as "tag:ruby.yaml.org,2002:object" + def to_yaml_style; end + def to_yaml_properties; instance_variables.sort; end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + to_yaml_properties.each do |m| + map.add( m[1..-1], instance_variable_get( m ) ) + end + end + end + end +end + +class Hash + yaml_as "tag:ruby.yaml.org,2002:hash" + yaml_as "tag:yaml.org,2002:map" + def yaml_initialize( tag, val ) + if Array === val + update Hash.[]( *val ) # Convert the map to a sequence + elsif Hash === val + update val + else + raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + each do |k, v| + map.add( k, v ) + end + end + end + end +end + +class Struct + yaml_as "tag:ruby.yaml.org,2002:struct" + def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end + def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end + def self.yaml_new( klass, tag, val ) + if Hash === val + struct_type = nil + + # + # Use existing Struct if it exists + # + props = {} + val.delete_if { |k,v| props[k] = v if k =~ /^@/ } + begin + struct_name, struct_type = YAML.read_type_class( tag, Struct ) + rescue NameError + end + if not struct_type + struct_def = [ tag.split( ':', 4 ).last ] + struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) ) + end + + # + # Set the Struct properties + # + st = YAML::object_maker( struct_type, {} ) + st.members.each do |m| + st.send( "#{m}=", val[m] ) + end + props.each do |k,v| + st.instance_variable_set(k, v) + end + st + else + raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + # + # Basic struct is passed as a YAML map + # + out.map( taguri, to_yaml_style ) do |map| + self.members.each do |m| + map.add( m, self[m] ) + end + self.to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end +end + +class Array + yaml_as "tag:ruby.yaml.org,2002:array" + yaml_as "tag:yaml.org,2002:seq" + def yaml_initialize( tag, val ); concat( val.to_a ); end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + each do |x| + seq.add( x ) + end + end + end + end +end + +class Exception + yaml_as "tag:ruby.yaml.org,2002:exception" + def Exception.yaml_new( klass, tag, val ) + o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } ) + val.each_pair do |k,v| + o.instance_variable_set("@#{k}", v) + end + o + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + map.add( 'message', message ) + to_yaml_properties.each do |m| + map.add( m[1..-1], instance_variable_get( m ) ) + end + end + end + end +end + +class String + yaml_as "tag:ruby.yaml.org,2002:string" + yaml_as "tag:yaml.org,2002:binary" + yaml_as "tag:yaml.org,2002:str" + def is_complex_yaml? + to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/ + end + def is_binary_data? + ( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 ) unless empty? + end + def String.yaml_new( klass, tag, val ) + val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary" + val = { 'str' => val } if String === val + if Hash === val + s = klass.allocate + # Thank you, NaHi + String.instance_method(:initialize). + bind(s). + call( val.delete( 'str' ) ) + val.each { |k,v| s.instance_variable_set( k, v ) } + s + else + raise YAML::TypeError, "Invalid String: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out| + if is_binary_data? + out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal ) + elsif to_yaml_properties.empty? + out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style ) + else + out.map( taguri, to_yaml_style ) do |map| + map.add( 'str', "#{self}" ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Symbol + yaml_as "tag:ruby.yaml.org,2002:symbol" + yaml_as "tag:ruby.yaml.org,2002:sym" + def Symbol.yaml_new( klass, tag, val ) + if String === val + val = YAML::load( val ) if val =~ /\A(["']).*\1\z/ + val.intern + else + raise YAML::TypeError, "Invalid Symbol: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain ) + end + end +end + +class Range + yaml_as "tag:ruby.yaml.org,2002:range" + def Range.yaml_new( klass, tag, val ) + inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")' + opts = {} + if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o + r1, rdots, r2 = $1, $2, $3 + opts = { + 'begin' => YAML.load( "--- #{r1}" ), + 'end' => YAML.load( "--- #{r2}" ), + 'excl' => rdots.length == 3 + } + val = {} + elsif Hash === val + opts['begin'] = val.delete('begin') + opts['end'] = val.delete('end') + opts['excl'] = val.delete('excl') + end + if Hash === opts + r = YAML::object_maker( klass, {} ) + # Thank you, NaHi + Range.instance_method(:initialize). + bind(r). + call( opts['begin'], opts['end'], opts['excl'] ) + val.each { |k,v| r.instance_variable_set( k, v ) } + r + else + raise YAML::TypeError, "Invalid Range: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or + # self.end.is_complex_yaml? or self.end.respond_to? :to_str or + # not to_yaml_properties.empty? + out.map( taguri, to_yaml_style ) do |map| + map.add( 'begin', self.begin ) + map.add( 'end', self.end ) + map.add( 'excl', self.exclude_end? ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + # else + # out.scalar( taguri ) do |sc| + # sc.embed( self.begin ) + # sc.concat( self.exclude_end? ? "..." : ".." ) + # sc.embed( self.end ) + # end + # end + end + end +end + +class Regexp + yaml_as "tag:ruby.yaml.org,2002:regexp" + def Regexp.yaml_new( klass, tag, val ) + if String === val and val =~ /^\/(.*)\/([mix]*)$/ + val = { 'regexp' => $1, 'mods' => $2 } + end + if Hash === val + mods = nil + unless val['mods'].to_s.empty? + mods = 0x00 + mods |= Regexp::EXTENDED if val['mods'].include?( 'x' ) + mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' ) + mods |= Regexp::MULTILINE if val['mods'].include?( 'm' ) + end + val.delete( 'mods' ) + r = YAML::object_maker( klass, {} ) + Regexp.instance_method(:initialize). + bind(r). + call( val.delete( 'regexp' ), mods ) + val.each { |k,v| r.instance_variable_set( k, v ) } + r + else + raise YAML::TypeError, "Invalid Regular expression: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + if to_yaml_properties.empty? + out.scalar( taguri, self.inspect, :plain ) + else + out.map( taguri, to_yaml_style ) do |map| + src = self.inspect + if src =~ /\A\/(.*)\/([a-z]*)\Z/ + map.add( 'regexp', $1 ) + map.add( 'mods', $2 ) + else + raise YAML::TypeError, "Invalid Regular expression: " + src + end + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Time + yaml_as "tag:ruby.yaml.org,2002:time" + yaml_as "tag:yaml.org,2002:timestamp" + def Time.yaml_new( klass, tag, val ) + if Hash === val + t = val.delete( 'at' ) + val.each { |k,v| t.instance_variable_set( k, v ) } + t + else + raise YAML::TypeError, "Invalid Time: " + val.inspect + end + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + tz = "Z" + # from the tidy Tobias Peters Thanks! + unless self.utc? + utc_same_instant = self.dup.utc + utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec) + difference_to_utc = utc_same_writing - utc_same_instant + if (difference_to_utc < 0) + difference_sign = '-' + absolute_difference = -difference_to_utc + else + difference_sign = '+' + absolute_difference = difference_to_utc + end + difference_minutes = (absolute_difference/60).round + tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60] + end + standard = self.strftime( "%Y-%m-%d %H:%M:%S" ) + standard += ".%06d" % [usec] if usec.nonzero? + standard += " %s" % [tz] + if to_yaml_properties.empty? + out.scalar( taguri, standard, :plain ) + else + out.map( taguri, to_yaml_style ) do |map| + map.add( 'at', standard ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Date + yaml_as "tag:yaml.org,2002:timestamp#ymd" + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain ) + end + end +end + +class Integer + yaml_as "tag:yaml.org,2002:int" + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain ) + end + end +end + +class Float + yaml_as "tag:yaml.org,2002:float" + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + str = self.to_s + if str == "Infinity" + str = ".Inf" + elsif str == "-Infinity" + str = "-.Inf" + elsif str == "NaN" + str = ".NaN" + end + out.scalar( "tag:yaml.org,2002:float", str, :plain ) + end + end +end + +class TrueClass + yaml_as "tag:yaml.org,2002:bool#yes" + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "true", :plain ) + end + end +end + +class FalseClass + yaml_as "tag:yaml.org,2002:bool#no" + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "false", :plain ) + end + end +end + +class NilClass + yaml_as "tag:yaml.org,2002:null" + def to_yaml( opts = {} ) + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "", :plain ) + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/store.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/store.rb new file mode 100644 index 00000000..2ffa9554 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/store.rb @@ -0,0 +1,29 @@ +# +# YAML::Store +# +require 'yaml' +require 'pstore' + +class YAML::Store < PStore + def initialize( *o ) + @opt = YAML::DEFAULTS.dup + if String === o.first + super(o.shift) + end + if o.last.is_a? Hash + @opt.update(o.pop) + end + end + + def dump(table) + @table.to_yaml(@opt) + end + + def load(content) + YAML::load(content) + end + + def load_file(file) + YAML::load(file) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/stream.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/stream.rb new file mode 100644 index 00000000..060fbc42 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/stream.rb @@ -0,0 +1,40 @@ +module YAML + + # + # YAML::Stream -- for emitting many documents + # + class Stream + + attr_accessor :documents, :options + + def initialize( opts = {} ) + @options = opts + @documents = [] + end + + def []( i ) + @documents[ i ] + end + + def add( doc ) + @documents << doc + end + + def edit( doc_num, doc ) + @documents[ doc_num ] = doc + end + + def emit( io = nil ) + # opts = @options.dup + # opts[:UseHeader] = true if @documents.length > 1 + out = YAML.emitter + out.reset( io || io2 = StringIO.new ) + @documents.each { |v| + v.to_yaml( out ) + } + io || ( io2.rewind; io2.read ) + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/stringio.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/stringio.rb new file mode 100644 index 00000000..8ad949fa --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/stringio.rb @@ -0,0 +1,83 @@ +# +# Limited StringIO if no core lib is available +# +begin +require 'stringio' +rescue LoadError + # StringIO based on code by MoonWolf + class StringIO + def initialize(string="") + @string=string + @pos=0 + @eof=(string.size==0) + end + def pos + @pos + end + def eof + @eof + end + alias eof? eof + def readline(rs=$/) + if @eof + raise EOFError + else + if p = @string[@pos..-1]=~rs + line = @string[@pos,p+1] + else + line = @string[@pos..-1] + end + @pos+=line.size + @eof =true if @pos==@string.size + $_ = line + end + end + def rewind + seek(0,0) + end + def seek(offset,whence) + case whence + when 0 + @pos=offset + when 1 + @pos+=offset + when 2 + @pos=@string.size+offset + end + @eof=(@pos>=@string.size) + 0 + end + end + + # + # Class method for creating streams + # + def YAML.make_stream( io ) + if String === io + io = StringIO.new( io ) + elsif not IO === io + raise YAML::Error, "YAML stream must be an IO or String object." + end + if YAML::unicode + def io.readline + YAML.utf_to_internal( readline( @ln_sep ), @utf_encoding ) + end + def io.check_unicode + @utf_encoding = YAML.sniff_encoding( read( 4 ) ) + @ln_sep = YAML.enc_separator( @utf_encoding ) + seek( -4, IO::SEEK_CUR ) + end + def io.utf_encoding + @utf_encoding + end + io.check_unicode + else + def io.utf_encoding + :None + end + end + io + end + +end + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/syck.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/syck.rb new file mode 100644 index 00000000..faf57e80 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/syck.rb @@ -0,0 +1,19 @@ +# +# YAML::Syck module +# .. glues syck and yaml.rb together .. +# +require 'syck' +require 'yaml/basenode' + +module YAML + module Syck + + # + # Mixin BaseNode functionality + # + class Node + include YAML::BaseNode + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/tag.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/tag.rb new file mode 100644 index 00000000..a91f2bd8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/tag.rb @@ -0,0 +1,91 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +# $Id: tag.rb 11708 2007-02-12 23:01:19Z shyouhei $ +# +# = yaml/tag.rb: methods for associating a taguri to a class. +# +# Author:: why the lucky stiff +# +module YAML + # A dictionary of taguris which map to + # Ruby classes. + @@tagged_classes = {} + + # + # Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types + # to classes when loading YAML. Taguris are of the form: + # + # tag:authorityName,date:specific + # + # The +authorityName+ is a domain name or email address. The +date+ is the date the type + # was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for + # the type being added. + # + # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the + # +date+. The +specific+ is simply the name of the type: + # + # tag:yaml.org,2002:int + # tag:yaml.org,2002:float + # tag:yaml.org,2002:timestamp + # + # The domain must be owned by you on the +date+ declared. If you don't own any domains on the + # date you declare the type, you can simply use an e-mail address. + # + # tag:why@ruby-lang.org,2004:notes/personal + # + def YAML.tag_class( tag, cls ) + if @@tagged_classes.has_key? tag + warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag" + end + @@tagged_classes[tag] = cls + end + + # Returns the complete dictionary of taguris, paired with classes. The key for + # the dictionary is the full taguri. The value for each key is the class constant + # associated to that taguri. + # + # YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer + # + def YAML.tagged_classes + @@tagged_classes + end +end + +class Module + # :stopdoc: + + # Adds a taguri _tag_ to a class, used when dumping or loading the class + # in YAML. See YAML::tag_class for detailed information on typing and + # taguris. + def yaml_as( tag, sc = true ) + verbose, $VERBOSE = $VERBOSE, nil + class_eval <<-"end;", __FILE__, __LINE__+1 + attr_writer :taguri + def taguri + if respond_to? :to_yaml_type + YAML::tagurize( to_yaml_type[1..-1] ) + else + return @taguri if defined?(@taguri) and @taguri + tag = #{ tag.dump } + if self.class.yaml_tag_subclasses? and self.class != YAML::tagged_classes[tag] + tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }" + end + tag + end + end + def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end + end; + YAML::tag_class tag, self + ensure + $VERBOSE = verbose + end + # Transforms the subclass name into a name suitable for display + # in a subclassed tag. + def yaml_tag_class_name + self.name + end + # Transforms the subclass name found in the tag into a Ruby + # constant name. + def yaml_tag_read_class( name ) + name + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/types.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/types.rb new file mode 100644 index 00000000..3871c628 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/types.rb @@ -0,0 +1,192 @@ +# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4 +# +# Classes required by the full core typeset +# + +module YAML + + # + # Default private type + # + class PrivateType + def self.tag_subclasses?; false; end + verbose, $VERBOSE = $VERBOSE, nil + def initialize( type, val ) + @type_id = type; @value = val + @value.taguri = "x-private:#{ @type_id }" + end + def to_yaml( opts = {} ) + @value.to_yaml( opts ) + end + ensure + $VERBOSE = verbose + end + + # + # Default domain type + # + class DomainType + def self.tag_subclasses?; false; end + verbose, $VERBOSE = $VERBOSE, nil + def initialize( domain, type, val ) + @domain = domain; @type_id = type; @value = val + @value.taguri = "tag:#{ @domain }:#{ @type_id }" + end + def to_yaml( opts = {} ) + @value.to_yaml( opts ) + end + ensure + $VERBOSE = verbose + end + + # + # Unresolved objects + # + class Object + def self.tag_subclasses?; false; end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map| + @ivars.each do |k,v| + map.add( k, v ) + end + end + end + end + end + + # + # YAML Hash class to support comments and defaults + # + class SpecialHash < ::Hash + attr_accessor :default + def inspect + self.default.to_s + end + def to_s + self.default.to_s + end + def update( h ) + if YAML::SpecialHash === h + @default = h.default if h.default + end + super( h ) + end + def to_yaml( opts = {} ) + opts[:DefaultKey] = self.default + super( opts ) + end + end + + # + # Builtin collection: !omap + # + class Omap < ::Array + yaml_as "tag:yaml.org,2002:omap" + def yaml_initialize( tag, val ) + if Array === val + val.each do |v| + if Hash === v + concat( v.to_a ) # Convert the map to a sequence + else + raise YAML::Error, "Invalid !omap entry: " + val.inspect + end + end + else + raise YAML::Error, "Invalid !omap: " + val.inspect + end + self + end + def self.[]( *vals ) + o = Omap.new + 0.step( vals.length - 1, 2 ) do |i| + o[vals[i]] = vals[i+1] + end + o + end + def []( k ) + self.assoc( k ).to_a[1] + end + def []=( k, *rest ) + val, set = rest.reverse + if ( tmp = self.assoc( k ) ) and not set + tmp[1] = val + else + self << [ k, val ] + end + val + end + def has_key?( k ) + self.assoc( k ) ? true : false + end + def is_complex_yaml? + true + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + self.each do |v| + seq.add( Hash[ *v ] ) + end + end + end + end + end + + # + # Builtin collection: !pairs + # + class Pairs < ::Array + yaml_as "tag:yaml.org,2002:pairs" + def yaml_initialize( tag, val ) + if Array === val + val.each do |v| + if Hash === v + concat( v.to_a ) # Convert the map to a sequence + else + raise YAML::Error, "Invalid !pairs entry: " + val.inspect + end + end + else + raise YAML::Error, "Invalid !pairs: " + val.inspect + end + self + end + def self.[]( *vals ) + p = Pairs.new + 0.step( vals.length - 1, 2 ) { |i| + p[vals[i]] = vals[i+1] + } + p + end + def []( k ) + self.assoc( k ).to_a + end + def []=( k, val ) + self << [ k, val ] + val + end + def has_key?( k ) + self.assoc( k ) ? true : false + end + def is_complex_yaml? + true + end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + self.each do |v| + seq.add( Hash[ *v ] ) + end + end + end + end + end + + # + # Builtin collection: !set + # + class Set < ::Hash + yaml_as "tag:yaml.org,2002:set" + end +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/yamlnode.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/yamlnode.rb new file mode 100644 index 00000000..e36a18e6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/yamlnode.rb @@ -0,0 +1,54 @@ +# +# YAML::YamlNode class +# +require 'yaml/basenode' + +module YAML + + # + # YAML Generic Model container + # + class YamlNode + include BaseNode + attr_accessor :kind, :type_id, :value, :anchor + def initialize( t, v ) + @type_id = t + if Hash === v + @kind = 'map' + @value = {} + v.each { |k,v| + @value[ k.transform ] = [ k, v ] + } + elsif Array === v + @kind = 'seq' + @value = v + elsif String === v + @kind = 'scalar' + @value = v + end + end + + # + # Transform this node fully into a native type + # + def transform + t = nil + if @value.is_a? Hash + t = {} + @value.each { |k,v| + t[ k ] = v[1].transform + } + elsif @value.is_a? Array + t = [] + @value.each { |v| + t.push v.transform + } + else + t = @value + end + YAML.transfer_method( @type_id, t ) + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/ypath.rb b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/ypath.rb new file mode 100644 index 00000000..81348ca0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/IronRuby/lib/ruby/1.8/yaml/ypath.rb @@ -0,0 +1,52 @@ +# +# YAML::YPath +# + +module YAML + + class YPath + attr_accessor :segments, :predicates, :flags + def initialize( str ) + @segments = [] + @predicates = [] + @flags = nil + while str =~ /^\/?(\/|[^\/\[]+)(?:\[([^\]]+)\])?/ + @segments.push $1 + @predicates.push $2 + str = $' + end + unless str.to_s.empty? + @segments += str.split( "/" ) + end + if @segments.length == 0 + @segments.push "." + end + end + def YPath.each_path( str ) + # + # Find choices + # + paths = [] + str = "(#{ str })" + while str.sub!( /\(([^()]+)\)/, "\n#{ paths.length }\n" ) + paths.push $1.split( '|' ) + end + + # + # Construct all possible paths + # + all = [ str ] + ( paths.length - 1 ).downto( 0 ) do |i| + all = all.collect do |a| + paths[i].collect do |p| + a.gsub( /\n#{ i }\n/, p ) + end + end.flatten.uniq + end + all.collect do |path| + yield YPath.new( path ) + end + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.CPL.txt b/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.CPL.txt new file mode 100644 index 00000000..a8e6c050 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.CPL.txt @@ -0,0 +1,86 @@ +Common Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + + c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.MSPL.html b/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.MSPL.html new file mode 100644 index 00000000..24f7dc67 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.MSPL.html @@ -0,0 +1,44 @@ + + + +Microsoft Public License (Ms-PL) + + + + +

    This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.

    + +

    The software is governed by the Microsoft Public License, the terms of which +are below; except for the Ruby Standard libraries which are governed by the +Ruby license. We have included a copy of the Ruby license in the same +directory as this file

    + +

    1. Definitions

    +

    The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the same meaning here as under U.S. copyright law.

    +

    A “contribution” is the original software, or any additions or changes to the software.

    +

    A “contributor” is any person that distributes its contribution under this license.

    +

    “Licensed patents” are a contributor’s patent claims that read directly on its contribution.

    +

    2. Grant of Rights

    +

    (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright +license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.

    + +

    (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, +royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative +works of the contribution in the software.

    + +

    3. Conditions and Limitations

    (A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks.

    +

    (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.

    +

    (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.

    +

    (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. +If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.

    + +

    (E) The software is licensed “as-is.” You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional +consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, +fitness for a particular purpose and non-infringement.

    + +

    See FAQ.html for answers to frequently asked questions +about this license.

    + + + + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.Ruby.txt b/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.Ruby.txt new file mode 100644 index 00000000..4a99f6f0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/LICENSE.Ruby.txt @@ -0,0 +1,58 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the GPL +(see COPYING.txt file), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or executable + form, provided that you do at least ONE of the following: + + a) distribute the executables and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard executables non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under this terms. + + They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some + files under the ./missing directory. See each file for the copying + condition. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. + diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Dynamic.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Dynamic.dll new file mode 100644 index 00000000..c4dd1f20 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Dynamic.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.Core.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.Core.dll new file mode 100644 index 00000000..b175e5c0 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.Core.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.ExtensionAttribute.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.ExtensionAttribute.dll new file mode 100644 index 00000000..22c8d5d0 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.ExtensionAttribute.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.dll b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.dll new file mode 100644 index 00000000..fc5b52ed Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/Microsoft.Scripting.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/ir.exe b/lib/Gallio_3.1.397.0/bin/DLR/libs/ir.exe new file mode 100644 index 00000000..49c611b8 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/DLR/libs/ir.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/DLR/libs/ir.exe.config b/lib/Gallio_3.1.397.0/bin/DLR/libs/ir.exe.config new file mode 100644 index 00000000..eff9d98d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/DLR/libs/ir.exe.config @@ -0,0 +1,16 @@ + + + +
    + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.Server.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.Server.exe new file mode 100644 index 00000000..6c3f7521 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.Server.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.Server.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.Server.exe.config new file mode 100644 index 00000000..f9b9c920 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.Server.exe.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.UI.dll b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.UI.dll new file mode 100644 index 00000000..d4c4a590 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.UI.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.UI.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.UI.plugin new file mode 100644 index 00000000..85cebfdc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.UI.plugin @@ -0,0 +1,46 @@ + + + + Gallio Ambience UI + 3.1.0.0 + Ambience UI components. + + + + + + + + + + + + + + + + + + + + + Ambience + + + + + + Ambience/Server + Machine + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.dll b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.dll new file mode 100644 index 00000000..99e37266 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.pdb b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.pdb new file mode 100644 index 00000000..e049bb8b Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.plugin new file mode 100644 index 00000000..1f8e869c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.plugin @@ -0,0 +1,30 @@ + + + + Gallio Ambience Library + 3.1.0.0 + Provides a lightweight object database based on db4o for storing test data across test runs. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.xml b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.xml new file mode 100644 index 00000000..eab9b22e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Ambience.xml @@ -0,0 +1,337 @@ + + + + Gallio.Ambience + + + + + The Ambience client accesses shared data provided by a remote . + + + + + Connects the client to the remote server. + + The client configuration. + Thrown if is null. + Thrown if the operation failed. + + + + Gets the client's data container. + + Thrown if the client has been disposed. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Provides configuration data for . + + + + Initializes a new instance of the class + + + + Gets or sets the Ambient server username and password. + + Thrown if is null. + + + + Gets or sets the Ambient server hostname. + + Thrown if is null. + Thrown if is empty. + + + + Gets or sets the Ambient server port number. + + Thrown if the port number is not in the range 1..65535. + + + + Describes a problem accessing Gallio Ambience. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Recognizes and processes the <ambience> configuration section. + + + + Initializes a new instance of the class + + + + Creates a configuration section handler. + + + Parent object. + + + Configuration context object. + + + Section XML node. + + + The created section handler object. + + + + + The name of the Ambience section: "ambience". + + + + + The Ambience server provides shared data to remote s. + + + + + Creates an ambient server with parameters initialized to defaults. + + The server configuration. + Thrown if is null. + + + + Stops and disposes the server. + + + + + Stops and disposes the server. + + True if disposing. + + + + Starts the server. + + Thrown if the server has already been started. + Thrown if the server has been disposed. + Thrown if the operation failed. + + + + Stops the server. + + Thrown if the server has been disposed. + + + + Provides configuration data for . + + + + Initializes a new instance of the class + + + + Gets or sets the Ambient server username and password. + + Thrown if is null. + + + + Gets or sets the database file path. + + + + + Gets or sets the Ambient server port number. + + Thrown if the port number is not in the range 1..65535. + + + + The Ambient object store is a shared lightweight repository for intermediate test data. + + + + + Gets the default ambient data container. + + Thrown if the operation failed. + + + + Gets or sets the default client configuration. + + Thrown if is null. + + + + Extension methods for LINQ syntax over Ambient data containers. + + + + + Obtains a query over a data container. + + The container. + The result type. + The query object. + + + + Extension methods for LINQ syntax over Ambient data queries. + + + + + Counts the number of objects produced by the query. + + The query. + The type of object being queried. + The number of objects. + + + + Produces a new query ordered by a comparison expression in ascending order. + + The query. + The sort comparison expression. + The type of object being queried. + The sort key type. + The ordered query. + + + + Produces a new query ordered by a comparison expression in descending order. + + The query. + The sort comparison expression. + The type of object being queried. + The sort key type. + The ordered query. + + + + Produces a new query to select a projection of a component of another query. + + The query. + The selection expression. + The type of object being queried. + The projection result type. + The projected query. + + + + Produces a new query ordered by an additional comparison expression in ascending order. + + The query. + The sort comparison expression. + The type of object being queried. + The sort key type. + The ordered query. + + + + Produces a new query ordered by an additional comparison expression in descending order. + + The query. + The sort comparison expression. + The type of object being queried. + The sort key type. + The ordered query. + + + + Produces a new query to filter another query by a criteria. + + The query. + The filter expression. + The type of object being queried. + The filtered query. + + + + Represents a container of Ambient data and providers operations to + query, store and update its contents. + + + + + Deletes the object from the container. + + The object to delete. + Thrown if the operation failed. + + + + Deletes all objects in the container. + + Thrown if the operation failed. + + + + Gets all objects of a particular type in the container. + + The object type. + The data set. + Thrown if the operation failed. + + + + Gets all objects of a particular type in the container that match a particular filtering criteria. + + The filtering criteria. + The object type. + The data set. + Thrown if the operation failed. + + + + Stores or updates an object in the container. + + The object to store. + Thrown if the operation failed. + + + + Represents a lazily evaluated query over Ambient data for use with + the LINQ query syntax. + + + + + A data set containing Ambient objects. + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.exe b/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.exe new file mode 100644 index 00000000..d8fec94b Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.exe.config new file mode 100644 index 00000000..88586cdb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.exe.config @@ -0,0 +1,12 @@ + + + +
    + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.plugin new file mode 100644 index 00000000..884c3b98 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.ControlPanel.plugin @@ -0,0 +1,18 @@ + + + + Gallio Control Panel + 3.1.0.0 + An application for configuring preferences and managing the Gallio installation. + plugin://Gallio.ControlPanel/Resources/Gallio.ControlPanel.ico + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Copy.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Copy.exe new file mode 100644 index 00000000..5c2f6641 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Copy.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Copy.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Copy.exe.config new file mode 100644 index 00000000..e4d5b41c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Copy.exe.config @@ -0,0 +1,24 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Copy.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Copy.plugin new file mode 100644 index 00000000..148a5b4f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Copy.plugin @@ -0,0 +1,24 @@ + + + + Gallio Copy Program + 3.1.0.0 + Creates and maintains partial copies of a Gallio installation. + plugin://Gallio.Copy/Resources/Gallio.Copy.ico + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Echo.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Echo.exe new file mode 100644 index 00000000..96e8d9e3 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Echo.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Echo.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Echo.exe.config new file mode 100644 index 00000000..e56e9886 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Echo.exe.config @@ -0,0 +1,26 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Echo.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Echo.plugin new file mode 100644 index 00000000..9b3dfcdb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Echo.plugin @@ -0,0 +1,18 @@ + + + + Gallio Echo + 3.1.0.0 + A command-line test runner. + plugin://Gallio.Echo/Resources/Gallio.Echo.ico + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.exe new file mode 100644 index 00000000..e5159659 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.exe.config new file mode 100644 index 00000000..d705f1c4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.exe.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.x86.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.x86.exe new file mode 100644 index 00000000..ca529432 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.x86.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.x86.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.x86.exe.config new file mode 100644 index 00000000..d705f1c4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Host.Elevated.x86.exe.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Host.exe new file mode 100644 index 00000000..2658401a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Host.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Host.exe.config new file mode 100644 index 00000000..d705f1c4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Host.exe.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.x86.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Host.x86.exe new file mode 100644 index 00000000..651757dd Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Host.x86.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Host.x86.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Host.x86.exe.config new file mode 100644 index 00000000..d705f1c4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Host.x86.exe.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.XmlSerializers.dll b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.XmlSerializers.dll new file mode 100644 index 00000000..0827a657 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.XmlSerializers.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.exe new file mode 100644 index 00000000..f5e5e535 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.exe.config new file mode 100644 index 00000000..6544b7ab --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.exe.config @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.plugin new file mode 100644 index 00000000..a3f416cd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Icarus.plugin @@ -0,0 +1,247 @@ + + + + + Gallio Icarus Test Runner + 3.1.0.0 + A GUI based test runner. + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Icarus + -75 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + Icarus/Appearance/Test Status + 100 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + Icarus/Startup + 200 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + Icarus/Test Explorer + 300 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + Icarus/Test Explorer/Tree View Categories + 1 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + Icarus/Reports + 1 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + Icarus/Appearance/Progress Monitoring + 1 + plugin://Gallio.Icarus/Resources/Gallio.Icarus.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.dll b/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.dll new file mode 100644 index 00000000..21ab05ca Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.plugin new file mode 100644 index 00000000..e77d6280 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.plugin @@ -0,0 +1,20 @@ + + + + Gallio MSBuild Tasks + 3.1.0.0 + Provides MSBuild tasks for running tests with Gallio. + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.xml b/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.xml new file mode 100644 index 00000000..21d94d73 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.MSBuildTasks.xml @@ -0,0 +1,252 @@ + + + + Gallio.MSBuildTasks + + + + + An MSBuild task that provides support for running Gallio tests. + + + + Initializes a new instance of the class + + + + + Gets or sets the relative or absolute path of the application base directory, + or null to use a default value selected by the consumer. + + + If relative, the path is based on the current working directory, + so a value of "" causes the current working directory to be used. + + + The default is null. + + + + + + Gets the number of assertions evaluated. + + + + + + Attaches the debugger to the test process when set to true. + + + The default is false. + + + + + + Sets whether to load the tests but not run them. This option may be used to produce a + report that contains test metadata for consumption by other tools. + + + + + Gets the duration of the tests execution in seconds. + + + + + Sets whether to echo results to the screen as tests finish. If this option is set + to true, the default, test results are echoed to the console + in varying detail depending on the current verbosity level. Otherwise + only final summary statistics are displayed. + + + + + When overridden in a derived class, executes the task. + + true if the task successfully executed; otherwise, false. + + + + + Gets the exit code of the tests execution. + + + + + Gets the total number of test cases that were run and failed. + + + + + The list of relative or absolute paths of test files, projects and assemblies to execute. + Wildcards may be used. This is required. + + + + + + Sets the filter set to apply, which consists of a sequence of one or more inclusion + or exclusion filter rules prefixed using 'include' (optional) or 'exclude'. + + + + + + The list of directories used for loading referenced assemblies and other dependent resources. + + + + + + Sets whether to ignore annotations when determining the result code. + If false (default), then error annotations, usually indicative of broken tests, will cause + a failure result to be generated. + + + + + + Sets whether test failures will be ignored and allow the build to proceed. + When set to false, test failures will cause the build to fail. + + + + + Gets the total number of test cases that ran and were inconclusive. + + + + + Gets the total number of test cases that were run and passed. + + + + + Additional Gallio plugin directories to search recursively. + + + + + Sets the name of the directory where the reports will be put. + + + + + Specifies option property key/value pairs for the report formatter. + + + + + Sets the format string to use to generate the reports filenames. + + + + + A list of the types of reports to generate, separated by semicolons. + + + + + Gets the total number of test cases that were run. + + + + + + Specifies the type, assembly, and parameters of custom test runner + extensions to use during the test run in the form: + '[Namespace.]Type,Assembly[;Parameters]'. + + + eg. 'FancyLogger,MyCustomExtensions.dll;SomeParameters' + + + + + + Specifies option property key/value pairs for the test runner. + + + + + Sets the type of test runner to use. + + + + + Sets the maximum amount of time (in seconds) the tests can run + before they are canceled. The default is an infinite time to run. + + + + + + Gets or sets the version of the .Net runtime to use for running tests. + + + For the CLR, this must be the name of one of the framework directories in %SystemRoot%\Microsoft.Net\Framework. eg. 'v2.0.50727'. + + + The default is null which uses the most recent installed and supported framework. + + + + + + + Enables shadow copying when set to true. + + + Shadow copying allows the original assemblies to be modified while the tests are running. + However, shadow copying may occasionally cause some tests to fail if they depend on their original location. + + + The default is false. + + + + + + Sets whether to show generated reports in a window using the default system application + registered to the report file type. + + + + + Gets the total number of test cases that did not run because they were skipped. + + + + + Gets the total number of test steps run. + + + + + Gets the total number of test cases run. + + + + + The verbosity to use when logging. The default is "Normal". + + + + + + Gets or sets the relative or absolute path of the working directory + or null to use a default value selected by the consumer. + + + If relative, the path is based on the current working directory, + so a value of "" causes the current working directory to be used. + + + The default is null. + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.dll b/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.dll new file mode 100644 index 00000000..03ce2056 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.plugin new file mode 100644 index 00000000..cb1cf92f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.plugin @@ -0,0 +1,20 @@ + + + + Gallio NAnt Tasks + 3.1.0.0 + Provides NAnt tasks for running tests with Gallio. + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.xml b/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.xml new file mode 100644 index 00000000..9b8e617f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.NAntTasks.xml @@ -0,0 +1,150 @@ + + + + Gallio.NAntTasks + + + + + A NAnt task that provides support for running Gallio tests. + + + + Initializes a new instance of the class + + + + Gets or sets the relative or absolute path of the application base directory, + or null to use a default value selected by the consumer. + + + + + Attaches the debugger to the test process when set to true. + + + + + Sets whether to load the tests but not run them. + + + + + Sets whether to echo results to the screen as tests finish. + + + + + Executes the task. + + + + + The list of test files, projects and assemblies to execute. + + + + + + Sets the filter set to apply, which consists of a sequence of one or more inclusion + or exclusion filter rules prefixed using 'include' (optional) or 'exclude'. + + + + + + The list of directories used for loading referenced assemblies and other dependent resources. + + + + + Sets whether to ignore annotations when determining the result code. + + + + + Additional Gallio plugin directories to search recursively. + + + + + Sets the name of the directory where the reports will be put. + + + + + Specifies option property key/value pairs for the report formatter. + + + + + Sets the format string to use to generate the reports filenames. + + + + + A list of the types of reports to generate, separated by semicolons. + + + + + Sets the name of a NAnt property in which the exit code of the tests execution + should be stored. + + + + + Specifies the type, assembly, and parameters of custom test runner + extensions to use during the test run. + + + + + Specifies option property key/value pairs for the test runner. + + + + + Sets the type of test runner to use. + + + + + Sets the maximum amount of time (in seconds) the tests can run + before they are canceled. + + + + + Gets or sets the version of the .Net runtime to use for running tests. + + + + + Enables shadow copying when set to true. + + + + + Sets whether to show generated reports in a window using the default system application + registered to the report file type. + + + + + Sets the prefix that will be used for the statistics result properties. + + + + + Controls the level of information logged. + + + + + Gets or sets the relative or absolute path of the working directory + or null to use a default value selected by the consumer. + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.Readme.txt b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.Readme.txt new file mode 100644 index 00000000..728c9b6f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.Readme.txt @@ -0,0 +1,24 @@ +Gallio.Navigator +================ + +The Gallio Navigator component enables external applications to navigate to source code +by clicking on links that are interpreted by a Pluggable Protocol Handler or by loading +an ActiveX / COM object marked safe for scripting. + +These services are intended to present a minimum security risk and specifically do not +disclose user information to the calling application. + +(In the future this mechanism may be used to provide additional Gallio services.) + +NavigateTo Service: + + Link Format: gallio:navigateTo?path=&line=&column= + + ActiveX: Gallio.Navigator.GallioNavigator class + bool NavigateTo(string path, int lineNumber, int columnNumber) + + Parameters: + + - The path of the source file. + - The 1-based line number, or 0 if unspecified. + - The 1-based column number, or 0 if unspecified. diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.exe new file mode 100644 index 00000000..44903d24 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.exe.config new file mode 100644 index 00000000..7b791efb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.exe.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.plugin new file mode 100644 index 00000000..c0dcf199 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Navigator.plugin @@ -0,0 +1,22 @@ + + + + Gallio Navigator + 3.1.0.0 + . + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.dll b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.dll new file mode 100644 index 00000000..b0c8934f Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.dll-Help.xml b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.dll-Help.xml new file mode 100644 index 00000000..49ab72c6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.dll-Help.xml @@ -0,0 +1,388 @@ + + + + + + + + Run-Gallio + + + Runs tests using Gallio. + + + Copyright © 2005-2009 Gallio Project - http://www.gallio.org/ + + Run + Gallio + + + + The Run-Gallio cmdlet runs tests using Gallio. + + + + + + + + + ApplicationBaseDirectory + + The relative or absolute path of the application base directory to use during test execution instead of the default. + + String.Empty + + + Run-Gallio + + Files + + The list of comma-separated, relative or absolute paths of test files, projects and assemblies to execute. Wildcards may be used. + + + + + DoNotRun + + Sets whether to load the tests but not run them. This option may be used to produce a report that contains test metadata for consumption by other tools. + + false + + + + Filter + + + Sets the filter set to apply, which consists of a sequence of one or more inclusion + or exclusion filter rules prefixed using 'include' (optional) or 'exclude'. + A filter rule consists of zero or more filter expressions + that may be combined using 'and', 'or', and 'not' and grouped with + parentheses. A filter expression consists of a filter key followed by one or + more comma-delimited matching values in the form 'key: value, "quoted value", + /regular expression/'. + + + * + + + + HintDirectories + + The list of directories used for loading referenced assemblies and other dependent resources. + + + + + NoEchoResults + + Sets whether to echo results to the screen as tests finish. If this option is specified only the final summary statistics are displayed. Otherwise test results are echoed to the console in varying detail depending on the current verbosity level. + + false + + + + NoProgress + + Sets whether progress information is shown during the execution. If this option is specified, the execution is silent and no progress information is displayed. + + false + + + + PluginDirectories + + Additional Gallio plugin directories to search recursively. + + + + + ReportDirectory + + Sets the name of the directory where the reports will be put. + + "Reports" + + + + ReportNameFormat + + Sets the format string to use to generate the reports filenames. + + test-report-{0}-{1} + + + + ReportTypes + + A list of the types of reports to generate, separated by semicolons. + + String.Empty + + + + RunnerType + + Sets the type of test runner to use (LocalAppDomain, IsolatedAppDomain or IsolatedProcess, but more could be available as plugins). + + IsolatedProcess + + + + ShadowCopy + + + Enables shadow copying when set to true. Shadow copying allows the original assemblies to be modified while the tests are running. However, shadow copying may occasionally cause some tests to fail if they depend on their original location. + + + false + + + + DebugTests + + + Attaches the debugger to the test process. + + + false + + + + ShowReports + + Sets whether to open the generated reports once execution has finished. + + false + + + + WorkingDirectory + + + The relative or absolute path of the working directory to use during test execution instead of the default. + + + String.Empty + + + + RuntimeVersion + + The version of the .Net runtime to use for running tests. For the CLR, this must be the name of one of the framework directories in %SystemRoot%\Microsoft.Net\Framework. eg. 'v2.0.50727'. The default is null which uses the most recent installed and supported framework. + + + + + + + + + + + ApplicationBaseDirectory + + The relative or absolute path of the application base directory. + + String.Empty + + + Run-Gallio + + Files + + The list of comma-separated, relative or absolute paths of test files, projects and assemblies to execute. Wildcards may be used. + + + + + DoNotRun + + Sets whether to load the tests but not run them. This option may be used to produce a report that contains test metadata for consumption by other tools. + + false + + + + Filter + + + Sets the filter set to apply, which consists of a sequence of one or more inclusion + or exclusion filter rules prefixed using 'include' (optional) or 'exclude'. + A filter rule consists of zero or more filter expressions + that may be combined using 'and', 'or', and 'not' and grouped with + parentheses. A filter expression consists of a filter key followed by one or + more comma-delimited matching values in the form 'key: value, "quoted value", + /regular expression/'. + + + * + + + + HintDirectories + + The list of directories used for loading referenced assemblies and other dependent resources. + + + + + NoEchoResults + + Sets whether to echo results to the screen as tests finish. If this option is specified only the final summary statistics are displayed. Otherwise test results are echoed to the console in varying detail depending on the current verbosity level. + + false + + + + NoProgress + + Sets whether progress information is shown during the execution. If this option is specified, the execution is silent and no progress information is displayed. + + false + + + + PluginDirectories + + Additional Gallio plugin directories to search recursively. + + + + + ReportDirectory + + Sets the name of the directory where the reports will be put. + + "Reports" + + + + ReportNameFormat + + Sets the format string to use to generate the reports filenames. + + test-report-{0}-{1} + + + + ReportTypes + + A list of the types of reports to generate, separated by semicolons. + + String.Empty + + + + RunnerType + + Sets the type of test runner to use: Local, IsolatedAppDomain, IsolatedProcess, or others that may be provided by plugins. + + IsolatedProcess + + + + RunnerExtensions + + Specifies the type, assembly, and parameters of custom test runner extensions to use during the test run in the form: '[Namespace.]Type,Assembly[;Parameters]. eg. 'FancyLogger,MyExtensions.dll;ColorOutput,FancyIndenting' + + + + + ShadowCopy + + + Enables shadow copying when set to true. Shadow copying allows the original assemblies to be modified while the tests are running. However, shadow copying may occasionally cause some tests to fail if they depend on their original location. + + + false + + + + DebugTests + + + Attaches the debugger to the test process. + + + false + + + + ShowReports + + Sets whether to open the generated reports once execution has finished. + + false + + + + WorkingDirectory + + + The relative or absolute path of the working directory. If relative, the path is based on the current working directory, so a value of "" (an empty string) causes the current working directory to be used. + + + String.Empty + + + + RuntimeVersion + + The version of the .Net runtime to use for running tests. For the CLR, this must be the name of one of the framework directories in %SystemRoot%\Microsoft.Net\Framework. eg. 'v2.0.50727'. The default is null which uses the most recent installed and supported framework. + + + + + + + # Makes the Gallio commands available + Add-PSSnapIn Gallio + # Runs TestAssembly1.dll + Run-Gallio "[Path-to-assembly1]\TestAssembly1.dll","[Path-to-assembly2]\TestAssembly2.dll","[Path-to-test-script1]/TestScript1_spec.rb","[Path-to-test-script2]/TestScript2.xml" -f Category:UnitTests -rd C:\build\reports -rf html + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.plugin new file mode 100644 index 00000000..1c1a9adf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.plugin @@ -0,0 +1,21 @@ + + + + Gallio PowerShell Commands + 3.1.0.0 + Provides PowerShell cmdlets for running tests with Gallio. + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.xml b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.xml new file mode 100644 index 00000000..ddac2257 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.PowerShellCommands.xml @@ -0,0 +1,182 @@ + + + + Gallio.PowerShellCommands + + + + + A PowerShell Cmdlet for running Gallio. + + + + Initializes a new instance of the class + + + + + Gets or sets the relative or absolute path of the application base directory, + or null to use a default value selected by the consumer. + + + If relative, the path is based on the current working directory, + so a value of "" causes the current working directory to be used. + + + The default is null. + + + + + + + Attaches the debugger to the test process when set to true. + + + The default is false. + + + + + + Sets whether to load the tests but not run them. This option may be used to produce a + report that contains test metadata for consumption by other tools. + + + + + The list of relative or absolute paths of test files, projects and assemblies to execute. + Wildcards may be used. This is required. + + + + + + Sets the filter set to apply, which consists of a sequence of one or more inclusion + or exclusion filter rules prefixed using 'include' (optional) or 'exclude'. + + + + + + The list of directories used for loading referenced assemblies and other dependent resources. + + + + + + Sets whether to ignore annotations when determining the result code. + If false (default), then error annotations, usually indicative of broken tests, will cause + a failure result to be generated. + + + + + + Sets whether to echo results to the screen as tests finish. If this option is specified + only the final summary statistics are displayed. Otherwise test results are echoed to the + console in varying detail depending on the current verbosity level. + + + + + Additional Gallio plugin directories to search recursively. + + + + + Sets the name of the directory where the reports will be put. + + + + + Specifies option property key/value pairs for the report formatter. + + + + + Sets the format string to use to generate the reports filenames. + + + + + A list of the types of reports to generate, separated by semicolons. + + + + + + Specifies the type, assembly, and parameters of custom test runner + extensions to use during the test run in the form: + '[Namespace.]Type,Assembly[;Parameters]'. + + + eg. 'FancyLogger,MyCustomExtensions.dll;SomeParameters' + + + + + + Specifies option property key/value pairs for the test runner. + + + + + Sets the type of test runner to use. + + + + + Sets the maximum amount of time (in seconds) the tests can run + before they are canceled. The default is an infinite time to run. + + + + + + Gets or sets the version of the .Net runtime to use for running tests. + + + For the CLR, this must be the name of one of the framework directories in %SystemRoot%\Microsoft.Net\Framework. eg. 'v2.0.50727'. + + + The default is null which uses the most recent installed and supported framework. + + + + + + + Enables shadow copying when set to true. + + + Shadow copying allows the original assemblies to be modified while the tests are running. + However, shadow copying may occasionally cause some tests to fail if they depend on their original location. + + + The default is false. + + + + + + Sets whether to open the generated reports once execution has finished. + + + + + + Gets or sets the relative or absolute path of the working directory + or null to use a default value selected by the consumer. + + + If relative, the path is based on the current working directory, + so a value of "" causes the current working directory to be used. + + + The default is null. + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Reports.dll b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.dll new file mode 100644 index 00000000..676f1df3 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Reports.pdb b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.pdb new file mode 100644 index 00000000..d0d99e8e Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Reports.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.plugin new file mode 100644 index 00000000..0d8b2703 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.plugin @@ -0,0 +1,242 @@ + + + + Gallio Reports Library + 3.1.0.0 + Provides several common report formats including Xml, Html, XHtml, MHtml and Text. + plugin://Gallio/Resources/Gallio.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Link + + + Xml + + Generates XML reports with linked attachment files. + + Supported report formatter properties: + - AttachmentContentDisposition: Specifies how attachments should be stored. "Absent", "Link" or "Inline". Default is "Link". + + + + + + + Inline + + + Xml-Inline + Generates XML reports with inline encoded attachments. + + + + + + txt + text/plain + Absent + plugin://Gallio.Reports/Resources/ + xsl/Gallio-Report.txt.xsl + + + + Text + Generates plain text reports. + + + + + + txt + text/plain + Absent + plugin://Gallio.Reports/Resources/ + xsl/Gallio-Report.txt-condensed.xsl + + + + Text-Condensed + Generates plain text reports without passing tests. + + + + + + html + text/html + Link + plugin://Gallio.Reports/Resources/ + xsl/Gallio-Report.html.xsl + css;js;img + + + Html + + Generates HTML reports. + + Supported report formatter properties: + - AttachmentContentDisposition: Specifies how attachments should be stored. "Absent", "Link" or "Inline". Default is "Link". + + + + + + + html + text/html + Link + plugin://Gallio.Reports/Resources/ + xsl/Gallio-Report.html-condensed.xsl + css;js;img + + + Html-Condensed + + Generates HTML reports that omit passing tests. + + Supported report formatter properties: + - AttachmentContentDisposition: Specifies how attachments should be stored. "Absent", "Link" or "Inline". Default is "Link". + + + + + + + xhtml + text/xhtml+xml + Link + plugin://Gallio.Reports/Resources/ + xsl/Gallio-Report.xhtml.xsl + css;js;img + + + XHtml + + Generates XHTML reports. + + Supported report formatter properties: + - AttachmentContentDisposition: Specifies how attachments should be stored. "Absent", "Link" or "Inline". Default is "Link". + + + + + + + xhtml + text/xhtml+xml + Link + plugin://Gallio.Reports/Resources/ + xsl/Gallio-Report.xhtml-condensed.xsl + css;js;img + + + XHtml-Condensed + + Generates XHTML reports that omit passing tests. + + Supported report formatter properties: + - AttachmentContentDisposition: Specifies how attachments should be stored. "Absent", "Link" or "Inline". Default is "Link". + + + + + + + ${ReportFormatter.Html} + + + MHtml + Generates MHTML reports. + + + + + + ${ReportFormatter.Html-Condensed} + + + MHtml-Condensed + Generates MHTML reports that omit passing tests. + + + + + + plugin://Gallio.Reports/Resources/img/testkinds/ + plugin://Gallio.Reports/Resources/css/Gallio-Report.Generated.css + + + true + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Reports.xml b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.xml new file mode 100644 index 00000000..1c76850f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Reports.xml @@ -0,0 +1,176 @@ + + + + Gallio.Reports + + + + + Abstract base class for report formatters. + + + + + Creates a report formatter. + + + + + Gets the name of the option that how attachments are saved. + + + + + Gets or sets the default attachment content disposition. + Defaults to . + + + + + Formats the report indicated by the report writer. + + The report writer. + The report formatter options. + The progress monitor. + Thrown if , + or is null. + + + + Gets the attachment content disposition. + + The formatter options. + The attachment content disposition. + + + + + Formats MIME HTML archive reports similar to the web archives generated by Internet Explorer. + The report can then be sent to recipients as a single file. + + + Unfortunately the format is non-standard and cannot be read by most other browsers. + + + + + + Creates a report formatter. + + The HTML report formatter. + Thrown if is null. + + + + Formats the report indicated by the report writer. + + The report writer. + The report formatter options. + The progress monitor. + Thrown if , + or is null. + + + + Installs derived resources for reports such as test framework icons. + + + + + Initializes the installer. + + The test kind manager, not null. + The test kind image directory, not null. + The generated CSS file, not null. + + + + Installs components. + + The progress monitor, not null. + + + + Formats reports as Xml. + + + + + Creates an Xml report formatter. + + + + + Formats the report indicated by the report writer. + + The report writer. + The report formatter options. + The progress monitor. + Thrown if , + or is null. + + + + + Generic XSLT report formatter. + + + Recognizes the following options: + OptionDescriptionAttachmentContentDispositionOverrides the default attachment content disposition for the format. + The content disposition may be "Absent" to exclude attachments, "Link" to + include attachments by reference to external files, or "Inline" to include attachments as + inline content within the formatted document. Different formats use different + default content dispositions. + + + + + Creates an XSLT report formatter. + + The preferred extension without a '.' + The content type of the main report document. + The resource directory. + The path of the XSLT relative to the resource directory. + The paths of the resources (such as images or CSS) to copy + to the report directory relative to the resource directory. + Thrown if any arguments are null. + + + + Applies the transform to produce a report. + + + + + Copies additional resources to the content path within the report. + + + + + Formats the report indicated by the report writer. + + The report writer. + The report formatter options. + The progress monitor. + Thrown if , + or is null. + + + + Loads the XSL transform. + + The full path of the XSLT. + The transform. + + + + Populates the arguments for the XSL template processing. + + + + + Gets the XSL transform. + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.UI.dll b/lib/Gallio_3.1.397.0/bin/Gallio.UI.dll new file mode 100644 index 00000000..b4cec5d5 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.UI.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.UI.pdb b/lib/Gallio_3.1.397.0/bin/Gallio.UI.pdb new file mode 100644 index 00000000..6656c0ed Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.UI.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.UI.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.UI.plugin new file mode 100644 index 00000000..ff3ab7eb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.UI.plugin @@ -0,0 +1,101 @@ + + + + Gallio UI Library + 3.1.0.0 + Gallio UI components. + plugin://Gallio/Resources/Gallio.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Preferences + 0 + + + + + + Plugins + 100 + + + + + + Gallio + -100 + plugin://Gallio/Resources/Gallio.ico + + + + + + Gallio/Runtime + plugin://Gallio/Resources/Gallio.ico + Machine + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.UI.xml b/lib/Gallio_3.1.397.0/bin/Gallio.UI.xml new file mode 100644 index 00000000..716cc10b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.UI.xml @@ -0,0 +1,643 @@ + + + + Gallio.UI + + + + + Wrapper for static UnhandledExceptionPolicy class (to improve testability). + + + + + Reports an unhandled exception. + + A message to explain how the exception was intercepted. + The unhandled exception. + Thrown if or + is null. + + + + Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy. + + + + Initializes a new instance of the class + + + + Reports an unhandled exception. + + A message to explain how the exception was intercepted. + The unhandled exception. + Thrown if or + is null. + + + + Default implementation of ISynchronizationContext. + + + + Initializes a new instance of the class + + + + Returns a shared SynchronizationContext instance. + + + + + Wrapper for Send on the shared sync context. + + + + + + + + + Presents the control panel dialog. + + + + + Creates a control panel presenter. + + The preference page provider handles, not null. + The elevation manager, not null. + + + + Shows the control panel dialog. + + The dialog owner control. + The dialog result, either + or depending on how the dialog + was closed. + + + + Base class for components that present control panel tabs. + + + + + Creates a control panel tab. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Describes the traits of a . + + + + + Creates a traits object for a control panel tab provider. + + The control panel tab name. + Thrown if is null. + Thrown if is empty. + + + + Gets the control panel tab name. + + + + + Gets or sets an integer index used to sort control panel tabs in ascending order. + + + + + Presents the control panel dialog. + + + + + Shows the control panel dialog. + + The dialog owner control. + The dialog result, either + or depending on how the dialog + was closed. + + + + Provides a preference pane to be incorporated into the Gallio control panel. + + + + + Creates a control panel tab to include in the control panel. + + The control panel tab. + + + + Base class for user controls for editing settings with deferred application. + + + + Initializes a new instance of the class + + + + Applies pending settings changes. + + An elevation context when + is true, otherwise null. + The progress monitor, not null. + + + + Raises the event. + + The event arguments. + + + + Raises the event. + + The event arguments. + + + + Gets or sets whether there are pending settings changes yet to be applied. + + + + + Event raised when the value of changes. + + + + + Gets or sets whether elevation will be required to apply pending modifications. + + + + + Event raised when the value of changes. + + + + + A control panel tab for managing installed plugins. + + + + + Creates a control panel tab for managing installed plugins. + + The plugin registry, not null. + + + + Creates a control panel tab to include in the control panel. + + The control panel tab. + + + + Provides a preference pane to be incorporated into the Gallio control panel. + + + + + Creates a preference pane to include in the control panel. + + The preference pane. + + + + A preference pane provider that is used as an empty placeholder for a + non-leaf node in the preference pane tree. + + + + Initializes a new instance of the class + + + + Creates a preference pane to include in the control panel. + + The preference pane. + + + + Provides the preferences control panel tab. + + + + + Creates a control panel tab provider for preference panes. + + The preference page provider handles, not null. + + + + Creates a control panel tab to include in the control panel. + + The control panel tab. + + + + Base class for components that present preference panels. + + + + + Creates a preference pane. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Describes the traits of a . + + + + + Creates a traits object for a preference pane provider. + + The preference pane path consisting of slash-delimited name segments + specifying tree nodes. + Thrown if is null. + Thrown if is empty. + + + + Gets or sets an icon (16x16) for the preference pane, or null if none. + + + + + Gets or sets an integer index used to sort control panel tabs in ascending order. + + + + + Gets the preference pane path consisting of slash-delimited name segments + specifying tree nodes. + + + + + Gets or sets a value that describes the scope of the changes effected by a preference pane. + + + + + Specifies the scope of the changes effected by a preference pane. + + + + + Changes affect the current user only. + + + + + Changes affect all users of the machine. + + + + + Applies changes made by the . + + + + Initializes a new instance of the class + + + + Executes the command. + + The command arguments. + The progress monitor, non-null. + The command result, must be null or serializable. + + + + Provides the preference pane for the Gallio runtime paths. + + + + Initializes a new instance of the class + + + + Creates a preference pane to include in the control panel. + + The preference pane. + + + + An extension of the Button class that displays the "Shield" icon when + privilege elevation is required. + + + + + Creates a shield button. + + + + + Raises the event. + + The event arguments. + + + + Gets or sets whether the shield icon should be displayed. + + + + + An event raised when the value of has changed. + + + + + Presents an error dialog consisting of a title, a message and a detailed message. + + + + + Creates the dialog. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Gets or sets the error details. + + Thrown if is null. + + + + Gets or sets whether the error details panel is visible. + + + + + Gets or sets the error message. + + Thrown if is null. + + + + Gets or sets the error title. + + Thrown if is null. + + + + Shows the error dialog. + + The owner window, or null if none. + The error title. + The error message. + The error details. + Thrown if , + or is null. + + + + Installs an unhandled exception handler that displays an error dialog. + + + + + Installs the handler. + + The owner window. + Thrown if is null. + Thrown if there is already a handler installed for a different owner. + + + + Runs an application + + The main form. + + + + Uninstalls the handler. + + + + + Command pattern. + + + + + Run a task (with progress information). + + The progress monitor. + + + + A task manager for UI applications. + + + + + Run a task as a background action (uses ThreadPool). + No progress information will be displayed. + + The action to perform. + + + + Empty the queue of tasks. + + + + + The underlying progress monitor for the running task. + + + + + Event fired when a progress update is received from a running task. + + + + + Add a task to the queue. If nothing is in the queue or + running, then the task will be executed. + + The command to queue. + + + + Event fired if a task is canceled. + + + + + Event fired when a task completes. + + + + + Returns true if a task is currently underway. + + + + + Event fired when a task starts. + + + + + Progress dialog. + + + + + Default constructor. + + The progress monitor to display information for. + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + + Raises the event. + + + An that contains the event data. + + + + + Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy. + + + + + Default constructor. + + An unhandled exception policy. + + + + Run a task as a background action (uses ThreadPool). + No progress information will be displayed. + + The action to perform. + + + + Empty the queue of tasks. + + + + + The underlying progress monitor for the running task. + + + + + Event fired when a progress update is received from a running task. + + + + + Add a task to the queue. If nothing is in the queue or + running, then the task will be executed. + + The command to queue. + + + + Event fired if a task is canceled. + + + + + Event fired when a task completes. + + + + + Returns true if a task is currently underway. + + + + + Event fired when a task starts. + + + + + + Displays a summary of a set of test step runs. + + + This control is optimized to display individual test run results to the user on + demand more quickly than could be done if we had to show the whole report at once. + + + + + + Creates a test step run viewer. + + + + + Clears the contents of the report viewer and discards all cached content. + + + + + Clean up any resources being used. + + true if managed resources should be disposed; otherwise, false. + + + + Displays information about a set of test step run. + + The test step runs. + + + + Displays information about a set of test step runs, using additional + information from the test model when available. + + The test step runs. + The test model data, or null if not available. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Utility.exe b/lib/Gallio_3.1.397.0/bin/Gallio.Utility.exe new file mode 100644 index 00000000..f02622c7 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.Utility.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Utility.exe.config b/lib/Gallio_3.1.397.0/bin/Gallio.Utility.exe.config new file mode 100644 index 00000000..989b7b06 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Utility.exe.config @@ -0,0 +1,24 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.Utility.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.Utility.plugin new file mode 100644 index 00000000..07fb8b24 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.Utility.plugin @@ -0,0 +1,18 @@ + + + + Gallio Utility + 3.1.0.0 + A command-line utility for performing maintenance tasks related to the Gallio installation. + plugin://Gallio.Utility/Resources/Gallio.Utility.ico + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.dll b/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.dll new file mode 100644 index 00000000..41534fe1 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.pdb b/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.pdb new file mode 100644 index 00000000..7c4f2eed Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.plugin new file mode 100644 index 00000000..86d3b3f9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.VisualStudio.Interop.plugin @@ -0,0 +1,29 @@ + + + + Visual Studio Interoperability Plugin + 3.1.0.0 + Provides support for opening files in Visual Studio and launching the debugger. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.XmlSerializers.dll b/lib/Gallio_3.1.397.0/bin/Gallio.XmlSerializers.dll new file mode 100644 index 00000000..9c821dad Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.XmlSerializers.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.dll b/lib/Gallio_3.1.397.0/bin/Gallio.dll new file mode 100644 index 00000000..e2ec676a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.pdb b/lib/Gallio_3.1.397.0/bin/Gallio.pdb new file mode 100644 index 00000000..3cc2075a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.plugin b/lib/Gallio_3.1.397.0/bin/Gallio.plugin new file mode 100644 index 00000000..c5db0b71 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.plugin @@ -0,0 +1,618 @@ + + + + Gallio + 3.1.0.0 + The heart of Gallio. + plugin://Gallio/Resources/Gallio.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fallback + plugin://Gallio/Resources/Gallio.ico + + + + + + ${Gallio.FallbackTestFramework} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${Gallio.LocalTestIsolationProvider} + + + Local + Runs tests locally within the same process and AppDomain as the test runner application. Each test isolation context runs locally. This mode offers no isolation between tests and the test runner; it does not support loading test assembly configuration files or using a different runtime version or processor architecture. + + + + + + ${Gallio.IsolatedAppDomainTestIsolationProvider} + + + IsolatedAppDomain + Runs tests within an isolated AppDomain of the same process as the test runner application. Each test isolation context runs in its own AppDomain. This mode provides lightweight but limited isolation between tests and the test runner; it does not support using different runtime version or processor architecture. + + + + + + ${Gallio.IsolatedProcessTestIsolationProvider} + + + IsolatedProcess + Runs tests within an isolated process external to the test runner. Each test isolation context runs in its own process. This mode protects the test runner application from most faults that may occur during test execution; it supports all features. + + + + + + + + ${Gallio.LocalHostFactory} + + + + + + ${Gallio.IsolatedAppDomainHostFactory} + + + + + + ${Gallio.IsolatedProcessHostFactory} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Project + A Gallio project file. + .*\.gallio + + + + + + Executable + A library or program file. + .*\.(dll|exe) + + + + + + Assembly + A .Net assembly. + Executable + + + + + + + + + + + + + + + + + + + + + ClearCurrentUserPluginCache + Clears the plugin cache of the current user. + + + + + + VerifyInstallation + Checks for runtime installation errors. + + + + + + Setup + Installs or uninstalls components. + + + + + + ResetInstallationId + Resets the installation id. The plugin list will be refreshed the next time a Gallio application is started. + + + + + + + + + + + + + + + + + + Root + The root node of the test tree. + plugin://Gallio/Resources/Assembly.ico + + + + + + Assembly + A test assembly. + plugin://Gallio/Resources/Assembly.ico + + + + + + File + A test file. + plugin://Gallio/Resources/Container.ico + + + + + + Namespace + A test namespace. + plugin://Gallio/Resources/Container.ico + + + + + + Group + A test group. + plugin://Gallio/Resources/Container.ico + + + + + + Suite + A test suite. + plugin://Gallio/Resources/Container.ico + + + + + + Fixture + A test fixture. + plugin://Gallio/Resources/Fixture.ico + + + + + + Test + A test case. + plugin://Gallio/Resources/Test.ico + + + + + + Unsupported + An unsupported test. + plugin://Gallio/Resources/Unsupported.ico + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.xml b/lib/Gallio_3.1.397.0/bin/Gallio.xml new file mode 100644 index 00000000..da6d41d0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.xml @@ -0,0 +1,37863 @@ + + + + Gallio + + + + + Represents a method that returns a value of a specified type from the instance of an object. + + The object to get the value from. + The type of the object to get the value from. + The type of the returned value. + The returned value. + + + + An action with no arguments. + + + + + An action with two arguments. + + The first argument. + The second argument. + The first argument type. + The second argument type. + + + + An action with three arguments. + + The first argument. + The second argument. + The third argument. + The first argument type. + The second argument type. + The third argument type. + + + + An action with four arguments. + + The first argument. + The second argument. + The third argument. + The fourth argument. + The first argument type. + The second argument type. + The third argument type. + The fourth argument type. + + + + An action with five arguments. + + The first argument. + The second argument. + The third argument. + The fourth argument. + The fifth argument. + The first argument type. + The second argument type. + The third argument type. + The fourth argument type. + The fifth argument type. + + + + An action chain captures a sequence of actions to be performed as + part of a complex multi-part process. + + The action argument type. + + + Initializes a new instance of the class + + + + Gets or sets a representation of the chain as a single action. + + Thrown if is null. + + + + Registers an action to perform after all other actions + currently in the chain. + + The action to register. + Thrown if is null. + + + + Registers an action to perform around all other actions + currently in the chain. The contained part of the chain + is passed in as an action to the decorator that the decorator + can choose to run (or not) as needed. + + The decorator to register. + Thrown if is null. + + + + Registers an action to perform before all other actions + currently in the chain. + + The action to register. + Thrown if is null. + + + + Clears the chain and sets it action to . + + + + + Gets a singleton action that does nothing when invoked. + + + + + An action chain captures a sequence of actions to be performed as + part of a complex multi-part process. + + The first argument type. + The second argument type. + + + Initializes a new instance of the class + + + + Gets or sets a representation of the chain as a single action. + + Thrown if is null. + + + + Registers an action to perform after all other actions + currently in the chain. + + The action to register. + Thrown if is null. + + + + Registers an action to perform around all other actions + currently in the chain. The contained part of the chain + is passed in as an action to the decorator that the decorator + can choose to run (or not) as needed. + + The decorator to register. + Thrown if is null. + + + + Registers an action to perform before all other actions + currently in the chain. + + The action to register. + Thrown if is null. + + + + Clears the chain and sets it action to . + + + + + Gets a singleton action that does nothing when invoked. + + + + + Represents a delegate that decorates an action. + + The object to act upon. + The action to decorate which should be called in + the middle of applying the decoration. + The type of object the action is performed upon. + + + + Represents a delegate that decorates an action. + + The first argument. + The second argument. + The action to decorate which should be called in + the middle of applying the decoration. + The first argument type. + The second argument type. + + + + A condition is a simple light-weight mechanism for evaluating conditional + expressions in a given context. + + + + + Returns true if the condition is satisfied in the given context. + + The condition evaluation context. + True if the condition is satisfied. + Thrown if is null. + + + + Parses a condition from an expression. + + The expression to parse. + The expression. + Thrown if is null. + Thrown if cannot be parsed. + + + + Returns the conditional expression as a string. + + The expression string. + + + + A condition context provides information used to evaluate whether a condition holds true. + + + + Initializes a new instance of the class + + + + Returns true if the context contains a value for a given property. + + The property namespace. + The property identifier. + True if the context has the specified property. + Thrown if + or is null. + + + + Returns true if the context contains a value for a given property. + + The property namespace, not null. + The property identifier, not null. + True if the context has the specified property. + + + + Represents the method that determines whether two objects of the same type are equal. + + The first object to compare. + The second object to compare. + The type of the objects to compare. + True if the object are equal; otherwise false. + + + + A function with zero arguments. + + The result type. + The function result. + + + + A function with one argument. + + The first argument. + The first argument type. + The result type. + The function result. + + + + A function with two arguments. + + The first argument. + The second argument. + The first argument type. + The second argument type. + The result type. + The function result. + + + + A function with three arguments. + + The first argument. + The second argument. + The third argument. + The first argument type. + The second argument type. + The third argument type. + The result type. + The function result. + + + + A function with four arguments. + + The first argument. + The second argument. + The third argument. + The fourth argument. + The first argument type. + The second argument type. + The third argument type. + The fourth argument type. + The result type. + The function result. + + + + A function chain captures a sequence of actions to be performed as + part of a complex multi-part process. + + The function argument type. + The function result type. + + + + Creates a function chain. + + The initial function. + Thrown if is null. + + + + Registers a function decorator to perform around all other actions + currently in the chain. The contained part of the chain + is passed in as a function to the decorator that the decorator + can choose to run (or not) as needed. + + The decorator to register. + Thrown if is null. + + + + Gets or sets a representation of the chain as a single function. + + Thrown if is null. + + + + Represents a delegate that decorates a function. + + The object to act upon. + The function to decorate which should be called in + the middle of applying the decoration. + The type of object the function is performed upon. + The type of the function result. + + + + A 64 bit hash code value type. + + + + + Gets a hash code containing the specified 64bit value. + + The 64bit value. + + + + Produces a new hash code by combining information from the specified string + with this hash code. + + The string, may be null if none. + The augmented hash code. + + + + Creates a proabilistically unique 64bit hash code. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Provides a typed clone operation. + + The type produced when the object is cloned. + + + + Clones the object. + + The cloned object. + + + + A structure that memoizes the result of some computation for later reuse. + Maintains an internal dictionary to memoize results by key. + + The key type. + The value type. + + + + Gets the memoized value for the given key if available, otherwise populates it + using the specified populator function and stores it in association with its keys + for later reuse. + + The key by which to look up a memoized result. + The populator for the value associated with the key. + The value returned by the populator, possibly memoized. + + + + A structure that memoizes the result of some computation for later reuse. + + The value type. + + + + Gets the memoized value if available, otherwise populates it + using the specified populator function and stores it for later reuse. + + The populator. + The value returned by the populator, possibly memoized. + + + + An immutable record that holds two values. + + The type of the first value. + The type of the second value. + + + + Creates a pair. + + The first value. + The second value. + + + + Gets the first value. + + + + + Gets the second value. + + + + + Defines constants used throughout the Gallio schema. + + + + + The XML namespace for all schema types. + + + + + An immutable record that holds three values. + + The type of the first value. + The type of the second value. + The type of the third value. + + + + Creates a triple. + + The first value. + The second value. + The third value. + + + + Gets the first value. + + + + + Gets the second value. + + + + + Gets the third value. + + + + + A value type that represents the result of evaluating an + expression of type . + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Gets the singular value of the type. + + + + + The type of exception thrown when an error occurs while manipulating the disk cache. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + A disk cache manages temporary files and directories stored on disk and + arranged into groups associated with arbitrary string keys. + + + + + Gets the collection of disk cache groups. + + + + + Deletes all items in the cache. + + Thrown if an error occurs. + + + + A disk cache group represents an indexed partition of the disk cache. + + + + + Gets the disk cache that contains the group. + + + + + Creates the group if it does not exist. + + Thrown if an error occurs. + + + + Creates a directory within the group. + + The relative path of the directory to create within the group. + Directory information for the directory that was created. + Thrown if is null. + Thrown if an error occurs. + + + + Deletes the group and all of its contents if any. + + Thrown if an error occurs. + + + + Returns true if the group exists on disk. + + Thrown if an error occurs. + + + + Gets information about a file within the group. + + The relative path of the file within the group. + The file info. + Thrown if is null. + Thrown if an error occurs. + + + + Gets information about a directory within the group. + + The relative path of the directory within the group. + The directory info. + Thrown if is null. + Thrown if an error occurs. + + + + Gets the key of the group. + + + + + Gets the that represents the physical + storage location of the disk cache group in the filesystem. + + + + + Opens a file within the group. + + The relative path of the file to open within the group. + The file open mode. + The file access mode. + The file sharing mode. + The file stream. + Thrown if is null. + Thrown if an error occurs. + + + + Represents a collection of groups in a disk cache indexed by an aritrary key string. + + + + + Gets the group with the specified key. + + The key. + The group. + Thrown if is null. + + + + A simple disk cache that stores its contents in a particular directory using hashes + of the key values to ensure uniqueness. + + + + + Creates a simple disk cache. + + The path of the cache directory. + Thrown if is null. + + + + Gets the path of the cache directory. + + + + + Gets the group with the given key. + + The key, nor null. + The cache group. + + + + Gets the collection of disk cache groups. + + + + + Deletes all items in the cache. + + Thrown if an error occurs. + + + + Represents a disk cache group. + + + + + Creates a group. + + The cache. + The cache group key. + The location of the cache group. + Thrown if , + or is null. + + + + Gets the disk cache that contains the group. + + + + + Creates the group if it does not exist. + + Thrown if an error occurs. + + + + Creates a directory within the group. + + The relative path of the directory to create within the group. + Directory information for the directory that was created. + Thrown if is null. + Thrown if an error occurs. + + + + Deletes the group and all of its contents if any. + + Thrown if an error occurs. + + + + Returns true if the group exists on disk. + + Thrown if an error occurs. + + + + Gets information about a file within the group. + + The relative path of the file within the group. + The file info. + Thrown if is null. + Thrown if an error occurs. + + + + Gets information about a directory within the group. + + The relative path of the directory within the group. + The directory info. + Thrown if is null. + Thrown if an error occurs. + + + + Gets the key of the group. + + + + + Gets the that represents the physical + storage location of the disk cache group in the filesystem. + + + + + Opens a file within the group. + + The relative path of the file to open within the group. + The file open mode. + The file access mode. + The file sharing mode. + The file stream. + Thrown if is null. + Thrown if an error occurs. + + + + A disk cache that stores its contents in the user's temporary directory. + + + + + Creates a temporary disk cache within the + subdirectory of the user's temporary directory. + + + + + Creates a temporary disk cache within the specified subdirectory of the user's temporary directory. + + The name of the cache subdirectory. + Thrown if is null. + + + + The default cache directory name. + + + + + Compares arrays for equality by element. + + + + + Creates a default array equality comparer. + + + + + Creates an array equality comparer using the specified element comparer. + + The comparer to use to compare individual elements, + or null to use . + + + + Gets a default instance of the array equality comparer. + + + + + Determines whether the specified objects are equal. + + + The first object of type to compare. + + + The second object of type to compare. + + true if the specified objects are equal; otherwise, false. + + + + + Returns a hash code for the specified object. + + + The for which a hash code is to be returned. + + + A hash code for the specified object. + + + The type of is a reference type and is null. + + + + + Utility functions for manipulating collections. + + + + + Converts all elements of the input collection and returns the collected results as an array + of the same size. + + The input collection. + The conversion function to apply to each element. + The input type. + The output type. + The output array. + + + + Returns the first element of the input enumeration for which the specified + predicate returns true. + + The input enumeration. + The predicate. + The element type. + The first matching value or the default for the type if not found. + + + + Copies all of the elements of the input collection to an array. + + The input collection. + The element type. + The output array. + + + + A covariant list converts a list of the input type to a + read-only list of the more generic output type. The wrapped + list can be used to mimic covariance in method return types. + + The input list type. + The output list type. + + + + Creates a wrapper for the specified list. + + The input list. + Thrown if is null. + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Determines the index of a specific item in the . + + + The object to locate in the . + + + The index of if found in the list; otherwise, -1. + + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + Gets an item from the list with the specified index. + + The index. + The item. + Thrown if is out of range. + + + + Provides a singleton empty array instance. + + The type of array to provide. + + + + An empty array of type . + + + + + A read-only empty dictionary. + + The dictionary key type. + The dictionary value type. + + + Initializes a new instance of the class + + + + Adds an item to the . + + + The object to add to the . + + + The is read-only. + + + + + Adds an element with the provided key and value to the . + + + The object to use as the key of the element to add. + + + The object to use as the value of the element to add. + + + is null. + + + An element with the same key already exists in the . + + + The is read-only. + + + + + Removes all items from the . + + + The is read-only. + + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Determines whether the contains an element with the specified key. + + + The key to locate in the . + + true if the contains an element with the key; otherwise, false. + + + is null. + + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + A read-only empty dictionary instance. + + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + Gets or sets the element with the specified key. + + + The key of the element to get or set. + + + The element with the specified key. + + + is null. + + + The property is retrieved and is not found. + + + The property is set and the is read-only. + + + + + Gets an containing the keys of the . + + + An containing the keys of the object that implements . + + + + + Removes the first occurrence of a specific object from the . + + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + + The is read-only. + + + + + Removes the element with the specified key from the . + + + The key of the element to remove. + + true if the element is successfully removed; otherwise, false. This method also returns false if was not found in the original . + + + is null. + + + The is read-only. + + + + + Gets the value associated with the specified key. + + + The key whose value to get. + + + When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the parameter. This parameter is passed uninitialized. + + true if the object that implements contains an element with the specified key; otherwise, false. + + + is null. + + + + + Gets an containing the values in the . + + + An containing the values in the object that implements . + + + + + Utility functions for manipulating generic collections. + + + + + Adds all elements of the input enumeration to the output collection. + + The input enumeration. + The output collection. + The element type. + + + + Adds elements of the input enumeration to the output collection, + if not already present. + + The input enumeration. + The output collection. + The element type. + + + + Converts each element of the input collection and returns the collected results as an array + of the same size. + + The input collection. + The conversion function to apply to each element. + The input type. + The output type. + The output array. + + + + Converts each element of the input collection and adds the result to the + output collection succession in the same order. + + The input list. + The output list. + The conversion function to apply to each element. + The input type. + The output type. + + + + Converts each element of the input collection and stores the result in the + output list using the same index. The output list must be at least as + large as the input list. + + The input list. + The output list. + The conversion function to apply to each element. + The input type. + The output type. + + + + Converts each element of the input collection and stores the result in place. + + The list to mutate. + The conversion function to apply to each element. + The item type. + + + + Returns true if the elements of both lists are equal. + + The first collection. + The second collection. + True if the elements are equal. + + + + Returns true if the elements of both lists are equal. + + The first collection. + The second collection. + The comparison strategy to use. + True if the elements are equal. + + + + Returns true if the elements of both lists are equal but possibly appear in a different order. + Handles elements that appear multiple times and ensures that they appear the same + number of times in each list. + + The first collection. + The second collection. + True if the elements are equal. + + + + Returns true if the input enumeration contains an element for which the predicate returns true. + + The input enumeration. + The predicate. + The element type. + True if a matching element exists. + + + + Returns the first element of the input enumeration for which the specified + predicate returns true. + + The input enumeration. + The predicate. + The element type. + The first matching value or the default for the type if not found. + + + + Performs an action for each element in an enumeration. + + The input enumeration. + The action to perform. + The element type. + + + + Returns true if both dictionaries have equal key/value pairs. + + The first collection. + The second collection. + True if the elements are equal. + + + + Copies all of the elements of the input collection to an array. + + The input collection. + The element type. + The output array. + + + + Copies all of the elements of the input enumerable to an array. + + The input enumerable. + The element type. + The output array. + + + + A hashtable-based set implementation. + + + + + Creates an empty set. + + + + + Creates an empty set using the specified comparer. + + The comparer, or null to use the default comparer. + + + + Adds an item to the . + + + The object to add to the . + + + The is read-only. + + + + + Removes all items from the . + + + The is read-only. + + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + Removes the first occurrence of a specific object from the . + + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + + The is read-only. + + + + + A multi-map allows a list of values to be associated with a single key. + + + + + Adds a value to the list of those associated with a key. + + The key. + The value to associate. + + + + Adds all of the values from the specified map. + + The map. + Thrown if is null. + + + + Adds all of the values from the specified enumeration of key-value pairs. + + The key-value pairs. + Thrown if is null. + + + + Returns true if the map contains an entry with the specified key and value. + + The key. + The value to find. + True if the map contains an entry with the specified key and value. + + + + Gets the contents of the multi-map as an enumeration of pairs of keys and lists of values. + + + + + Removes a value from the list of those associated with a key. + + The key. + The value to remove from the key. + True if the value was removed. + + + + A strongly-typed key to be used together with an associative array to help the + compiler perform better type checking of the value associated with the key. + + The type of value associated with the key. + + + + Creates a new key. + + The unique name of the key. + Thrown if is null. + + + + Gets the unique name of the key. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Lazily populates and caches values associated with a particular key. + + + + + Creates a cache with the specified populator function. + + A function that provides a value given a key. + Thrown if is null. + + + + Gets the value associated with the specified key. + Populates it on demand if not already cached. + + The key. + The associated value. + + + + A multi-map allows a list of values to be associated with a single key. + + + + + Creates an empty multi-map. + + + + + Adds all values in the pair to the specified key. + + The key and values pair. + + + + Adds all values in the pair to the specified key. + + The key. + The values. + + + + Adds a value to the list of those associated with a key. + + The key. + The value to associate. + + + + Adds all of the values from the specified map. + + The map. + Thrown if is null. + + + + Adds all of the values from the specified map. + + The map. + Thrown if is null. + + + + Removes all items from the . + + + The is read-only. + + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Returns true if the map contains an entry with the specified key and value. + + The key. + The value to find. + True if the map contains an entry with the specified key and value. + + + + Returns true if the map contains at least one value associated with + the specified key. + + The key. + True if there is at least one value associated with the key. + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of distinct keys in the map. + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + Gets or sets the list of values associated with the specified key. + Returns an empty list if there are none. + + The key. + The list of values. + + + + Gets the collection of keys in the multi-map. + + + + + Gets the contents of the multi-map as an enumeration of pairs of keys and lists of values. + + + + + Obtains a read-only view of another multi-map. + + The multi-map. + Thrown if is null. + + + + Removes all values in the pair from the specified key. + + The key and values pair. + True if at least one value was removed. + + + + Removes all values associated with the specified key. + + The key. + True if the key existed and was removed. + + + + Removes a value from the list of those associated with a key. + + The key. + The value to remove from the key. + True if the value was removed. + + + + Gets the value associated with the specified key. + + + The key whose value to get. + + + When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the parameter. This parameter is passed uninitialized. + + true if the object that implements contains an element with the specified key; otherwise, false. + + + is null. + + + + + Gets the collection of lists of values in the multi-map. + + + + + A property bag associates keys with values where each key may have one or more associated value. + All keys and values must be non-null strings. + + + + + Creates an empty property bag. + + + + + Adds an item to the . + + + The object to add to the . + + + The is read-only. + + + + + Adds an element with the provided key and value to the . + + + The object to use as the key of the element to add. + + + The object to use as the value of the element to add. + + + is null. + + + An element with the same key already exists in the . + + + The is read-only. + + + + + Adds a value to the list of those associated with a key. + + The key. + The value to associate. + + + + Adds all of the values from the specified map. + + The map. + Thrown if is null. + + + + Adds all of the values from the specified map. + + The map. + Thrown if is null. + + + + Gets a read-only view of this property set. + + A read-only view. + + + + Removes all items from the . + + + The is read-only. + + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Returns true if the map contains an entry with the specified key and value. + + The key. + The value to find. + True if the map contains an entry with the specified key and value. + + + + Determines whether the contains an element with the specified key. + + + The key to locate in the . + + true if the contains an element with the key; otherwise, false. + + + is null. + + + + + Creates a copy of this property bag. + + The copy. + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets the first value associated with a key. + + The key. + The first associated value, or null if none. + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + Gets or sets the element with the specified key. + + + The key of the element to get or set. + + + The element with the specified key. + + + is null. + + + The property is retrieved and is not found. + + + The property is set and the is read-only. + + + + + Gets an containing the keys of the . + + + An containing the keys of the object that implements . + + + + + Gets the contents of the multi-map as an enumeration of pairs of keys and lists of values. + + + + + Provides the Xml schema for this element. + + The schema set. + The schema type of the element. + + + + Removes the first occurrence of a specific object from the . + + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + + The is read-only. + + + + + Removes the element with the specified key from the . + + + The key of the element to remove. + + true if the element is successfully removed; otherwise, false. This method also returns false if was not found in the original . + + + is null. + + + The is read-only. + + + + + Removes a value from the list of those associated with a key. + + The key. + The value to remove from the key. + True if the value was removed. + + + + Sets the value associated with a key. + + The key. + The new value, or null to remove the existing values. + + + + Gets the value associated with the specified key. + + + The key whose value to get. + + + When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the parameter. This parameter is passed uninitialized. + + true if the object that implements contains an element with the specified key; otherwise, false. + + + is null. + + + + + Gets an containing the values in the . + + + An containing the values in the object that implements . + + + + + A property set associates keys with values where each key may have exactly one associated value. + All keys and values must be non-null strings. + + + + + Creates an empty property set. + + + + + Adds an item to the . + + + The object to add to the . + + + The is read-only. + + + + + Adds an element with the provided key and value to the . + + + The object to use as the key of the element to add. + + + The object to use as the value of the element to add. + + + is null. + + + An element with the same key already exists in the . + + + The is read-only. + + + + + Adds all elements of another collection to this dictionary. + + The collection to add. + Thrown if is null. + + + + Gets a read-only view of this property set. + + A read-only view. + + + + Removes all items from the . + + + The is read-only. + + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Determines whether the contains an element with the specified key. + + + The key to locate in the . + + true if the contains an element with the key; otherwise, false. + + + is null. + + + + + Creates a full copy of this property set. + + The copy. + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets the value associated with a key, or null if absent. + + The key. + The associated value, or null if none. + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + Gets or sets the element with the specified key. + + + The key of the element to get or set. + + + The element with the specified key. + + + is null. + + + The property is retrieved and is not found. + + + The property is set and the is read-only. + + + + + Gets an containing the keys of the . + + + An containing the keys of the object that implements . + + + + + Provides the Xml schema for this element. + + The schema set. + The schema type of the element. + + + + Removes the first occurrence of a specific object from the . + + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + + The is read-only. + + + + + Removes the element with the specified key from the . + + + The key of the element to remove. + + true if the element is successfully removed; otherwise, false. This method also returns false if was not found in the original . + + + is null. + + + The is read-only. + + + + + Sets the value associated with a key, removes an existing value if null. + + The key. + The new value, or null to remove the existing value. + + + + Gets the value associated with the specified key. + + + The key whose value to get. + + + When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the parameter. This parameter is passed uninitialized. + + true if the object that implements contains an element with the specified key; otherwise, false. + + + is null. + + + + + Gets an containing the values in the . + + + An containing the values in the object that implements . + + + + + A read-only dictionary wrapper. + + + + + Creates a read-only dictionary wrapper for another dictionary. + + The dictionary to wrap. + Thrown if is null. + + + + Adds an item to the . + + + The object to add to the . + + + The is read-only. + + + + + Adds an element with the provided key and value to the . + + + The object to use as the key of the element to add. + + + The object to use as the value of the element to add. + + + is null. + + + An element with the same key already exists in the . + + + The is read-only. + + + + + Removes all items from the . + + + The is read-only. + + + + + Determines whether the contains a specific value. + + + The object to locate in the . + + true if is found in the ; otherwise, false. + + + + + Determines whether the contains an element with the specified key. + + + The key to locate in the . + + true if the contains an element with the key; otherwise, false. + + + is null. + + + + + Copies the elements of the to an , starting at a particular index. + + + The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. + + + The zero-based index in at which copying begins. + + + is null. + + + is less than 0. + + + is multidimensional. + + -or- + is equal to or greater than the length of . + + -or- + + The number of elements in the source is greater than the available space from to the end of the destination . + + -or- + + Type cannot be cast automatically to the type of the destination . + + + + + Gets the number of elements contained in the . + + + The number of elements contained in the . + + + + + Returns an enumerator that iterates through the collection. + + + A that can be used to iterate through the collection. + + + + + Gets a value indicating whether the is read-only. + + true if the is read-only; otherwise, false. + + + + + + + Removes the first occurrence of a specific object from the . + + + The object to remove from the . + + true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + + + The is read-only. + + + + + Removes the element with the specified key from the . + + + The key of the element to remove. + + true if the element is successfully removed; otherwise, false. This method also returns false if was not found in the original . + + + is null. + + + The is read-only. + + + + + Gets the value associated with the specified key. + + + The key whose value to get. + + + When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the parameter. This parameter is passed uninitialized. + + true if the object that implements contains an element with the specified key; otherwise, false. + + + is null. + + + + + + An equality comparer that compares values by reference. + + The type of values to compare, must be reference types. + + + + Determines whether the specified objects are equal. + + + The first object of type to compare. + + + The second object of type to compare. + + true if the specified objects are equal; otherwise, false. + + + + + Returns a hash code for the specified object. + + + The for which a hash code is to be returned. + + + A hash code for the specified object. + + + The type of is a reference type and is null. + + + + + Gets the singleton instance of the comparer. + + + + + Provides functions for manipulating ad-hoc trees. + + + + + Gets an enumeration of a tree data structure in pre-order traversal. + + The root node of the tree. + A function that yields an enumeration of the children + of a node in the tree. + The type of node in the tree. + The pre-order traversal enumeration. + + + + Enumerates child nodes in a tree. + + The node. + The node's children. + + + + A user data collection stores arbitrary key/value pairs that may be associated + with other objects in the system. + + + + + Creates an empty collection. + + + + + Creates a copy of the collection. + + The copy. + + + + Gets a value from the collection. + + The key. + The value type. + The associated value. + Thrown if was not found. + + + + Gets a value from the collection or a default value if none found. + + The key. + The default value. + The value type. + The associated value, or the default value. + + + + Determines whether a key has an associated value in the collection. + + The key. + The value type. + True if the key has an associated value. + Thrown if is null. + + + + Removes a value from the collection. + + The key. + The value type. + + + + Sets a value in the collection. + + The key. + The value to set. + The value type. + + + + Tries to get a value from the collection. + + The key. + Set to the value, or default(T) if none present. + The value type. + True if a value was obtained. + + + + An event dispatched by the when its + is being configured to enable customization. + + + + + Creates event arguments. + + The process start info being configured. + Thrown if is null. + + + + Gets the process start info being configured. + + + + + A function that returns the maximum number of threads that a work scheduler + may use to perform work. The value may change over time and cause the + scheduler to adapt to changing degrees of parallelism. + + The degree of parallelism which must be at least 1. + + + + Wrapper for to allow testing. + + + + + Gets a value indicating whether the associated process has been terminated. + + + + + Gets the unique identifier for the associated process. + + + + + Checks whether a module with the specified file name is + loaded in the process. + + The file name. + true if the module is loaded; otherwise, false. + + + + Immediately stops the associated process. + + + + + Discards any information about the associated process + that has been cached inside the process object. + + + + + Gets or sets the properties to passed to the + method of the underlying . + + + + + Causes the object to wait indefinitely for + the associated process to enter an idle state. This overload applies + only to processes with a user interface and, therefore, a message loop. + + true if the associated process has reached an idle state. + + + + Causes the object to wait the specified number + of milliseconds for the associated process to enter an idle state. This + overload applies only to processes with a user interface and, therefore, + a message loop. + + + A value of 1 to that specifies the amount of + time, in milliseconds, to wait for the associated process to become idle. + A value of 0 specifies an immediate return, and a value of -1 specifies + an infinite wait. + + + true if the associated process has reached an idle state; otherwise, false. + + + + + Wraps the static process creation methods on to allow testing. + + + + + Starts the process and associates it with a new object. + + The process start info. + The new process. + + + + Wraps the static process query methods on to allow testing. + + + + + Creates an array of objects for all + processes on the local compuer that share the specified name. + + The friendly name of he process. + An array of objects. + + + + A lock box object provides protected read / write access to a shared object + that may be accessed concurrently by multiple threads. + + The type of object inside the lock box. + + + + Creates a lock box for the specified object. + + The object to protect. + + + + Acquires a read lock and invokes the action with the object inside the lock box. + + The action to invoke. + Thrown if is null. + + + + Acquires a read lock and invokes the function with the object inside the lock box. + + The action to invoke. + The function result type. + The value returned by the function. + Thrown if is null. + + + + Acquires a write lock and invokes the action with the object inside the lock box. + + The action to invoke. + Thrown if is null. + + + + Acquires a write lock and invokes the function with the object inside the lock box. + + The action to invoke. + The function result type. + The value returned by the function. + Thrown if is null. + + + + Default implementation of using . + + + + Initializes a new instance of the class + + + + Starts the process and associates it with a new object. + + The process start info. + The new process. + + + + Default implementation of using . + + + + Initializes a new instance of the class + + + + Creates an array of objects for all + processes on the local compuer that share the specified name. + + The friendly name of he process. + An array of objects. + + + + A process task provides support for launching external processes + and collecting their output. + + + + + Creates a process task. + + The path of the executable executable. + The arguments for the executable. + The working directory. + Thrown if , + or is null. + + + + Aborts the task. + + + + + Gets the arguments. + + + + + Gets or sets whether console error stream of the process should be captured + and made available via the property. + + + + + Gets or sets whether console output stream of the process should be captured + and made available via the property. + + + + + The event fired to configure just before the process is started. + + + + + Gets the captured contents of the console error stream written by the process. + + Thrown if the process has not been started + or if is null. + + + + The event fired when each line of new output is received on the console error stream. + + + + + Gets the captured contents of the console output stream written by the process. + + Thrown if the process has not been started + or if is null. + + + + The event fired when each line of new output is received on the console output stream. + + + + + Gets or sets whether to create a window for the command prompt. + + + + + Gets the executable path. + + + + + Gets the exit code of the process, or -1 if the process did not run or has not exited. + + + + + Gets a description of the exit code, if available, or null otherwise. + + + + + Waits for the task to terminate. + + The timeout, or null to wait indefinitely. + True if the task is not running as of the time this method exits, + false if a timeout occurred while waiting. + + + + Gets the that was started or null if the + process has not been started yet. + + + + + Sets an environment variable to be passed to the process when started. + + The variable name. + The variable value, or null to remove the environment variable + so it will not be inherited by the child process. + Thrown if the process has already been started. + Thrown if is null. + + + + Starts the task. + + + + + Starts a . + + The that has been started. + The process. + + + + Gets or sets whether to execute the command with the Windows shell. + + + + + Gets the working directory path. + + + + + Default implementation of using . + + + + + Creates a new process wrapper. + + A process. + If is null. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Releases the resources used by the . + + + + + Gets a value indicating whether the associated process has been terminated. + + + + + Gets the unique identifier for the associated process. + + + + + Checks whether a module with the specified file name is + loaded in the process. + + The file name. + true if the module is loaded; otherwise, false. + + + + Immediately stops the associated process. + + + + + Discards any information about the associated process + that has been cached inside the process object. + + + + + Gets or sets the properties to passed to the + method of the underlying . + + + + + Causes the object to wait indefinitely for + the associated process to enter an idle state. This overload applies + only to processes with a user interface and, therefore, a message loop. + + true if the associated process has reached an idle state. + + + + Causes the object to wait the specified number + of milliseconds for the associated process to enter an idle state. This + overload applies only to processes with a user interface and, therefore, + a message loop. + + + A value of 1 to that specifies the amount of + time, in milliseconds, to wait for the associated process to become idle. + A value of 0 specifies an immediate return, and a value of -1 specifies + an infinite wait. + + + true if the associated process has reached an idle state; otherwise, false. + + + + + An action that reads the contents of a protected object. It should not modify the object in any way. + + The object. + The type of object. + + + + A function that reads the contents of a protected object and produces some result. It should not modify the object in any way. + + The object. + The type of object. + The result type. + + + + Provides helpers for cross-thread synchronization. + + + + + Synchronizes an action. + + The invoker, such as a WinForms control. + The action. + The exception thrown by the action. + + + + Synchronizes a function that returns a value. + + The invoker, such as a WinForms control. + The function. + The function return type. + The value returned by the function. + The exception thrown by the function. + + + + A task represents a concurrently executing operation. + + + + + Creates a task. + + The name of the task. + Thrown if is null. + + + + Asynchronously aborts the task. + + + + + Adds or removes an event handler that is signaled when the task is aborted. + If a handler is being added and the task has already aborted, it is immediately invoked. + + + + + Aborts the task. + + + + + Returns true if the task has been aborted. + + + + + Returns true if the task has not been started or aborted yet. + + + + + Returns true if the task is running. + + + + + Returns true if the task ran and was terminated. + + + + + Waits for the task to terminate. + + The maximum amount of time to wait for completion, or null to wait indefinitely. + True if the task is not running as of the time this method exits, + false if a timeout occurred while waiting. + Thrown if + represents a negative time span. + + + + Waits for the task to terminate. + + The timeout, or null to wait indefinitely. + True if the task is not running as of the time this method exits, + false if a timeout occurred while waiting. + + + + Gets the name of the task. + + + + + Dispatches notification that the task has terminated and provides its result. + + The task result. + Thrown if is null. + Thrown if the task is not currently running. + + + + Notifies the event handlers. + + + + + Notifies the event handlers. + + + + + Notifies the event handlers. + + + + + Gets the task result, or null if the task has not terminated or was aborted before starting. + + + + + Starts the task and waits for it to complete until the timeout expires. + If the timeout expires, aborts the task and returns false. + + The maximum amount of time to wait for completion, or null to wait indefinitely. + True if the task ran to completion within the specified time span, + false if the task was aborted. + Thrown if + represents a negative time span. + + + + Starts running the task. + + + + + Adds or removes an event handler that is signaled when the task is started. + If a handler is being added and the task has already started, it is immediately invoked. + + + + + Starts the task. + + + + + Adds or removes an event handler that is signaled when the task is terminated. + If a handler is being added and the task has already terminated, it is immediately invoked. + + + + + A manages the lifecycle of any number of s + and monitors their run-time behavior. + + + + + Creates an empty task container. + + + + + Asynchronously aborts all of the tasks currently running within the container. + + + + + Gets the list of all tasks that are currently running. + + The list of running tasks. + + + + Waits for all of currently running tasks to terminate. + + The maximum amount of time to wait for completion, or null to wait indefinitely. + True if no tasks are running as of the time this method exits, + false if a timeout occurred while waiting. + Thrown if + represents a negative time span. + + + + Adds or removes an event handler that is signaled when any watched task is aborted. + + + + + Adds or removes an event handler that is signaled when any watched task is started. + + + + + Adds or removes an event handler that is signaled when any watched task is terminated. + + + + + Adds a new task for this container to watch. + + The task to monitor. + Thrown if is null. + + + + A task-related event. + + + + + Creates event arguments for a task-related event. + + The task that the event is about. + Thrown if is null. + + + + Gets the task that the event is about. + + + + + Holds the value or exception produced by a task. + + + + + Gets the exception that was thrown by the task. + + Thrown if is true. + + + + Returns true if the task ran to completion and returned a value, + or false if an exception was thrown. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the value that was returned by the task. + + Thrown if is false. + + + + Holds the value or exception produced by a task. + + + + + Creates a result object containing the exception thrown by the task. + + The exception. + The new task result. + Thrown if is null. + + + + Creates a result object containing the value returned by the task. + + The value. + The new task result. + + + + Gets the value that was returned by the task. + + Thrown if is false. + + + + A executes a block of code inside a special + scope that is designed to issue and safely handle + on demand. + + + + Initializes a new instance of the class + + + + Aborts the currently running action and prevents any further actions from running + inside of this scope. + + + + + Enters a protected context wherein it cannot receive a thread abort from this + . + + An object that when disposed ends the protected block, possibly null if there was no protection necessary. + + + + Runs an action inside of the scope. + + The action to run. + The that was caught if the action + was aborted, or null if the action completed normally. + Thrown if is null. + Thrown if an action is already running in this scope. + Any other exception thrown by itself. + + + + An implementation of based on a locally running thread. + + + + + Creates a task that will execute code within a new locally running thread. + When the task terminates successfully, its result will contain the value null. + + The name of the task. + The action to perform within the thread. + Thrown if + or is null. + + + + Creates a task that will execute code within a new locally running thread. + When the task terminates successfully, its result will contain the value + returned by . + + The name of the task. + The function to perform within the thread. + Thrown if + or is null. + + + + Aborts the task. + + + + + Performs an action within the thread after the task's main action runs. + + + + + Gets or sets the desired to use for + the thread when it is started. + + Thrown if this method is called + after the thread has started. + + + + Performs an action within the thread before the task's main action runs. + + + + + Waits for the task to terminate. + + The timeout, or null to wait indefinitely. + True if the task is not running as of the time this method exits, + false if a timeout occurred while waiting. + + + + Starts the task. + + + + + Gets the thread on which the task is running, or null if the + task is not running. + + + + + Schedules actions to be run in parallel up to a specified (variable) + maximum number of threads. + + + + + Creates a work scheduler. + + A function that determines + the current degree of parallelism which may change over time. + Thrown if + is null. + + + + Runs a set of actions in parallel up to the current degree of parallelism. + + The actions to run. + Thrown if is null + or contains null. + + + + An action that reads or writes the contents of a protected object. + + The object. + The type of object. + + + + A function that reads or writes the contents of a protected object and produces some result. + + The object. + The type of object. + The result type. + + + + Describes an exception in a serializable form. + + + + + Creates an exception data object from an exception. + + The exception. + Thrown if is null. + + + + Creates an exception data object. + + The exception type full name. + The exception message text. + The exception stack trace. + The inner exception data, or null if none. + Thrown if , + or is null. + + + + Creates an exception data object. + + The exception type full name. + The exception message text. + The exception stack trace. + The inner exception data, or null if none. + Thrown if , + or is null. + + + + Gets the inner exception data, or null if none. + + + + + Gets the exception message text. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets the exception stack trace. + + + + + Formats the exception to a string similar to the one that the .Net framework + would ordinarily construct. + + The formatted exception. + + + + Gets the exception type full name. + + + + + Writes the exception in a structured format with markers to distinguish its component elements. + + The log stream writer. + Thrown if is null. + + + + Provides helper functions for manipulating s. + + + + + Creates an object using without producing a + The type of object to create. + The constructor arguments, or null if none. + The new instance, or null if none. + Thrown if is null. + + + + Invokes a constructor without producing a + The constructor to invoke. + The constructor arguments, or null if none. + The new instance, or null if none. + Thrown if is null. + + + + Invokes a method without producing a + The method to invoke. + The instance on which to invoke the method, or null if none. + The method arguments, or null if none. + The method return value, or null if none. + Thrown if is null. + + + + Rethrows an exception without discarding its stack trace. + This enables the inner exception of + to be unwrapped. + + The exception to rethrow. + + + + Safely obtains the component of an exception. + + The message. + Thrown if is null. + + + + Safely obtains the component of an exception. + + The stack trace. + Thrown if is null. + + + + Safely converts an exception to a string. + + The exception. + The string contents. + Thrown if is null. + + + + Describes a stack trace in a serializable form. + + + + + Creates a stack trace data object that points to the specified code element. + + The code element. + Thrown if is null. + + + + Creates a stack trace data object from a string. + + The stack trace. + Thrown if is null. + + + + Returns true if the stack trace data is empty. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Formats the stack trace to a string similar to the one that the .Net framework + would ordinarily construct. + + The formatted stack trace. + + + + Writes the stack trace in a structured format with markers to distinguish its component elements. + + The log stream writer. + Thrown if is null. + + + + Provides methods for filtering the stack trace for tests. + + + + + Captures a filtered stack trace from the currently executing thread. + + The filtered stack trace. + + + + Filters the stack trace information about an exception. + + The exception data. + The filtered exception data. + Thrown if + is null. + + + + Filters the stack trace information in an exception. + + The exception. + The filtered exception data. + Thrown if + is null. + + + + Filters a stack trace. + + The stack trace. + The filtered stack trace. + Thrown if + is null. + + + + Filters a stack trace. + + The stack trace. + The filtered stack trace string. + Thrown if + is null. + + + + This attribute is used to mark methods and types that are internal to the implementation + of the system. + + + + Initializes a new instance of the class + + + + This attribute is used to mark methods that call into user code. + + + + Initializes a new instance of the class + + + + Redirects the console streams. + + + + + Redirect console output and error stream and disables the console input stream. + + The new console output writer. + The new console error writer. + Thrown if + or is null. + + + + Resets the console streams as they were initially. + + + + + Resets the console streams as they were initially. + + True if was called directly. + + + + Sets when created, then + restores it when disposed. + + + + + Saves the current directory then changes it to the specified value. + + The new directory. + Thrown if is null. + Thrown if the current directory could not be set. + + + + Resets the current directory to its original saved value. + + Thrown if the current directory could not be reset. + + + + Resets the current directory to its original saved value if disposing. + + True if was called directly. + Thrown if the current directory could not be reset. + + + + Default implementation of IFileSystem using System.IO classes. + + + + Initializes a new instance of the class + + + + Copy a directory and contents. + + The path of the directory to copy. + The destination. + + + + Copies an existing file to a new file. Overwriting a file of the same name is allowed. + + The file to copy. + The name of the destination file. + This cannot be a directory or an existing file. + true if the destination file can be overwritten; + otherwise, false. + + + + Attempts to create a directory. + + The location of the directory. + + + + Deletes the specified directory and, if indicated, + any subdirectories in the directory. + + The name of the directory to remove. + true to remove directories, subdirectories, + and files in path; otherwise, false. + + + + Attempts to delete a file. + + The location of the file. + + + + Checks if a directory exists (Directory.Exists) + + The location of the directory. + True if the directory exists, otherwise False. + + + + Checks if a given file exists (File.Exists). + + The path of the file. + True if the file exists, otherwise False. + + + + Returns a list of matching files in the specified directory. + + The directory to inspect. + The pattern to match files with. + Whether to search all directories or just + the top-level one. + A string array of filenames. + + + + Checks if a path is relative or absolute (Path.IsPathRooted). + + The path to check. + True if the path is absolute, otherwise False. + + + + Attempts to open a file using the default program. + + The location of the file. + + + + Utilities for manipulating files. + + + + + Makes an absolute path. + + The base directory for resolving relative paths, + or null to use the current directory. + The path to canonicalize, or null if none. + The absolute path, or null if none. + + + + Makes all paths in the list absolute. + + The base directory for resolving relative paths, + or null to use the current directory. + The list of paths to canonicalize in place. + + + + Recursively copies files and folders from the source path to the destination. + + The source file or directory path. + The destination file or directory path. + If true, overwrites existing files in the destination. + Thrown if or is null. + + + + Recursively copies files and folders from the source path to the destination + using an indirect mechanism to actually create a file or folder. + + The source file or directory path. + The destination file or directory path. + A delegate used to create a directory with a given destination directory path, or null to do nothing. + A delegate used to copy a source file to a given destination file path, or null to do nothing. + Thrown if or is null. + + + + + Copies the contents of a source stream to a destination stream. + + + The source stream. + The destination stream. + Thrown if + or is null. + + + + Recursively deletes a file or directory. + Does nothing if the file or directory does not exist. + + The path. + + + + Replaces invalid characters in a file or directory name with underscores + and trims it if it is too long. + + The file or directory name. + The encoded file or directory name. + Thrown if is null. + + + + Gets the full path of the containing directory. + + The path. + The full path of the parent directory or null if it is at the root. + Thrown if is null. + + + + Makes an absolute path from an relative path if possible. + + The relative path. + The base path. + The absolute path. + + + + Makes a relative path from an absolute path if possible. + + The absolute path. + The base path. + The path relative to the base path, or an absolute path if the paths are unrelated. + + + + Strips the trailing backslash off of a directory path, if present. + + The path to strip, or null if none. + The stripped path, or null if none. + + + + Wrapper for static System.IO.File operations to + allow testing. + + + + + Copy a directory and contents. + + The path of the directory to copy. + The destination. + + + + Copies an existing file to a new file. Overwriting a file of the same name is allowed. + + The file to copy. + The name of the destination file. + This cannot be a directory or an existing file. + true if the destination file can be overwritten; + otherwise, false. + + + + Attempts to create a directory. + + The location of the directory. + + + + Deletes the specified directory and, if indicated, + any subdirectories in the directory. + + The name of the directory to remove. + true to remove directories, subdirectories, + and files in path; otherwise, false. + + + + Attempts to delete a file. + + The location of the file. + + + + Checks if a directory exists (Directory.Exists) + + The location of the directory. + True if the directory exists, otherwise False. + + + + Checks if a given file exists (File.Exists). + + The path of the file. + True if the file exists, otherwise False. + + + + Returns a list of matching files in the specified directory. + + The directory to inspect. + The pattern to match files with. + Whether to search all directories or just + the top-level one. + A string array of filenames. + + + + Checks if a path is relative or absolute (Path.IsPathRooted). + + The path to check. + True if the path is absolute, otherwise False. + + + + Attempts to open a file using the default program. + + The location of the file. + + + + An attachment is an embedded object in a markup document. An attachment must specify a + content type (a MIME type), and some contents. + + + + + Gets the content type of the attachment specified as a MIME type, not null. + for definitions of common supported MIME types. + + + + + Creates an HTML attachment. + + The attachment name, or null to automatically assign one. + The html string, not null. + The attachment. + Thrown if is null. + + + + Creates an image attachment with a mime-type compatible with its internal representation. + + The attachment name, or null to automatically assign one. + The image to attach. + Thrown if is null. + + + + Creates XML attachment with mime-type by serializing an object. + + The attachment name, or null to automatically assign one. + The object to serialize and embed, must not be null. + The xml serializer to use, or null to use the default based on the object's type. + Thrown if is null. + + + + Creates a plain text attachment. + + The attachment name, or null to automatically assign one. + The text string, not null. + The attachment. + Thrown if is null. + + + + Creates an video attachment with a mime-type compatible with its internal representation. + + The attachment name, or null to automatically assign one. + The video to attach. + Thrown if is null. + + + + Creates an XHTML attachment. + + The attachment name, or null to automatically assign one. + The xhtml string, not null. + The attachment. + Thrown if is null. + + + + Creates an XML attachment. + + The attachment name, or null to automatically assign one. + The XML string, not null. + The attachment. + Thrown if is null. + + + + Recovers the attachment information from serializable attachment data. + + The attachment data. + The attachment. + Thrown if is null. + + + + Gets the name of the attachment, not null. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Generates serializable attachment data from an attachment. + + The attachment data. + + + + Specifies how attachments are stored in Xml and as files. + + + + + The attachment content is not present. + + + + + The attachment content is saved to a linked file indicated by . + + + + + The attachment content is included inline as + with a given . + + + + + + An Xml-serializable structure that describes the contents, encoding and disposition of an attachment. + + + The contents of the attachment are embedded in the execution log according to + their encoding. Text is directly embedded into the Xml whereas + binary attachments are base 64 encoded. + + + + + + Gets or sets the content disposition of the attachment which + indicates how the attachment has been stored. + + + + + Gets or sets the path of the attachment contents relative to + the directory that contains the Xml serialized report, + or null if the content is embedded. + + + + + Gets or sets the content type of the attachment as a MIME type, not null. + + Thrown if is null. + + + + Gets or sets the encoding of the attachment. + This value specifies how the attachment is represented in Xml. + + + + + Gets the binary contents of a binary attachment. + + The bytes, or null if not available. + Thrown if the attachment is not binary. + + + + Gets the text contents of a text attachment. + + The text, or null if not available. + Thrown if the attachment is not textual. + + + + Returns true if the attachment is textual, false if it is binary. + + + + + Loads the attachment contents from a stream. + + The stream. + Thrown if is null. + If the attachment could not be loaded. + + + + Gets or sets the name of the attachment, not null. + + Thrown if is null. + + + + Saves the attachment contents to a stream. + + The stream. + The preferred encoding to use if writing text, or null if none. + Thrown if is null. + If the attachment could not be saved. + Thrown if the attachment contents are not available. + + + + Gets or sets the attachment content serialized as text (including Base64 attachments), possibly null if none. + + + + + Specifies the Xml-encoding of the contents of an embedded attachment. + + + + + The attachment is encoded as a text string. + + + + + The attachment is encoded as base 64 text string. + + + + + Represents a binary-encoded attachment. + + + + + Creates an attachment. + + The attachment name, not null. + The content type, not null. + The binary data, not null. + Thrown if or is null. + + + + Gets the binary content of the attachment, not null. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Generates serializable attachment data from an attachment. + + The attachment data. + + + + A markup document writer that falls back to a different writer for certain + operations when its primary markup document writer is closed. + + + + + Creates a fallback markup document writer with the specified provider. + + The markup document writer to call by default. + The markup document to call as a fallback. + Thrown if + or is null. + + + + Adds an attachment to the markup document. + + The attachment to write, never null. + Thrown if there is already an attachment + with the same name. + + + + Begins a marked region in a markup stream. + + The markup stream name. + The marker. + + + + Begins a section in a markup stream. + + The markup stream name. + The name of the section to begin, never null. + + + + Embeds an attachment into a markup stream. + + The markup stream name. + The name of the attachment to write, never null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Ends the current region started with one of the Begin* methods in a markup stream. + + The markup stream name. + Thrown if there is no current nested region. + + + + Writes a text string to a markup stream. + + The markup stream name. + The text to write, never null. + + + + Interface implemented by objects that can write themselves to + a + + + + Writes the object to a markup stream. + + The markup stream. + Thrown if is null. + + + + A marker is a hidden tag that labels markup contents with a semantic class. + + + + + Creates a marker. + + The marker class. + Thrown if is null. + Thrown if the is not a valid identifier. . + + + + Creates a marker with attributes. + + The marker class. + The attributes. + Thrown if or + is null. + Thrown if the is not a valid identifier. . + + + + Standard marker for assertion failures. + + + + + Standard marker class for assertion failures. + + + + + Gets the marker's attributes which are optional name/value pairs associated + with a marker to carry additional semantic content. + + + + + Gets the marker class. + + + + + Creates a standard marker for a code location. + + + + + Standard marker class for code location references. + + + + + Column attribute for code location references. + + + + + Line attribute for code location references. + + + + + Path attribute for code location references. + + + + + Standard marker for content that represents added content in a diff. + + + + + Standard marker class for content that represents added content in a diff. + + + + + Standard marker for content that represents changed content in a diff. + + + + + Standard marker class for content that represents changed content in a diff. + + + + + Standard marker for content that represents deleted content in a diff. + + + + + Standard marker class for content that represents deleted content in a diff. + + + + + Standard marker for text that is elided and replaced by an ellipsis. + + + + + Standard marker class for content that has been elided and may be made available + instead as an attribute. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Standard marker for exceptions including their details. + + + + + Standard marker class for exceptions including their details. + + + + + Standard marker for exception messages reported as part of exception details. + + + + + Standard marker class for exception messages reported as part of exception details. + + + + + Standard marker for exception types reported as part of exception details. + + + + + Standard marker class for exception types reported as part of exception details. + + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Standard marker for content that should be displayed with a highlight. + + + + + Standard marker class for content that should be displayed with a highlight. + + + + + Standard marker for labels and headings. + + + + + Standard marker class for labels and headings. + + + + + Creates a standard marker for a link to a Url. + + + + + Standard marker class for link to a url. + + + + + Url attribute for links. + + + + + Standard marker for fixed width output such as that from a console or structured table. + + + + + Standard marker class for fixed width output such as that from a console or structured table. + + + + + Returns true if two markers are equal. + + The first marker to compare. + The second marker to compare. + True if the markers are equal. + + + + Returns true if two markers are not equal. + + The first marker to compare. + The second marker to compare. + True if the markers are not equal. + + + + Standard marker for stack traces. + + + + + Standard marker class for stack traces. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Verifies that the parameter is a valid marker class or attribute identifier. + + The identifier. + Thrown if is null. + Thrown if is empty or contains characters + other than letters, digits and underscores. + + + + Creates a copy of the marker with the specified attribute added. + + The attribute name. + The attribute value. + The marker copy with the attribute. + Thrown if + or is null. + Thrown if the is not a valid identifier. . + + + + A markup document writer records structured text as a hierarchically structured + document. + + + + Initializes a new instance of the class + + + + Attaches an attachment to the document. + + The attachment to include. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an HTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The HTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an image attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The image to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Adds an attachment to the markup document. + + The attachment to write, never null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XML-serialized object as an XML attachment with mime-type + using the default for the object's type. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The object to serialize and embed, must not be null. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XML-serialized object as an XML attachment with mime-type + using the specified . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The object to serialize and embed, must not be null. + The to use, or null to use the default + for the object's type. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an plain text attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The text to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches a video attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The video to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XHTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The XHTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The XML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Closes the markup document writer. + + + + + Closes the markup document writer. + + + + + Gets the stream writer for captured messages. + + + + + Gets the stream writer for captured messages. + + + + + Gets the stream writer for captured messages. + + + + + Gets the stream writer for diagnostic and messages. + + + + + Gets the stream writer for generic log messages. + + + + + Gets the stream writer for reporting failure messages and exceptions. + + + + + Flushes the markup writer. + + + + + Flushes the markup document writer. + + + + + Gets a writer for the stream with the specified name. + + The stream name, never null. + The markup stream writer. + + + + Returns true if the markup document writer is closed. + + + + + Gets the markup stream with the specified name. If the stream + does not exist, it is created on demand. + + The name of the markup stream. + The log stream. + Thrown if is null. + + + + Begins a marked region in a markup stream. + + The markup stream name. + The marker. + + + + Begins a section in a markup stream. + + The markup stream name. + The name of the section to begin, never null. + + + + Embeds an attachment into a markup stream. + + The markup stream name. + The name of the attachment to write, never null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Ends the current region started with one of the Begin* methods in a markup stream. + + The markup stream name. + Thrown if there is no current nested region. + + + + Flushes a markup stream. + + The markup stream name. + + + + Writes a text string to a markup stream. + + The markup stream name. + The text to write, never null. + + + + Gets the stream writer for reporting warning messages. + + + + + Utilities for normalizing markup contents. + + + + + Normalizes an attachment name. + + The attachment name, or null if none. + The normalized attachment name, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a content type. + + The content type, or null if none. + The normalized content type, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a section name. + + The section name, or null if none. + The normalized section name, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a stream name. + + The stream name, or null if none. + The normalized stream name, or null if none. May be the same instance if + was already normalized. + + + + Normalizes markup text. + + The text, or null if none. + The normalized text, or null if none. May be the same instance if + was already normalized. + + + + Common markup stream names. + + + + + The name of the standard stream for captured messages. + + + + + The name of the standard stream for captured messages. + + + + + The name of the standard stream for captured messages. + + + + + The name of the standard stream for diagnostic and messages. + + + + + The name of the standard stream for generic log messages. + + + + + The name of the standard stream for reporting failure messages and exceptions. + + + + + The name of the standard stream for reporting warning messages. + + + + + A markup stream writer provides methods for writing rich structured text with embedded + attachments, nested sections and hidden semantic markers to a particular stream within + a markup document writer. + + + + + Creates a markup stream writer. + + The containing markup document writer. + The stream name. + Thrown if + or is null. + + + + Begins a marked region. May be nested. + + The marker. + A Disposable object that calls when disposed. This + is a convenience for use with the C# "using" statement. + + + + Begins a section with the specified name. May be nested. + + The name of the section. + A Disposable object that calls when disposed. This + is a convenience for use with the C# "using" statement. + Thrown if is null. + + + + Gets the containing markup document writer. + + + + + This method does not make sense for a markup stream writer because + a stream cannot be closed independently of its containing document. + + + + + Embeds an attachment. + + The attachment to embed. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds another copy of an existing attachment. + + The name of the existing attachment to embed. + Thrown if is null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Embeds an HTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The HTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an image attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The image to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XML-serialized object as an XML attachment with mime-type + using the default for the object's type. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The object to serialize and embed, must not be null. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XML-serialized object as an XML attachment with mime-type + using the specified . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The object to serialize and embed, must not be null. + The to use, or null to use the default + for the object's type. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an plain text attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The text to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds a video attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The video to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XHTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The XHTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the document. + The XML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + When overridden in a derived class, returns the in which the output is written. + + + The Encoding in which the output is written. + + + + + Ends the region most recently started with one of the Begin* methods. + + Thrown if there is no current nested region. + + + + Clears all buffers for the current writer and causes any buffered data to be written to the underlying device. + + + + + Gets or sets the line terminator string used by the current TextWriter. + + + The line terminator string for the current TextWriter. + + + + + Gets the name of the markup stream being written. + + + + + + Writes a markup stream writable object to the stream. + + + The object to write, or null if none. + + + + Writes a character to the text stream. + + + The character to write to the text stream. + + + The is closed. + + + An I/O error occurs. + + + + + Writes a subarray of characters to the text stream. + + + The character array to write data from. + + + Starting index in the buffer. + + + The number of characters to write. + + + The buffer length minus is less than . + + + The parameter is null. + + + or is negative. + + + The is closed. + + + An I/O error occurs. + + + + + Writes the text representation of an object to the text stream by calling ToString on that object. + + + The object to write. + + + The is closed. + + + An I/O error occurs. + + + + + Writes a string to the text stream. + + + The string to write. + + + The is closed. + + + An I/O error occurs. + + + + + Writes an ellipsis to indicate where content has been elided for brevity. + An ellipsis may be used, for example, when printing assertion failures to clearly + identify sections where the user is not being presented all of the information + because it was too long and had to be truncated. + + + + + Writes an exception. + + The exception data to write. + Thrown if is null. + + + + Writes an exception within its own section which provides additional cues for interpretation. + + The exception data to write. + The section name, or null if none. + Thrown if is null. + + + + Writes an exception. + + The exception to write. + Thrown if is null. + + + + Writes an exception within its own section. + + The exception to write. + The section name, or null if none. + Thrown if is null. + + + + Writes highlighted text. Highlights can be used to + emphasize important information such differences between similar expected + and actual values. + + The text to write, or null if none. + + + + Writes the text representation of an object by calling ToString on this object, followed by a line terminator to the text stream. + + + The object to write. If is null, only the line termination characters are written. + + + The is closed. + + + An I/O error occurs. + + + + + Defines constants for commonly used mime types for attachment contents. + + + + + Binary data. + + + + + Cascading Style Sheet. + + + + + Flash video. + + + + + Guesses the extension given a well-known mime-type. + + The mime type. + The extension, or null if not known. + Thrown if is null. + + + + Guesses the mime type given a well-known extension. + + The extension. + The mime type, or null if not known. + Thrown if is null. + + + + GIF image. + + + + + HTML. + + + + + JavaScript + + + + + JPEG image. + + + + + MHTML web archive. + + + + + Plain text data. + + + + + PNG image. + + + + + Well-formed XHTML. + + + + + Xml data. + + + + + A markup document writer that does nothing. + + + + Initializes a new instance of the class + + + + Adds an attachment to the markup document. + + The attachment to write, never null. + Thrown if there is already an attachment + with the same name. + + + + Begins a marked region in a markup stream. + + The markup stream name. + The marker. + + + + Begins a section in a markup stream. + + The markup stream name. + The name of the section to begin, never null. + + + + Embeds an attachment into a markup stream. + + The markup stream name. + The name of the attachment to write, never null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Ends the current region started with one of the Begin* methods in a markup stream. + + The markup stream name. + Thrown if there is no current nested region. + + + + Writes a text string to a markup stream. + + The markup stream name. + The text to write, never null. + + + + An implementation of that writes its output to a string. + + + + + Creates a log stream writer for the stream. + + If true, prints detailed information about the location of + attachments, sections, and markers, otherwise discards these formatting details + and prints section headers as text on their own line. + + + + Gets the formatted log contents as a string. + + The contents as a string. + + + + A structured document is an Xml-serializable in-memory representation of a markup + document written by a . + + + + + Creates an empty document. + + + + + Gets the list of attachments, not null. + + + + + Gets an attachment by name. + + The attachment name. + The attachment or null if not found. + Thrown if is null. + + + + Gets a stream by name. + + The stream name. + The stream or null if not found. + Thrown if is null. + + + + Gets the list of streams, not null. + Used for Xml-serialization. + + + + + Formats the document to a string by concatenating all formatted streams and + displaying a "*** Stream Name ***" header for each stream name. + + The formatted text. + + + + Writes the contents of the document to a markup document writer. + + The writer. + Thrown if is null. + + + + Writes a in memory. + + + + + Creates a document writer that builds a new . + + + + + Adds an attachment to the markup document. + + The attachment to write, never null. + Thrown if there is already an attachment + with the same name. + + + + Closes the markup document writer. + + + + + Gets the document under construction. + + + + + Flushes the markup document writer. + + + + + Begins a marked region in a markup stream. + + The markup stream name. + The marker. + + + + Begins a section in a markup stream. + + The markup stream name. + The name of the section to begin, never null. + + + + Embeds an attachment into a markup stream. + + The markup stream name. + The name of the attachment to write, never null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Ends the current region started with one of the Begin* methods in a markup stream. + + The markup stream name. + Thrown if there is no current nested region. + + + + Flushes a markup stream. + + The markup stream name. + + + + Writes a text string to a markup stream. + + The markup stream name. + The text to write, never null. + + + + Flushes the writer and formats it as a string. + + The formatted document as a string. + + + + A structured stream object represents a recursively structured stream of rich text that + supports embedded attachments, nested sections and marked regions. Each part of the + text is captured by a tag, some of which are composable and may therefore contain other tags. + + + + + Creates an initialized stream. + + The stream name. + Thrown if is null. + + + + Gets or sets the body of the stream, not null. + + Thrown if is null. + + + + Gets or sets the name of the stream, not null. + + Thrown if is null. + + + + Formats the stream using a . + + The formatted text. + + + + Writes the contents of the stream to a markup stream writer. + + The writer. + Thrown if is null. + + + + A structured text object contains attachments and formatted text with rich + presentation elements. + + + + + Creates a structured text object that wraps the body tag of a structured markup document stream + and no attachments. + + The body tag to wrap. + Thrown if is null. + + + + Creates a structured text object that wraps the body tag of a structured markup document stream + and a list of attachments. + + The body tag to wrap. + The list of attachments. + Thrown if , + or is null. + + + + Creates a simple structured text object over a plain text string. + + The text string. + Thrown if is null. + + + + Gets the immutable list of attachments belonging to the structured text. + + + + + Gets a copy of the body tag that describes the structured text. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Returns the total length of all s that appear within + the structured text body. + + The total text length. + + + + Returns true if two structured text objects are equal. + + The first structured text object to compare. + The second structured text object to compare. + True if the structured text objects are equal. + + + + Returns true if two structured text objects are not equal. + + The first structured text object to compare. + The second structured text object to compare. + True if the structured text objects are not equal. + + + + Formats the structured text to a string, discarding unrepresentable formatting details. + + The structured text as a string. + + + + Writes the structured text to a markup stream writer and truncates its text + to a particular maximum length, omitting all subsequent contents. + + The writer. + The maximum length of text to write. + True if truncation occurred. + Thrown if is null. + Thrown if is negative. + + + + Writes the structured text to a markup stream writer. + + The writer. + Thrown if is null. + + + + Writes information in a structured manner so as to produce a + or . + + + + + Creates a structured text writer. + + + + + Returns the structured text formatted as a string. + + The structured text as a string. + + + + Gets the structured text produced so far. + + The structured text. + + + + Writes the object to a markup stream. + + The markup stream. + Thrown if is null. + + + + Represents a text-encoded attachment. + + + + + Creates an attachment. + + The attachment name, or null to automatically assign one. + The content type, not null. + The text string, not null. + Thrown if or is null. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets the text of the attachment, not null. + + + + + Generates serializable attachment data from an attachment. + + The attachment data. + + + + An implementation of that represents the test log as + text written to a . + + + + + Creates a textual markup document writer. + + The text writer to write to. + If true, prints detailed information about the location of + attachments, sections, and markers, otherwise discards these formatting details + and prints section headers as text on their own line. + Thrown if is null. + + + + Adds an attachment to the markup document. + + The attachment to write, never null. + Thrown if there is already an attachment + with the same name. + + + + Begins a marked region in a markup stream. + + The markup stream name. + The marker. + + + + Begins a section in a markup stream. + + The markup stream name. + The name of the section to begin, never null. + + + + Embeds an attachment into a markup stream. + + The markup stream name. + The name of the attachment to write, never null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Ends the current region started with one of the Begin* methods in a markup stream. + + The markup stream name. + Thrown if there is no current nested region. + + + + Writes a text string to a markup stream. + + The markup stream name. + The text to write, never null. + + + + Returns true if the verbose print mode is enabled. + + + + + Gets the underlying text writer. + + + + + An abstract base class for tag visitors that recursively traverses all tags + and does nothing else by default. + + + + Initializes a new instance of the class + + + + Visits a body tag. + + The tag to visit. + + + + Visits an embedded attachment tag. + + The tag to visit. + + + + Visits a marker tag. + + The tag to visit. + + + + Visits a section tag. + + The tag to visit. + + + + Visits a text tag. + + The tag to visit. + + + + The top-level container tag of markup. + + + + Initializes a new instance of the class + + + + Clones the object. + + The cloned object. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + An abstract container tag for representing tags that can contain other tags. + + + + + Creates an empty container tag. + + + + + Invokes the appropriate visitor method each element contained within this tag. + + The visitor. + Thrown if is null. + + + + Clones the object. + + The cloned object. + + + + Gets the list of nested contents of this tag. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + An embedded attachment tag. + + + + + Creates an initialized tag. + + The name of the attachment to embed. + Thrown if is null. + + + + Gets or sets the name of the referenced attachment to embed, not null. + + Thrown if is null. + + + + Clones the object. + + The cloned object. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Visits a . + + + + + Visits a body tag. + + The tag to visit. + + + + Visits an embedded attachment tag. + + The tag to visit. + + + + Visits a marker tag. + + The tag to visit. + + + + Visits a section tag. + + The tag to visit. + + + + Visits a text tag. + + The tag to visit. + + + + A marker tag. + + + + + Creates an initialized tag. + + The marker. + + + + Gets the list of marker attributes. + + + + + Gets or sets the marker class, not null. + + Thrown if is null. + Thrown if the is not a valid identifier. + . + + + + Clones the object. + + The cloned object. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets the marker. + + + + + Represents a marker attribute. + + + + + Creates an initialized attribute. + + The attribute name. + The attribute value. + Thrown if + is invalid. + Thrown if + or is null. + + + + Gets or sets the attribute name, not null. + + Thrown if is null. + Thrown if the is not a valid identifier. + + + + Gets or sets the attribute value, not null. + + Thrown if is null. + + + + A section tag. + + + + + Creates an initialized tag. + + The section name. + Thrown if is null. + + + + Clones the object. + + The cloned object. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets or sets the section name, not null. + + Thrown if is null. + + + + A tag is the fundamental unit of content within a markup stream. + + + + Initializes a new instance of the class + + + + Invokes the appropriate visitor method for this tag type. + + The visitor. + Thrown if is null. + + + + Clones the object. + + The cloned object. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Formats the tag using a . + + The formatted text. + + + + Writes the tag to a . + + The markup stream writer. + Throw if is null. + + + + + Formats instances to plain text. + + + Text tags are written as-is. Sections introduce paragraph breaks with + the header written out as the first line. Embedded attachments are + described by name. + + + + + Initializes a new instance of the class + + + + Appends text to the buffer including any requested spacing. + + The text to append. + + + + Ensures that the next chunk of text appended is separated by at least the specified + number of line breaks. + + The minimum number of line breaks to insert. + + + + Gets the formatted text that has been built. + + + + + Visits a body tag. + + The tag to visit. + + + + Visits an embedded attachment tag. + + The tag to visit. + + + + Visits a marker tag. + + The tag to visit. + + + + Visits a section tag. + + The tag to visit. + + + + Visits a text tag. + + The tag to visit. + + + + A text tag, containing text. + + + + + Creates an initialized text tag. + + The text within the tag. + Thrown if is null. + + + + Clones the object. + + The cloned object. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Provides the Xml schema for this element. + + The schema set. + The schema type of the element. + + + + Gets or sets the text within the tag, not null. + + Thrown if is null. + + + + A video frame that consists of a bitmap. + + + + + Creates a bitmap video frame. + + The bitmap. + Thrown if is null. + + + + Gets the bitmap. + + + + + Copies pixels from the frame into a buffer. + + The source rectangle of pixels to copy. + The buffer into which to copy the pixels as 32bit RGB with the upper 8 bits zeroed out. + The start offset where the first pixel should be written. + The incremental offset between subsequent rows of pixels. + + + + Gets the height of the video frame. + + + + + Gets the width of the video frame. + + + + + Displays a caption overlayed on top of an image. + + + + + Creates a caption overlay. + + + + + Gets or sets the font size. + + Thrown if is less than 1. + + + + Gets or sets the horizontal alignment. + + + + + Paints the overlay. + + The paint request, not null. + + + + Gets or sets the text of the caption. + + Thrown if is null. + + + + Gets or sets the vertical alignment. + + + + + Specifies parameters for screenshot captures. + + + + + Creates a capture parameters object. + + + + + Gets or sets the zoom factor. + + Thrown if is less than 1/16 or more than 16. + + + + Encodes video frames as FLV files using the Flash ScreenVideo lossless video codec. + + + + + Creates a new Flash screen video. + + The video parameters. + Thrown if is null. + + + + Adds a frame to the video. + + The video frame to add, not null. + + + + Gets the number of frames currently in the video. + + + + + Gets the mime-type of the video format. + + + + + Gets the video parameters. + + + + + Saves the video to a stream. + + The stream, not null. + + + + Specifies the parameters for a Flash screen video. + + + + + Creates a Flash video parameters object. + + The video width. + The video height. + The number of frames per second. + Thrown if or + are not between 1 and 4095 or if is not greater than zero. + + + + Gets or sets the height of each block to be compressed. + + Thrown if is invalid. + + + + Gets or sets the width of each block to be compressed. + + Thrown if is invalid. + + + + Gets or sets the ZLib compression level. + + Thrown if is invalid. + + + + Gets the interval between successive key frames. + + Thrown if is negative. + + + + Specifies the horizontal alignment of a caption. + + + + + Specifies left alignment. + + + + + Specifies horizontal alignment. + + + + + Specifies right alignment. + + + + + An exception that expresses a problem performing a media operation. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Abstract base class for video overlays. + + + + Initializes a new instance of the class + + + + Paints the overlay. + + The paint request. + Thrown if is null. + + + + Paints the overlay. + + The paint request, not null. + + + + Manages video source overlays. + + + + + Creates an overlay manager with no overlays. + + + + + Adds an overlay. + + The overlay to add. + Thrown if is null. + + + + Gets the read-only list of registered overlays. + + + + + Asks all overlays to paint themselves. + + The paint request. + Thrown if is null. + + + + Asks all overlays to paint themselves over the specified image. + + The image to paint on. + The frame number as in . + The number of frames per second as in . + Thrown if is null. + + + + Removes an overlay. + + The overlay to remove. + Thrown if is null. + + + + Returns a wrapper for the overlay manager as a composite overlay. + + The composite overlay. + + + + Describes a request to paint overlays. + + + + + Creates an overlay paint request. + + The graphics object to use for painting the overlay. + The bounds of the frame that is being rendered into the graphics context. + The zero-based monotonically increasing number of the frame that is being rendered. + The frame rate expressed as the number of frames per second, or zero if the frame is static. + Thrown if is null. + + + + Gets the zero-based monotonically increasing number of the frame that is being rendered. + + + + + Gets the bounds of the frame that is being rendered into the graphics context. + + + + + Gets the frame rate expressed as the number of frames per second, or zero if the frame is static. + + + + + Gets the graphics object to use for painting the overlay. + + + + + Grabs screenshots. + + + + + Creates a screen grabber. + + The capture parameters. + Thrown if is null. + + + + Returns true if screenshots can be captured. + + True if the screen can be captured. + + + + Captures a screenshot. + + If not null writes the screenshot into the specified bitmap, + otherwise creates and returns a new bitmap. + The screenshot. + Thrown if the provided is + not of the expected size. + Thrown if the object has been disposed. + Thrown if a screenshot cannot be captured at this time. + + + + Disposes the screen grabber. + + + + + Disposes the screen grabber. + + True if was called directly. + + + + Gets the size of the screen. + + The screen size. + + + + Gets the overlay manager. + + + + + Paints overlays onto a bitmap. + + The bitmap, not null. + + + + Gets the capture parameters. + + Thrown if the object has been disposed. + + + + Gets the width of the screenshots that will be taken. + + Thrown if the object has been disposed. + + + + Gets the width of the screenshots that will be taken. + + Thrown if the object has been disposed. + + + + Throws if the object has been disposed. + + + + + Throws an exception if a screenshot cannot be captured at this time. + + Thrown if a screenshot cannot be captured at this time. + + + + Records screenshots as a video. + + + + + Creates a screen recorder. + + The screen grabber. + The video to which frames are to be added. + Thrown if or + is null. + Thrown if size + is not exactly equal to the screenshot size. + + + + Adds a captured screenshot to the video. + + The bitmap, not null. + + + + Disposes the screen recorder. + + + + + Disposes the screen recorder. + + True if was called directly. + + + + Gets the current frame number. + + + + + Gets the number of frames per second. + + + + + Gets the screen grabber in use. + + Thrown if the object has been disposed. + + + + Gets the overlay manager. + + + + + Paints overlays onto a bitmap. + + The bitmap, not null. + + + + Starts or resumes recording. + + Thrown if the object has been disposed. + + + + Stops recorded. + + Thrown if the object has been disposed. + + + + Throws if the object has been disposed. + + + + + Gets the video being recorded. + + Thrown if the object has been disposed. + + + + An exception that is thrown when screenshots cannot be captured. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Specifies the vertical alignment of a caption. + + + + + Specifies top alignment. + + + + + Specifies middle alignment. + + + + + Specifies bottom alignment. + + + + + A video is an abstraction of an encoded video stream (possibly incorporating audio). + + + + + Creates a new video. + + The video parameters. + Thrown if is null. + + + + Adds a frame to the video. + + The video frame to add. + Thrown if is null. + Thrown if the dimensions are not + exactly equal to those of the video. + + + + Adds a frame to the video. + + The video frame to add, not null. + + + + Gets the number of frames currently in the video. + + + + + Gets the mime-type of the video format. + + + + + Gets the video parameters. + + + + + Saves the video to a stream. + + The stream. + Thrown if is null. + + + + Saves the video to a stream. + + The stream, not null. + + + + Represents a single frame of video content. + + + + Initializes a new instance of the class + + + + Copies pixels from the frame into a buffer. + + The source rectangle of pixels to copy. + The buffer into which to copy the pixels as 32bit RGB with the upper 8 bits zeroed out. + The start offset where the first pixel should be written. + The incremental offset between subsequent rows of pixels. + Thrown if is null. + Thrown if the components, + or are negative or if they would cause pixels + to be written outside the bounds of the pixel buffer. + Thrown if the components + are negative, is outside the bounds of the pixel buffer, or + is less than the width of the rectange. + Thrown if the combined dimensions, + and would cause pixels to be written out + of bounds of the pixel buffer. + + + + Copies pixels from the frame into a buffer. + + The source rectangle of pixels to copy. + The buffer into which to copy the pixels as 32bit RGB with the upper 8 bits zeroed out. + The start offset where the first pixel should be written. + The incremental offset between subsequent rows of pixels. + + + + Gets the height of the video frame. + + + + + Gets the width of the video frame. + + + + + Specifies the parameters for a video. + + + + + Creates a video parameters object. + + The width of the video. + The height of the video. + The number of frames per second of the video. + Thrown if or , + or are zero or negative. + + + + Gets the number of frames per second of the video. + + + + + Gets the height of the video. + + + + + Gets the width of the video. + + + + + An interface implemented by the server and registered on the server remoting channel + to allow message exchange with the client. + + + + + Gets the next message. + + The maximum amount of time to wait for a message. + The next message, or null if a timeout occurred. + + + + Sends a message. + + The message to send. + + + + Publishes messages directly to a subscriber. + + + + + Publishes a message. + + The message. + Thrown if is null. + Thrown if is not valid. + + + + Base class for all message objects. + + + + Initializes a new instance of the class + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + A message consumer provides a simple pattern for handling messages based on their type. + + + + + Creates a new message consumer with no handler clauses. + + + + + Consumes a message. + + The message to consume. + True if the message was consumed by a handler, false if no handler could consume it. + Thrown if is null. + Thrown if is not valid. + + + + Adds a handler for a particular message type. + + The message handler action. + The message type. + The message consumer. + Thrown if is null. + + + + Adds a catch-all handler. + + The message handler action. + The message consumer. + Thrown if is null. + + + + A message exchange mediates interactions between a server and a client. + + + + + Creates a message exchange. + + The message sink to which messages sent by the client should + be directed. + Thrown if is null. + + + + Gets an interface that a client can use to asynchronously receive and + synchronously send messages. + + The client link. + + + + Sends a message to the client. + + The message to send. + Thrown if is null. + Thrown if is not valid. + + + + Waits for all published messages to be received by the client. + + The timeout. + True if all messages were received, false if a timeout occurred. + + + + An exception thrown during a messaging failure. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + A null message sink discards all messages sent to it. + + + + + Gets the singleton instance of the null message sink. + + + + + Publishes a message. + + The message. + Thrown if is null. + Thrown if is not valid. + + + + Wraps a and queues messages so that messages are + published asynchronously. + + + + + Creates a queued message sink. + + The message sink to wrap. + Thrown if is null. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Flushes the queue. + + + + + Publishes a message. + + The message. + Thrown if is null. + Thrown if is not valid. + + + + Wraps a so that messages can be sent remotely. + + + + + Creates a remote message sink. + + The message sink to wrap. + Thrown if is null. + + + + Publishes a message. + + The message. + Thrown if is null. + Thrown if is not valid. + + + + Specifies a topic key routing published messages to their subscribers. + + + + + Creates a topic with a given key. + + The topic key. + Thrown if is null. + Thrown if is not a valid topic. + + + + Gets the complete topic key. + + + + + Returns the topic key. + + The topic key. + + + + A topic pattern expresses a simple matching rule for topics. + + + + + Creates a topic pattern. + + The topic pattern string. + Thrown if is null. + + + + Returns true if this pattern matches the specified topic. + + The topic to consider. + True if this pattern matches the specified topic. + Thrown if is null. + + + + Gets the topic pattern string. + + + + + Returns the topic pattern string. + + The topic pattern string. + + + + Provides a method that may be called by client code to obtain a normalized + copy of an object. + + The object type. + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Normalization utilities. + + + + + Normalizes a collection of normalizable values. + + The collection of values to normalize, or null if none. + The factory to use to create a new collection if needed. + The normalization function to apply to each value in the collection. + The comparer to compare normalized values to determine if a change occurred during normalization. + The type of the collection. + The type of the values in the collection. + The normalized collection, or null if none. The result will + be the same instance as if it was already normalized. + Thrown if , + or is null. + + + + Normalizes a name by replacing characters that are not printable with a '?'. + + The name to normalize, or null if none. + The normalized name, or null if was null. The result will + be the same instance as if it was already normalized. + + + + Normalizes a name by replacing characters that are not printable ASCII with '?'. + + The string to normalize, or null if none. + The normalized string, or null if was null. The result will + be the same instance as if it was already normalized. + + + + Normalizes a string. + + The string to normalize, or null if none. + The predicate to determine whether a character is valid. + If the character consists of a surrogate pair, then the parameter will be + its UTF32 value. + The converter to provide a replacement for an invalid character. + If the character consists of a surrogate pair, then the parameters will be + its UTF32 value. + The normalized text, or null if was null. The result will + be the same instance as if it was already normalized. + Thrown if + or is null. + + + + Normalizes Xml text. + + The Xml text to normalize, or null if none. + The normalized Xml text, or null if was null. The result will + be the same instance as if it was already normalized. + + + + Provides support for working with different versions of the .Net framework. + + + + + Gets the .Net framework version installed and currently running. + + The framework version. + + + + Specifies the version of the .Net framework. + + + + + .Net Framework 2.0. + + + + + .Net Framework 3.0. + + + + + .Net Framework 3.5. + + + + + .Net Framework 4.0. + + + + + Provides support for working with different implementations of the .Net runtime. + + + + + When using Mono, creates that re-enters the Mono runtime + if the executable is .Net otherwise creates a standard process start info. + + The executable path. + The arguments. + The process start info. + Thrown if + or is null. + + + + Gets the version of the installed .Net 2.0 runtime, or null if not installed. + + The runtime version, eg. "v2.0.50727" + + + + Gets the version of the installed .Net 4.0 runtime version, or null if not installed. + + The runtime version, eg. "v4.0.21006" + + + + Returns true if the application is running within the Mono runtime. + + + + + Gets the version of the most recent installed .Net runtime version. + + The runtime version, eg. "v4.0.21006" + + + + Get the type of the .Net runtime currently executing this process. + + + + + Gets the .Net runtime version in use. + + The runtime version, eg. "v2.0.50727" or "v4.0.21006" + + + + Specifies the .Net runtime type. + + + + + Using the Microsoft CLR. + + + + + Using the Mono runtime. + + + + + Specifies the integrity level of a Windows process. + + + + + Unknown integrity level. + + + + + Process is running with Untrusted integrity. + + + + + Process is running with Low integrity. + + + + + Process is running with Medium integrity. + + + + + Process is running with High integrity. + + + + + Process is running with System integrity. + + + + + Process is running with Protected Process integrity. + + + + + Provides support for working with different process execution models. + + + + + Returns true if the current process has elevated privileges. + + + + + Returns true if the current process is running in 32bit mode. + + + + + Returns true if the current process is running in 64bit mode. + + + + + Gets the integrity level of the current process. + + + + + Gets the process type of the current process. + + + + + Describes the kind of process that is executing. + + + + + The process is running in the console. + + + + + The process is running interactively. + + + + + The process is running as a Windows service. + + + + + Provides additional utilities for manipulating the Windows registry, particularly + to take care of differences on 32bit and 64bit platforms. + + + + + Gets a registry value taking into account the bitness of the platform. + + The key name. + The alternate key name to try on 64bit platforms if the other key cannot be found. (The name should probably include "Wow6432Node".) + The value name, or null to read the key's value. + The default value to return if the key exists but the value does not. + The value, or null if the key does not exist. + + + + Opens a registry subkey taking into account the bitness of the platform + and attempts to perform an action. If the action fails and running on x64, + then tries again with the alternate key. + + The registry key. + The subkey name. + The alternate subkey name to try on 64bit platforms if the other subkey cannot be found. (The name should probably include "Wow6432Node".) + The action to perform on the sub key. Should return true on success. + True if the action succeeded. + + + + Describes an exception that is to be reported. + + + + + Creates event arguments for reporting an exception. + + The message associated with the exception. + The exception that occurred. + The stack trace of the code that called to report the exception, or null if not available. + True if a second exception occurred while attempting to report a previous + unhandled exception on the same thread. + Thrown if or + is null. + + + + Adds a message that serves to describe the context in which the exception occurred. + The will be augmented with these details. + + The correlation message to append. + Thrown if is null. + + + + Gets the exception that occurred. + + + + + Formats a description of the exception to a string like: "Message\nException\nReported by: ReporterStackTrace". + + The formatted string. + + + + Formats the defaults of the exception to a string like: "Exception\nReported by: ReporterStackTrace". + + The formatted string. + + + + Returns true if a second exception occurred while attempting to report a previous + exception on the same thread. + + + + + Gets the message associated with the exception. + + + + + Gets the stack trace of the code that called to report the exception or null if not available. + + + + + Provides a few functions for working with and + and reporting unhandled exceptions in event + handlers safely via . + + + + + Safely invokes each delegate in the invocation list of an event handler. + Sends any exceptions thrown by the handler to . + + The event handler chain. + The sender. + The event arguments. + + + + Safely invokes each delegate in the invocation list of an event handler. + Sends any exceptions thrown by the handler to . + + The event handler chain. + The sender. + The event arguments. + + + + Describes a policy for obtaining paths of special resources such as + temporary directories and user profile settings files. + + + + + Creates a temporary directory with a unique name. + + The temporary directory. + + + + Creates a zero-byte temporary file with a unique name. + + The temporary file. + + + + Gets the special path policy for a partition whose name is derived from the type's full name. + + The type used to define the name of the partition. + The special path policy. + + + + Gets the special path policy for a specified partition. + + The partition name. + The special path policy. + Thrown if is null. + + + + Gets the application data directory shared by all users. + + The common application data directory. + + + + Gets the application data directory for the local non-roaming user. + + The local non-roaming user application data directory. + + + + Gets the application data directory for the roaming user. + + The roaming user application data directory. + + + + Gets the temporary directory. + + The temporary directory. + + + + Gets the name of the partition this policy describes. + + + + + This class provides a mechanism for reporting unhandled exceptions when the infrastructure + is otherwise unable to deal with them locally. + + + + + Adds or removes an event handler that is notified when unhandled exceptions occur + and is given a chance to add additional information the event about the + context in which the exception occurred. + + + + + Returns true if there is at least one handler registered for + . + + + + + Reports an unhandled exception. + + A message to explain how the exception was intercepted. + The unhandled exception. + Thrown if or is null. + + + + Adds or removes an event handler that is notified when unhandled exceptions occur. + + + + + Gets version information for Gallio components. + + + + + Gets a version label of a Gallio component assembly for display purposes. + + The assembly. + The version label. + Thrown if is null. + + + + Generates a version label from a version number for display purposes. + + The version to transform into a label. + The version label. + Thrown if is null. + + + + Gets the version number of an assembly for display purposes. + + The assembly. + The version number. + Thrown if is null. + + + + An assembly binding specifies the name and location of an assembly as well + as some properties to control how the .Net assembly loader resolves + particular assembly versions. + + + + + Creates an assembly binding using the name and codebase of the specified assembly. + + The assembly. + Thrown if is null. + + + + Creates an assembly binding with the specified assembly name. + + The assembly name. + Thrown if is null. + + + + Adds a binding redirect. + + The binding redirect to add. + Thrown if is null. + + + + Gets or sets whether to apply the assembly publisher policy. Default is true. + + + + + Gets the assembly name. + + + + + Gets the mutable list of assembly binding redirects. + + + + + Gets or sets the assembly codebase, or null if unknown. + + Thrown if + is not null and is not an absolute Uri. + + + + Gets or sets whether the assembly full name should be used to qualify all partial + name references to the assembly. + + + + + Specifies an old version range for an assembly binding redirect. + + + + + Creates an assembly binding redirect. + + The old assembly version number or range. + Thrown if is null. + Thrown if is not a valid version or version range. + + + + Gets the old assembly version number or range. + + Thrown if is null. + + + + Provides basic information about an Assembly derived from its metadata. + + + + + Gets the assembly references. + + Thrown if the assembly name was not populated. + + + + Gets the assembly references. + + Thrown if the assembly references were not populated. + + + + Gets the major version of the CLI runtime required for the assembly. + + + + + Gets the minor version of the CLI runtime required for the assembly. + + + + + Gets the processor architecture required for the assembly. + + + + + Gets the runtime version in the form "vX.Y.ZZZZ". + + Thrown if the runtime version were not populated. + + + + Specifies the optional fields of the assembly metadata that are to be populated. + + + + + Populates the basic PE format information about the assembly. + + + + + Populates the assembly name. + + + + + Populates the list of assembly references. + + + + + Populates the runtime version. + + + + + Describes characteristics used to match an assembly such as an assembly name and version range. + + + + + Creates an assembly signature. + + The simple name of the assembly. + Thrown if is null. + + + + Returns true if the signature matches the specified assembly name. + + The assembly name. + True if the signature matches the assembly name. + Thrown if is null. + + + + Gets the maximum assembly version to match inclusively, or null if there is no upper bound. + + + + + Gets the minimum assembly version to match inclusively, or null if there is no lower bound. + + + + + Gets the simple name of the assembly. + + + + + Parses the assembly signature from a string. + + The string to parse. + The parsed signature. + Thrown if is null. + Thrown if is malformed. + + + + Sets the assembly version to match. + + The version to match, or null if none. + + + + Sets the assembly version range to match. + + The minimum assembly version to match inclusively, or null if there is no lower bound. + The maximum assembly version to match inclusively, or null if there is no upper bound. + Thrown if is null but + not or vice-versa. Also thrown if + is greater than . + + + + Converts the signature to a string. + + The signature in a format that can be subsequently parsed by . + + + + Provides helpers for working with assemblies. + + + + + Gets the local path of the assembly prior to shadow copying. + Returns null if the original location of the assembly is not local. + + The assembly. + The original non-shadow copied local path of the assembly, or null if none. + Thrown if is null. + + + + Gets the location of the assembly, or null if it is dynamic. + + The assembly. + The assembly location as returned by or + null if the assembly is dynamic and does not have a location. + Thrown if is null. + + + + Gets metadata about CLI Assembly in Microsoft PE format. + + The stream. + The optional fields of the structure to populate. + The metadata or null if the stream does not represent a CLI assembly. + Thrown if is null. + + + + Gets the Major and Minor components of the CLI runtime version of a CLI Assembly in Microsoft PE format. + + The file path. + The optional fields of the structure to populate. + The version, of which only the major and minor components are populated, + or null if the stream does not represent a CLI assembly. + Thrown if is null. + + + + Gets the culture component of an assembly name. + + The assembly name. + The culture name. + Thrown if is null. + + + + If the assembly codebase is a local file, returns it as a local + path. Otherwise, returns the assembly codebase Uri. + + The assembly. + The assembly's path. + Thrown if is null. + + + + Gets the original local path of the assembly prior to shadow + copying, if it is local. Otherwise, returns the shadow-copied + assembly location. + + The assembly. + The local path of the assembly, preferably its original + non-shadow copied location, or null if the assembly is dynamic and does not + have a location. + Thrown if is null. + + + + Returns true if the stream represents a CLI Assembly in Microsoft PE format. + + The stream. + True if the stream represents an assembly. + Thrown if is null. + + + + Returns true if the file represents a CLI Assembly in Microsoft PE format. + + The file path. + True if the file represents an assembly. + Thrown if is null. + + + + Manipulates attributes described by their metadata. + + + + + Gets the attribute of the specified type, or null if none. + + The code element. + If true, includes inherited attributes. + The attribute type. + The attribute, or null if none. + Thrown if the code element + has multiple attributes of the specified type. + + + + Gets the attribute of the specified type, or null if none. + + The code element. + The attribute type. + If true, includes inherited attributes. + The attribute, or null if none. + Thrown if the code element + has multiple attributes of the specified type. + + + + Gets the attributes of the specified type. + + The code element. + If true, includes inherited attributes. + The attribute type. + The attributes. + + + + Gets the attributes of the specified type. + + The code element. + The attribute type. + If true, includes inherited attributes. + The attributes. + + + + Returns true if the code element has an attribute of the specified type. + + The code element. + If true, includes inherited attributes. + The attribute type. + True if the code element has at least one attribute of the specified type. + + + + Returns true if the code element has an attribute of the specified type. + + The code element. + The attribute type. + If true, includes inherited attributes. + True if the code element has at least one attribute of the specified type. + + + + Resolves all the attributes. + + The attribute descriptions. + The resolved attribute instances. + + + + Describes the kind of code element represented by a . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + The element is an . + + + + + Sorts code elements in various ways. + + + + + Sorts members such that those declared by supertypes appear before those + declared by subtypes. + + The members to sort. + The type of member. + The sorted members. + + + + Specifies the location of a code element as a position within a file. + + + + + Creates a code location. + + The path or Uri of a resource that contains the code element, + such as a source file or assembly, or null if unknown. + The line number, or 0 if unknown. + The column number, or 0 if unknown. + Thrown if or + is less than 0. + Thrown if is null and + is non-zero, or if is 0 and is non-zero. + + + + Gets the column number, or 0 if unknown. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Allows the code location structure to control + its own serialization and deserialization. + + The serialization info to populate with data. + The destination for this serialization. + + + + Gets the line number, or 0 if unknown. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Compares two code locations for equality. + + The first code location. + The second code location. + True if the code locations are equal. + + + + Compares two code locations for inequality. + + The first code location. + The second code location. + True if the code references are not equal. + + + + Gets the path or Uri of a resource that contains the code element, such as + a source file or assembly, or null if unknown. + + + + + Provides the Xml schema for this element. + + The schema set. + The schema type of the element. + + + + Converts the location to a string of the form "path(line,column)", + "path(line)" or "path" depending on which components are available. + + The code location as a string or "(unknown)" if unknown. + + + + Gets an empty code location with a null path and no line or column number information. + + + + + A code reference is a pointer into the structure of a .Net program for use in + describing the location of a certain code construct to the user. It is + typically used to identify the point of definition of a test component. + + + + + Creates a code reference from strings. + + The assembly name, or null if none. + The namespace name, or null if none. + The fully-qualified type name, or null if none. + The member name, or null if none. + The parameter name, or null if none. + + + + Gets the assembly name, or null if none. + + + + + Creates a code reference from an assembly. + + The assembly. + The code reference. + Thrown if is null. + + + + Creates a code reference from a member. + + The member. + The code reference. + Thrown if is null. + + + + Creates a code reference from an namespace name. + + The namespace name. + The code reference. + Thrown if is null. + + + + Creates a code reference from a method parameter. + + The parameter. + The code reference. + Thrown if is null. + + + + Creates a code reference from a type. + + The type. + The code reference. + Thrown if is null. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Gets the kind of code element specified by the code reference. + + + + + Gets the member name, or null if none. + + + + + Gets the namespace name, or null if none. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Compares two code references for equality. + + The first code reference. + The second code reference. + True if the code references are equal. + + + + Compares two code references for inequality. + + The first code reference. + The second code reference. + True if the code references are not equal. + + + + Gets the parameter name, or null if none. + + + + + Provides the Xml schema for this element. + + The schema set. + The schema type of the element. + + + + Produces a human-readable description of the code reference. + + A description of the code reference. + + + + Gets the fully-qualified type name, or null if none. + + + + + Gets an empty code reference used to indicate that the actual + reference is unknown. + + + + + Describes the kind of code element specified by a . + + + + + The code reference is unknown. + + + + + The code reference specifies an assembly. + + + + + The code reference specifies a namespace. + + + + + The code reference specifies a type. + + + + + The code reference specifies a constructor, method, property, field or event. + + + + + The code reference specifies a parameter of a constructor or method. + + + + + Specifies a typed constant value. + + + + + Creates a constant value. + + The constant value type. + The constant value. + Thrown if is null. + + + + Creates a constant value that wraps an existing native value. + + The native value. + The constant. + + + + Returns true if the value is an array. + + + + + Returns true if the value is an enum. + + + + + Returns true if the contents of can be interpreted as a native value + or false if must be used to resolve the constant to a native value. + + + + + Returns true if the value is a type. + + + + + Resolves the constant to a native value by replacing type references with actual + values, arrays of constants with values of the appropriate type, + and enums with values. + + If true, throws an exception if the target could + not be resolved, otherwise the result may include unresolved types, enums or arrays. + The native constant value. + Thrown if the target cannot be resolved. + + + + Gets the type of the constant. + + + + + Gets the value of the constant. + + + + + A placeholder enum type used to express enum values that cannot be resolved because + their actual enum type cannot be resolved. + + + + + Sorts an members that all belong to the same type + such that the members declared by supertypes appear before those + declared by subtypes. + + + + + Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other. + + + The first object to compare. + + + The second object to compare. + + + Value + + Condition + + Less than zero + is less than . + + Zero + equals . + + Greater than zero + is greater than . + + + + + Gets the singleton instance of the comparer. + + + + + A reflection wrapper. + + + + + Gets the full name of the assembly. + + + + + Gets the public types exported by the assembly. + + The exported types. + + + + Gets the of the assembly. + + The assembly name. + + + + Gets the names of the assemblies referenced by this assembly. + + The names of the references assemblies. + + + + Gets a public type by name, or null if not found. + + The type name. + The type. + + + + Gets all of the types in an assembly. + + The types. + + + + Gets the codebase of the assembly as a local path if possible or as a Uri otherwise. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Provides information about the contents of a custom attribute. + + + + + Gets the constructor used to create the attribute. + + Thrown if not supported. + + + + Gets an attribute field value. + + The field name. + The value, or a default value of the field's type if the field with the specified name + was not initialized by the attribute declaration. + Thrown if there is no writable instance field with the specified name. + + + + Gets an attribute property value. + + The property name. + The value, or a default value of the propery's type if the property with the specified name was not + initialized by the attribute declaration. + Thrown if there is no writable instance property with the specified name. + + + + Gets the initialized attribute constructor argument values. + + Thrown if not supported. + + + + Gets the initialized attribute field values. + + + + + Gets the initialized attribute property values. + + + + + Gets the attribute as an object. + + If true, throws an exception if the target could + not be resolved, otherwise the result may include unresolved types, enums or arrays + though it still may throw an exception if the attribute class cannot be instantiated. + The attribute. + Thrown if the attribute could not be resolved. + + + + Gets the attribute type. + + + + + Represents a structural element of some code base. + + + + + Gets a for this code element. + + The code reference. + + + + Gets information about the code element's custom attributes of the specified type. + + The attribute type, or null to return attributes of all types. + If true, includes inherited attributes + from base types (but not from interfaces, just like does). + The code element's attributes. + + + + Gets the code element's custom attributes of the specified type. + + The attribute type. + If true, includes inherited attributes + from base types (but not from interfaces, just like does). + The attributes. + + + + Gets the location of a resource that contains the declaration of this code element, or + if not available. The location may refer to the code + element's source code or to the location of its compiled assembly. + + The code location. + + + + Gets the XML documentation associated with the code element. + + The XML documentation or null if none available. + + + + Returns true if the code element has a custom attribute of the specified type. + + The attribute type, or null to search for attributes of all types. + If true, includes inherited attributes + from base types (but not from interfaces, just like does). + True if the code element has at least one attribute of the specified type. + + + + Gets the kind of code element represented by this instance. + + + + + Gets the name of the code element. + + + + + A reflection wrapper. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + A reflection wrapper. + + + + + Gets the add method of the event, or null if none. + + The add method, or null if none. + + + + Gets the event attributes. + + + + + Gets the event handler type. + + + + + Gets the raise method of the event, or null if none. + + The raise method, or null if none. + + + + Gets the remove method of the event, or null if none. + + The remove method, or null if none. + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + A reflection wrapper. + + + + + Gets the field attributes. + + + + + Gets a value indicating whether this field has Assembly level visibility. + + + + + Gets a value indicating whether this field has Family level visibility. + + + + + Gets a value indicating whether this field has FamilyAndAssembly level visibility. + + + + + Gets a value indicating whether this field has FamilyOrAssembly level visibility. + + + + + Returns true if the field is read-only and can only be set from the constructor. + + + + + Returns true if the field is a literal set at compile time. + + + + + Gets a value indicating whether the field is private. + + + + + Gets a value indicating whether the field is public. + + + + + Returns true if the field is static. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + A reflection wrapper. + + + + + Gets the calling conventions for this method. + + + + + Returns true if the method is abstract. + + + + + Gets a value indicating whether this method can be called by other classes in the same assembly. + + + + + Gets a value indicating whether access to this method is restricted to members of the class and members of its derived classes. + + + + + Gets a value indicating whether this method can be called by derived classes if they are in the same assembly. + + + + + Gets a value indicating whether this method can be called by derived classes, wherever they are, and by all classes in the same assembly. + + + + + Returns true if the method is final. + + + + + Gets a value indicating whether only a member of the same kind with exactly the same signature is hidden in the derived class. + + + + + Gets a value indicating whether this member is private. + + + + + Gets a value indicating whether this is a public method. + + + + + Returns true if the method is static. + + + + + Gets a value indicating whether the method is virtual. + + + + + Gets the method attributes. + + + + + Gets the parameters of the function. + + The parameters. + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + A reflection wrapper for generic parameters. + The parameter is presented as if it were a slot the accepted + a value of type . + + + + + Gets the constraints of the generic parameter. + + + + + Gets the declaring generic method of a generic method parameter + or null for a generic type parameter. + + + + + Gets the generic parameter attributes. + + + + + A reflection wrapper. + + + + + Gets the declaring type of the member. + + + + + Gets the reflected type of the member. The reflected type is the type that was + used to locate the member. If the member was inherited from a base class, its + declaring type will be the base class but its reflected type will be the inherited + class from which the member was accessed. + + + + + Gets the member to its underlying native reflection type. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The underlying native reflection type. + Thrown if the target cannot be resolved. + + + + A reflection wrapper. + + + + + Returns true if the method contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Gets the generic arguments of the method. + The list may contain objects when + no type has yet been bound to a certain generic parameter slots. + + The generic arguments. + + + + Gets the generic method definition of this method, or null if the method is not generic. + + + + + Returns true if the method is a generic method. + If so, the list will be non-empty. + + + + + Returns true if the method is a generic method definition. + + + + + Makes a generic method instantiation. + + The generic arguments. + The generic method instantiation. + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Gets the method return parameter object that contains information + about the return value and its attributes. + + + + + Gets the method return type. + + + + + A mirror describes a code element or attribute using a particular reflection policy. + + + + + Gets the reflection policy of the mirror. + + + + + A namespace reflection wrapper identified by its name. + + + + + A reflection wrapper. + + + + + Gets a value indicating whether this is an input parameter. + + + + + Gets a value indicating whether this parameter is optional. + + + + + Gets a value indicating whether this is an output parameter. + + + + + Gets the member to which the parameter belongs. + + + + + Gets the parameter attributes. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + A reflection wrapper. + + + + + Returns true if the property can be read. + + + + + Returns true if the property can be written. + + + + + Gets the get method of the property, or null if none. + + The get method, or null if none. + + + + Gets the list of index parameters for an indexer property, or + an empty array if none. + + + + + Gets the property attributes. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Gets the set method of the property, or null if none. + + The set method, or null if none. + + + + A reflection policy provides access to top-level reflection resources + such as assemblies. + + + + + Loads an assembly by name. + + The full or partial assembly name of the assembly to load. + The loaded assembly. + Thrown if is null. + Thrown if the assembly could not be loaded for any reason. + + + + Loads an assembly from a file. + + The assembly file path. + The loaded assembly. + Thrown if is null. + Thrown if the assembly could not be loaded for any reason. + + + + A slot represents a field, property or parameter. It is used to + simplify the handling of data binding since all three of these types + are similar in that they can hold values of some type. + + + + + Gets the positional index of a method parameter slot, -1 if the + slot is a method return parameter, or 0 if the slot is of some other kind. + + + + + Gets the type of value held in the slot. + + + + + A reflection wrapper. + + + + + Gets the rank of the array type. + + Thrown if the type is not an array type. + + + + Gets the assembly in which the type is declared. + + + + + Gets the assembly-qualified name of the type, or null if the type is a generic parameter. + + + + + Gets the base type of the type, or null if none. + + + + + Returns true if the type contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Gets the element type of an array, pointer or byref type, or null if none. + + + + + Gets the full name of the type, or null if the type is a generic parameter. + + + + + Gets the generic arguments of the type. + The list may contain objects when + no type has yet been bound to a certain generic parameter slots. + + The generic arguments, or an empty list if there are none. + + + + Gets the generic type definition of this type, or null if the type is not generic. + + + + + Gets all constructors of the type that satisfy the binding flags. + + The binding flags. + The constructors. + + + + Gets a event by name, or null if not found. + + The event name. + The binding flags. + The event. + + + + Gets all events of the type that satisfy the binding flags. + + The binding flags. + The events. + + + + Gets a field by name, or null if not found. + + The field name. + The binding flags. + The property. + + + + Gets all fields of the type that satisfy the binding flags. + + The binding flags. + The fields. + + + + Gets a method by name, or null if not found. + + The method name. + The binding flags. + The method. + + + + Gets all methods of the type that satisfy the binding flags. + + The binding flags. + The methods. + + + + Gets a nested type by name, or null if not found. + + The nested type name. + The binding flags. + The nested type. + + + + Gets all nested types of the type that satisfy the binding flags. + + The binding flags. + The nested types. + + + + Gets all properties of the type that satisfy the binding flags. + + The binding flags. + The properties. + + + + Gets a property by name, or null if not found. + + The property name. + The binding flags. + The property. + + + + Gets all of the type's interfaces. + + The type's interfaces. + + + + Returns true if the type is abstract and must be overridden. + + + + + Returns true if the type represents an array. + + + + + Returns true if variables of this type can be assigned with values of the specified type. + + The other type, or null if none. + True if the other type is not null and this type is assignable from the other type. + + + + Returns true if the type represents a type that is passed by reference. + + + + + Returns true if the type is a class. + + + + + Returns true if the type represents an enumeration. + + + + + Returns true if the type represents a generic type parameter. + + + + + Returns true if the type is a generic type. + If so, the list will be non-empty. + + + + + Returns true if the type is a generic type definition. + + + + + Returns true if the type is an interface. + + + + + Returns true if the type is nested. + + + + + Returns true if the type is nested and is visible only within its own assembly. + + + + + Returns true if the type is nested and visible only within its own family. + + + + + Returns true if the type is nested and visible only to classes that belong to both its own family and its own assembly. + + + + + Returns true if the type is nested and visible only to classes that belong to either its own family or to its own assembly. + + + + + Returns true if the type is nested and declared private. + + + + + Returns true if the type is nested and declared public. + + + + + Returns true if the type is not declared public. + + + + + Returns true if the type represents a pointer. + + + + + Returns true if the type is declared public. + + + + + Returns true if the type is sealed. + + + + + Returns true if this type is a subclass of the specified type. + + The other type, or null if none. + True if the other type is not null, this type is a subclass of the other type, + and this type not the same as the other type. + + + + Returns true if the type is a value type. + + + + + Makes an array type of the specified rank. + + The array rank. + The array type. + + + + Makes a reference type. + + The reference type. + + + + Makes a generic type instantiation. + + The generic arguments. + The generic type instantiation. + + + + Makes a pointer type. + + The pointer type. + + + + Gets the namespace in which the type is declared. + + + + + Gets the name of the namespace in which the type is declared. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Gets the type attributes. + + + + + Gets the type's . + + + + + This assembly loader loads assemblies externally for reflection only. + + + + + Creates an assembly loader. + + + + + Adds a hint directory to search for loading assemblies. + + The search directory to add. + Thrown if is null. + + + + Gets the reflection policy used to load and access the assemblies. + + + + + The type of exception thrown when a reflection info object or reference cannot + be resolved. + + + + + Creates an exception. + + + + + Creates an exception for an attribute that could not be resolved. + + The attribute that could not be resolved. + Thrown if is nul. + + + + Creates an exception for an attribute that could not be resolved. + + The attribute that could not be resolved. + The inner exception, or null if none. + Thrown if is nul. + + + + Creates an exception for a code element that could not be resolved. + + The code element that could not be resolved. + Thrown if is nul. + + + + Creates an exception for a code element that could not be resolved. + + The code element that could not be resolved. + The inner exception, or null if none. + Thrown if is nul. + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Provides functions for working with reflection. + + + + + Determines if the property has public, non-static and non-abstract getter + and setter functions. + + The property. + True if the property can be get and set. + + + + Determines if the type can be instantiated using a public constructor. + + The type. + True if the type can be instantiated. + + + + Determines if the method is public, non-static and is non-abstract so it can be invoked. + + The method. + True if the method can be invoked. + + + + Finds the assembly name of the directly referenced assembly with the specified display name. + + The assembly to search. + The display name of the referenced assembly to find. + The referenced assembly name or null if none. + + + + Gets the assembly that declares the code element, or the + code element itself if it is an . + + The code element, possibly null. + The assembly, or null if not found. + + + + Gets the default value for a type. + + The type. + The default value for the type, such as 0 if + the type represents an integer, or null if the type + is a reference type or if was null. + + + + Gets the default value of a type with a given type code. + + The type code. + The default value of the type associated with the + specified type code. + + + + Gets the non-type member that declares the code element, or the + code element itself if it is an + other than a . + + The code element, possibly null. + The member, or null if not found. + + + + Gets the namespace that declares the code element, or the + code element itself if it is an . + + The code element, possibly null. + The namespace, or null if not found. + + + + Gets the parameter that declares the code element, or the + code element itself if it is an . + + The code element, possibly null. + The parameter, or null if not found. + + + + Gets the type that declares the code element, or the + code element itself if it is an . + + The code element, possibly null. + The type, or null if not found. + + + + Returns true if the named type is assignable from the specified type. + + The search type. + The candidate type. + True if the search type is assignable from the candidate type. + Thrown if + or is null. + + + + Returns true if a type is derived from another type with the specified qualified name. + + The type to check. + The qualified type name. + True if is derived from + + + + Wraps reflection types using the reflection adapter interfaces. + Also resolves code references. + + + + + Creates a code element from the caller of the executing function. + + The code reference. + + + + Creates a code element from the executing function. + + The code reference. + + + + Creates a code element representing a function from a particular frame on the current stack. + + The number of frames to skip. If this number is 0, + the code reference will refer to the direct caller of this method; + if it is 1, it will refer to the caller's caller, and so on. + The code reference. + Thrown if is less than zero. + + + + Returns true if the target represents an unresolved assembly with + limited support for reflection. + + The assembly, or null if none. + True if the target is unresolved. + + + + Returns true if the target represents an unresolved member with + limited support for reflection. + + The member, or null if none. + True if the target is unresolved. + + + + Returns true if the target represents an unresolved parameter with + limited support for reflection. + + The parameter, or null if none. + True if the target is unresolved. + + + + Gets the singleton instance of the native + based on .Net reflection. + + + + + Resolves the specified . + + The code reference. + If true, throws an exception on error. + The associated code element, or null if the code reference + is of kind + Thrown if + is true and cannot be resolved. + + + + Obtains a reflection wrapper for an attribute instance. + + The attribute, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a list of types. + + The types, or null if none. + The reflection wrappers, or null original list was null. + + + + Obtains a reflection wrapper for an assembly. + + The assembly, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a constructor. + + The constructor, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for an event. + + The event, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a field. + + The field, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a member. + + The member, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a function. + + The function, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a method. + + The method, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a parameter. + + The parameter, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a property. + + The property, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a type. + + The type, or null if none. + The reflection wrapper, or null if none. + + + + Obtains a reflection wrapper for a namespace. + + The namespace name, or null if none. + The reflection wrapper, or null if none. + + + + Describes the name of a type and allows partial type names to be compared with one another. + + + + + Creates a type name from type info. + + The type info. + Thrown if is null. + Thrown if does not have a valid FullName property + (for example, it represents a generic type parameter). + + + + Creates a type name from its assembly-qualified name. + + The assembly-qualified name of the type, including + its namespace and assembly. + Thrown if is null. + Thrown if is malformed or + does not contain a valid assembly name. + + + + Creates a type name from its full name and assembly name. + + The full name of the type, including its namespace. + The full or partial name of the assembly that contains the type. + Thrown if or is null. + + + + Creates a type name from a type. + + The type. + Thrown if is null. + Thrown if does not have a valid FullName property + (for example, it represents a generic type parameter). + + + + Gets the full or partial name of the assembly that contains the type. + + + + + Gets the assembly-qualified name of the type, including its namespace and assembly. + + + + + Returns a type name that has a partial assembly name instead of the full assembly name. + + The type name. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Gets the full name of the type, including its namespace. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Returns true if the associated is a partial name only. + + + + + Resolves the type named by this instance. + + The type. + Thrown if the type could not be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A base reflection policy implementation that performs argument validation. + + + + Initializes a new instance of the class + + + + Loads an assembly by name. + + The full or partial assembly name of the assembly to load. + The loaded assembly. + Thrown if is null. + Thrown if the assembly could not be loaded for any reason. + + + + Loads an assembly from a file. + + The assembly file path. + The loaded assembly. + Thrown if is null. + Thrown if the assembly could not be loaded for any reason. + + + + Loads an assembly from a file. + + The assembly file path, not null. + The loaded assembly wrapper. + Any exception may be thrown if the loading fails. + + + + Loads an assembly. + + The assembly name, not null. + The loaded assembly wrapper. + Any exception may be thrown if the loading fails. + + + + Resolves debug symbols via the CorMetaDataDispenser COM class. + + + + + Creates a COM debug symbol resolver. + + If true, avoids taking a lock on the PDB files but may use more memory or storage. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Gets the location of a source file that contains the declaration of a method, or + null if not available. + + The path of the assembly that contains the method. + The method token. + The source code location, or null if unknown. + Thrown if is null. + + + + Helpers for working with . + + + + + Creates a new debug symbol resolver appropriate for this platform. + + If true, avoids taking a lock on the PDB files but may use more memory or storage. + The debug symbol resolver. + + + + Gets the location of a source file that contains the declaration of a method, or + unknown if not available. + + The method. + The source location, or if unknown. + Thrown if is null. + + + + Gets the location of a source file that contains the declaration of a type, or + unknown if not available. + + The type. + The code location, or if unknown. + Thrown if is null. + + + + Gets the singleton debug symbol resolver used by these utilities. + + + + + The default XML documentation resolver reads XML documentation files on + demand when available and caches them in memory for subsequent accesses. + It takes care of mapping member names to XML documentation conventions + when asked to resolve the documentation for a member. + + + + + Creates an XML documentation loader. + + + + + Gets the XML documentation for a member in an assembly. + + The assembly path. + The XML documentation id of the member. + The XML documentation for the member, or null if none available. + Thrown if or is null. + + + + Resolves debug symbols associated with members. + + + + + Gets the location of a source file that contains the declaration of a method, or + null if not available. + + The path of the assembly that contains the method. + The method token. + The source code location, or null if unknown. + Thrown if is null. + + + + This extension of is provided to enable the resolution of + a type with . + + + + + Resolves the wrapper to its native reflection target within the scope + of the specified method. + + The method that is currently in scope, or null if none. + This parameter is used when resolving types that are part of the signature + of a generic method so that generic method arguments can be handled correctly. + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Represents a code element that could not be resolved to a native reflection type. + + + + + Gets the underlying reflection adapter. + + + + + Resolves members to XML documentation contents. + + + + + Gets the XML documentation for a member in an assembly. + + The assembly path. + The XML documentation id of the member. + The XML documentation for the member, or null if none available. + Thrown if or is null. + + + + Implementation of a debug symbol resolver for Mono. + + + + + Creates a Mono debug symbol resolver. + + If true, avoids taking a lock on the PDB files but may use more memory or storage. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Gets the location of a source file that contains the declaration of a method, or + null if not available. + + The path of the assembly that contains the method. + The method token. + The source code location, or null if unknown. + Thrown if is null. + + + + Provides helpers for enumerating attributes taking into account + the attribute inheritance structure. + + + + + Creates an attribute instance from an . + + The attribute description. + If true, throws an exception if the target could + not be resolved, otherwise the result may include unresolved types, enums or arrays. + The attribute instance. + Thrown if the attribute could not be resolved. + + + + Returns true if the field is assignable as a named attribute parameter. + + The field. + True if the field is assignable. + + + + Returns true if the property is assignable as a named attribute parameter. + + The property. + True if the property is assignable. + + + + Provides helpers for manipulating reflection flags enumerations. + + + + Initializes a new instance of the class + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Adds to the enumeration + if is true. + + The flags enumeration to update. + The flag to add if is true. + The condition to check. + + + + Provides helpers for resolving abstract reflection objects to obtain + native ones based on the structural properties of the reflected + code elements. + + + + Initializes a new instance of the class + + + + Resolves a reflected assembly to its native object. + + The reflected assembly. + If true, allows the assembly to be resolved + by partial name if no match could be found by fullname. + If true, throws an exception if resolution fails, + otherwise returns an unresolved assembly object that can be detected + using . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected constructor to its native object. + + The reflected constructor. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected event to its native object. + + The reflected event. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected field to its native object. + + The reflected type. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected method to its native object. + + The reflected method. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected parameter to its native object. + + The reflected parameter. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected property to its native object. + + The reflected property. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Resolves a reflected type to its native object. + + The reflected type. + The method that is currently in scope, or null if none. + This parameter is used when resolving types that are part of the signature + of a generic method so that generic method arguments can be handled correctly. + If true, throws an exception if resolution fails, + otherwise returns an unresolved . + The resolved . + Thrown if + is null. + Thrown if + could not be resolved. + + + + Provides helpers for working with types and type codes. + + + + Initializes a new instance of the class + + + + Gets the default value for a reflected type. + + The reflected type. + The default value for the type, such as 0 if + the type represents an integer, or null if the type + is a reference type or if was null. + + + + Determines the type code of a reflected type based on the + type's name. + + The reflected type, or null if none. + The type code of the type, or + if was null. + + + + A array type wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The element type. + The array rank. + Thrown if or is null. + Thrown if is less than 1. + + + + Gets the rank of the array type. + + Thrown if the type is not an array type. + + + + + + Returns true if the type represents an array. + + + + + Gets the type attributes. + + + + + A assembly wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + Thrown if or is null. + + + + Gets a for this code element. + + The code reference. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the full name of the assembly. + + + + + Gets the location of a resource that contains the declaration of this code element, or + if not available. The location may refer to the code + element's source code or to the location of its compiled assembly. + + The code location. + + + + Gets the public types exported by the assembly. + + The exported types. + + + + Gets the of the assembly. + + The assembly name. + + + + Gets the names of the assemblies referenced by this assembly. + + The names of the references assemblies. + + + + Gets a public type by name, or null if not found. + + The type name. + The type. + + + + Gets all of the types in an assembly. + + The types. + + + + Returns true if the internal members of this assembly are visible to the specified assembly. + + The other assembly. + True if the other assembly can see internal members of this assembly. + + + + Gets the kind of code element represented by this instance. + + + + + Gets the name of the code element. + + + + + Gets the codebase of the assembly as a local path if possible or as a Uri otherwise. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A attribute wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + Thrown if or is null. + + + + Gets the constructor used to create the attribute. + + Thrown if not supported. + + + + Gets an attribute field value. + + The field name. + The value, or a default value of the field's type if the field with the specified name + was not initialized by the attribute declaration. + Thrown if there is no writable instance field with the specified name. + + + + Gets an attribute property value. + + The property name. + The value, or a default value of the propery's type if the property with the specified name was not + initialized by the attribute declaration. + Thrown if there is no writable instance property with the specified name. + + + + Gets the initialized attribute constructor argument values. + + Thrown if not supported. + + + + Gets the initialized attribute field values. + + + + + Gets the initialized attribute property values. + + + + + Gets the attribute as an object. + + If true, throws an exception if the target could + not be resolved, otherwise the result may include unresolved types, enums or arrays + though it still may throw an exception if the attribute class cannot be instantiated. + The attribute. + Thrown if the attribute could not be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the attribute type. + + + + + A by-ref type wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The element type. + Thrown if or is null. + + + + + + Returns true if the type represents a type that is passed by reference. + + + + + Gets the type attributes. + + + + + A code element wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + Thrown if or is null. + + + + Gets a for this code element. + + The code reference. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets information about the code element's custom attributes of the specified type. + + The attribute type, or null to return attributes of all types. + If true, includes inherited attributes + from base types (but not from interfaces, just like does). + The code element's attributes. + + + + Gets the code element's custom attributes of the specified type. + + The attribute type. + If true, includes inherited attributes + from base types (but not from interfaces, just like does). + The attributes. + + + + Gets the location of a resource that contains the declaration of this code element, or + if not available. The location may refer to the code + element's source code or to the location of its compiled assembly. + + The code location. + + + + Gets all attributes that appear on this code element, excluding inherited attributes. + + The attribute wrappers. + + + + Gets an enumeration of elements from which this code element inherits. + + The inherited code elements. + + + + Gets all pseudo custom attributes associated with a member. + + The pseudo custom attributes. + + + + Gets the XML documentation associated with the code element. + + The XML documentation or null if none available. + + + + Returns true if the code element has a custom attribute of the specified type. + + The attribute type, or null to search for attributes of all types. + If true, includes inherited attributes + from base types (but not from interfaces, just like does). + True if the code element has at least one attribute of the specified type. + + + + Gets the kind of code element represented by this instance. + + + + + Gets the name of the code element. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A constructed type wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The element type. + Thrown if or is null. + + + + Gets the assembly in which the type is declared. + + + + + Returns true if the type contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Gets the element type, or null if none. + + + + + Gets the full name of the type, or null if the type is a generic parameter. + + + + + Gets the location of a resource that contains the declaration of this code element, or + if not available. The location may refer to the code + element's source code or to the location of its compiled assembly. + + The code location. + + + + Gets all attributes that appear on this code element, excluding inherited attributes. + + The attribute wrappers. + + + + Gets the name of the code element. + + + + + Gets the name of the namespace in which the type is declared. + + + + + Gets the suffix to append to the name of the constructed type. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A constructor wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + Thrown if , , + or is null. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the kind of code element represented by this instance. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A declared type wrapper such as a + class, struct, enum or interface definition. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type, or null if none. + The type substitution for generic parameters. + Thrown if or is null. + + + + Gets the assembly in which the type is declared. + + + + + Gets the base type, or null if none. + + + + + Composes the substitution of the type with the specified substitution and returns a new wrapper. + + The substitution. + The new wrapper with the composed substitution. + + + + Returns true if the type contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Gets the full name of the type, or null if the type is a generic parameter. + + + + + Gets the generic arguments of the type. + The list may contain objects when + no type has yet been bound to a certain generic parameter slots. + + The generic arguments, or an empty list if there are none. + + + + Gets the generic type definition of this type, or null if the type is not generic. + + + + + Gets an enumeration of all base types. + + The enumeration of base types. + + + + Gets all constructors of the type that satisfy the binding flags. + + The binding flags. + The constructors. + + + + Gets a event by name, or null if not found. + + The event name. + The binding flags. + The event. + + + + Gets all events of the type that satisfy the binding flags. + + The binding flags. + The events. + + + + Gets a field by name, or null if not found. + + The field name. + The binding flags. + The property. + + + + Gets all fields of the type that satisfy the binding flags. + + The binding flags. + The fields. + + + + Gets a method by name, or null if not found. + + The method name. + The binding flags. + The method. + + + + Gets all methods of the type that satisfy the binding flags. + + The binding flags. + The methods. + + + + Gets a nested type by name, or null if not found. + + The nested type name. + The binding flags. + The nested type. + + + + Gets all nested types of the type that satisfy the binding flags. + + The binding flags. + The nested types. + + + + Gets all properties of the type that satisfy the binding flags. + + The binding flags. + The properties. + + + + Gets a property by name, or null if not found. + + The property name. + The binding flags. + The property. + + + + Gets all of the type's interfaces. + + The type's interfaces. + + + + Returns true if the type is a generic type. + If so, the list will be non-empty. + + + + + Returns true if the type is a generic type definition. + + + + + Makes a generic type instantiation. + + The generic arguments. + The generic type instantiation. + + + + Gets the name of the code element. + + + + + Gets the name of the namespace in which the type is declared. + + + + + Gets the type substitution for generic parameters. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the type attributes. + + + + + A event wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + The reflected type. + Thrown if , , + , or is null. + + + + Gets the add method of the event, or null if none. + + The add method, or null if none. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the event attributes. + + + + + Gets the event handler type. + + + + + Gets the events that this one overrides or hides. + Only includes overrides that appear on class types, not interfaces. + + If true, only returns overrides. + + + + Gets the kind of code element represented by this instance. + + + + + Gets the raise method of the event, or null if none. + + The raise method, or null if none. + + + + Gets the remove method of the event, or null if none. + + The remove method, or null if none. + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A field wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + The reflected type. + Thrown if , , + , or is null. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the field attributes. + + + + + Gets a value indicating whether this field has Assembly level visibility. + + + + + Gets a value indicating whether this field has Family level visibility. + + + + + Gets a value indicating whether this field has FamilyAndAssembly level visibility. + + + + + Gets a value indicating whether this field has FamilyOrAssembly level visibility. + + + + + Returns true if the field is read-only and can only be set from the constructor. + + + + + Returns true if the field is a literal set at compile time. + + + + + Gets a value indicating whether the field is private. + + + + + Gets a value indicating whether the field is public. + + + + + Returns true if the field is static. + + + + + Gets the kind of code element represented by this instance. + + + + + Gets the positional index of a method parameter slot, -1 if the + slot is a method return parameter, or 0 if the slot is of some other kind. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the type of value held in the slot. + + + + + A function wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + The reflected type, or null if none. + Thrown if , , + , or is null. + + + + Gets the calling conventions for this method. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Returns true if the method is abstract. + + + + + Gets a value indicating whether this method can be called by other classes in the same assembly. + + + + + Gets a value indicating whether access to this method is restricted to members of the class and members of its derived classes. + + + + + Gets a value indicating whether this method can be called by derived classes if they are in the same assembly. + + + + + Gets a value indicating whether this method can be called by derived classes, wherever they are, and by all classes in the same assembly. + + + + + Returns true if the method is final. + + + + + Gets a value indicating whether only a member of the same kind with exactly the same signature is hidden in the derived class. + + + + + Gets a value indicating whether this member is private. + + + + + Gets a value indicating whether this is a public method. + + + + + Returns true if the method is static. + + + + + Gets a value indicating whether the method is virtual. + + + + + Gets the method attributes. + + + + + Gets the parameters of the function. + + The parameters. + + + + Implementation of + + + + Implementation of + + + + A generic parameter wrapper. + + + + + Gets the assembly in which the type is declared. + + + + + Gets the assembly-qualified name of the type, or null if the type is a generic parameter. + + + + + Gets the constraints of the generic parameter. + + + + + Returns true if the type contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Creates a wrapper for a generic method parameter. + + The reflection policy. + The underlying reflection object. + The declaring method, which must be a generic method definition. + Thrown if , + or is null. + + + + Creates a wrapper for a generic type parameter. + + The reflection policy. + The underlying reflection object. + The declaring type, which must be a generic type definition. + Thrown if , + or is null. + + + + Gets the declaring method, or null if the generic parameter belongs to a type. + + + + + Gets the declaring type, or null if none. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the full name of the type, or null if the type is a generic parameter. + + + + + Gets the generic parameter attributes. + + + + + Gets all constructors of the type that satisfy the binding flags. + + The binding flags. + The constructors. + + + + Returns true if the type represents a generic type parameter. + + + + + Gets the kind of code element represented by this instance. + + + + + Gets the name of the namespace in which the type is declared. + + + + + Gets the positional index of a method parameter slot, -1 if the + slot is a method return parameter, or 0 if the slot is of some other kind. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the type attributes. + + + + + Gets the type of value held in the slot. + + + + + A member wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type, or null if none. + Thrown if or is null. + + + + Gets a for this code element. + + The code reference. + + + + Gets the declaring type, or null if none. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + + Gets the location of a resource that contains the declaration of this code element, or + if not available. The location may refer to the code + element's source code or to the location of its compiled assembly. + + The code location. + + + + Gets all attributes that appear on this code element, excluding inherited attributes. + + The attribute wrappers. + + + + + Gets the name of the code element. + + + + + Gets the reflected type, or null if none. + + + + + Implementation of + + + + Gets the type substitution for generic parameters. + + + + + A method wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + The reflected type. + The type substitution for generic parameters. + Thrown if , , + or or is null. + + + + Returns true if the method contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Gets the generic arguments of the method. + The list may contain objects when + no type has yet been bound to a certain generic parameter slots. + + The generic arguments. + + + + Gets the generic method definition of this method, or null if the method is not generic. + + + + + Gets the methods that this one overrides or hides. + Only includes overrides that appear on class types, not interfaces. + + If true, only returns overrides. + + + + Returns true if this method hides the specified method. + + The other method. + True if this method hides the other method. + + + + Returns true if the method is a generic method. + If so, the list will be non-empty. + + + + + Returns true if the method is a generic method definition. + + + + + Returns true if this method overrides another. + + + + + Gets the kind of code element represented by this instance. + + + + + Makes a generic method instantiation. + + The generic arguments. + The generic method instantiation. + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Gets the method return parameter object that contains information + about the return value and its attributes. + + + + + Gets the method return type. + + + + + Gets the type substitution for generic parameters. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A parameter wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The member to which the parameter belongs. + Thrown if , + or is null. + + + + Gets a for this code element. + + The code reference. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + + + Gets a value indicating whether this is an input parameter. + + + + + Gets a value indicating whether this parameter is optional. + + + + + Gets a value indicating whether this is an output parameter. + + + + + Gets the kind of code element represented by this instance. + + + + + Gets the member to which the parameter belongs. + + + + + Gets the name of the code element. + + + + + Gets the parameter attributes. + + + + + Gets the positional index of a method parameter slot, -1 if the + slot is a method return parameter, or 0 if the slot is of some other kind. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the type of value held in the slot. + + + + + A pointer type wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The element type. + Thrown if or is null. + + + + + + Returns true if the type represents a pointer. + + + + + Gets the type attributes. + + + + + A property wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + The reflected type. + Thrown if , , + , or is null. + + + + Returns true if the property can be read. + + + + + Returns true if the property can be written. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the get method of the property, or null if none. + + The get method, or null if none. + + + + Gets the properties that this one overrides or hides. + Only includes overrides that appear on class types, not interfaces. + + If true, only returns overrides. + + + + Gets the list of index parameters for an indexer property, or + an empty array if none. + + + + + Gets the kind of code element represented by this instance. + + + + + Gets the positional index of a method parameter slot, -1 if the + slot is a method return parameter, or 0 if the slot is of some other kind. + + + + + Gets the property attributes. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Gets the set method of the property, or null if none. + + The set method, or null if none. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Gets the type of value held in the slot. + + + + + A member wrapper for members that are not types, + generic parameters or nested types. These members must be declared by types, so + they all share the constraint that the declaring type and reflected type must not be null. + In particular, the reflected type may be a subtype of the declaring type in the case + of inherited members. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type. + The reflected type. + Thrown if , , + , or is null. + + + + Gets the reflected type, or null if none. + + + + + The static reflection policy base class is intended to assist with the implementation + of custom reflection policies defined over static metadata. + + + + Initializes a new instance of the class + + + + Determines if two wrappers represent the same object. + + The first wrapper, not null. + The second wrapper, not null. + True if both wrapper represent the same object. + + + + Gets the custom attributes of an assembly. + + The assembly, not null. + The attributes. + + + + Gets the public types exported by an assembly. + + The assembly wrapper, not null. + The types. + + + + Gets the name of an assembly. + + The assembly wrapper, not null. + The assembly name. + + + + Gets the path of an assembly. + + The assembly wrapper, not null. + The assembly path. + + + + Gets the references of an assembly. + + The assembly wrapper, not null. + The assembly references. + + + + Gets the specified named type within an assembly. + + The assembly wrapper, not null. + The type name, not null. + The type, or null if none. + + + + Gets all types contained in an assembly. + + The assembly wrapper, not null. + The types. + + + + Gets the constructor of an attribute. + + The attribute, not null. + The constructor. + + + + Gets the constructor arguments of an attribute. + + The attribute, not null. + The constructor argument values. + + + + Gets the field arguments of an attribute. + + The attribute, not null. + The field argument values. + + + + Gets the property arguments of an attribute. + + The attribute, not null. + The property argument values. + + + + Gets the add method of an event, or null if none. + + The event, not null. + The add method, or null if none. + + + + Gets the attributes of an event. + + The event, not null. + The event attributes. + + + + Gets the event handler type of an event. + + The event, not null. + The event handler type. + + + + Gets the raise method of an event, or null if none. + + The event, not null. + The raise method, or null if none. + + + + Gets the remove method of an event, or null if none. + + The event, not null. + The remove method, or null if none. + + + + Gets the attributes of a field. + + The field, not null. + The field attributes. + + + + Gets the field type. + + The field, not null. + The field type. + + + + Gets the attributes of a function. + + The function, not null. + The function attributes. + + + + Gets the calling conventions of a function. + + The function, not null. + The function calling conventions. + + + + Gets the parameters of a function. + + The function, not null. + The parameters. + + + + Gets the attributes of a generic parameter. + + The generic parameter, not null. + The generic parameter attributes. + + + + Gets the generic parameter constraints. + + The generic parameter, not null. + The generic parameter constraints. + + + + Gets the generic parameter position. + + The generic parameter, not null. + The generic parameter position. + + + + Gets a hashcode for a wrapper. + + The wrapper, not null. + The wrapper's hash code. + + + + Gets the custom attributes of a member. + + The member, not null. + The custom attributes. + + + + Gets the short name of a member. + In the case of a generic type, should exclude the generic parameter count + part of the name. eg. "`1" + + The member, not null. + The member's name. + + + + Gets the source code location of a member. + + The member, not null. + The source code location, or if not available. + + + + Gets the generic parameters of a method. + + The method, not null. + The generic parameters. + + + + Gets the return parameter of a method. + + The method, not null. + The return parameter. + + + + Gets the attributes of a parameter. + + The parameter, not null. + The parameter attributes. + + + + Gets the custom attributes of a parameter. + + The parameter, not null. + The custom attributes. + + + + Gets the name of a parameter. + + The parameter, not null. + The parameter's name. + + + + Gets the parameter's position, or -1 if the parameter is a return value. + + The parameter, not null. + The parameter's position. + + + + Gets the parameter type. + + The parameter, not null. + The parameter type. + + + + Gets the attributes of a property. + + The property, not null. + The property attributes. + + + + Gets the get method of a property, or null if none. + + The property, not null. + The get method, or null if none. + + + + Gets the set method of a property, or null if none. + + The property, not null. + The set method, or null if none. + + + + Gets the property type. + + The property, not null. + The property type. + + + + Gets the assembly that contains a type. + + The type, not null. + The type's assembly. + + + + Gets the attributes of a type. + + The type, not null. + The type attributes. + + + + Gets the base type of atype. + + The type, not null. + The base type. + + + + Gets the constructors of a type. + Only includes declared methods, not inherited ones. + + The type, not null. + The type's constructors. + + + + Gets the events of a type. + Only includes declared methods, not inherited ones. + + The type, not null. + The reflected type, not null. + The type's events. + + + + Gets the fields of a type. + Only includes declared methods, not inherited ones. + + The type, not null. + The reflected type, not null. + The type's fields. + + + + Gets the generic parameters of a type, including all generic parameters + of its declaring types if it is nested enumerated from outside in. + + The type, not null. + The type's generic parameters. + + + + Gets the interfaces directly implemented by a type. + + The type, not null. + The type's interfaces. + + + + Gets the methods of a type including accessor methods for properties and events. + Only includes declared methods, not inherited ones. + + The type, not null. + The reflected type, not null. + The type's methods. + + + + Gets the namespace that contains a type. + + The type, not null. + The type's namespace, or an empty string if it has none. + + + + Gets the nested types of a type. + Only includes declared nested types, not inherited ones. + + The type, not null. + The type's nested types. + + + + Gets the properties of a type. + Only includes declared methods, not inherited ones. + + The type, not null. + The reflected type, not null. + The type's properties. + + + + A type wrapper that represents a special type + that is either constructed from other types or derived from them as with a generic parameter. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type, or null if none. + Thrown if or is null. + + + + Internal implementation of . + + + + + Gets all constructors of the type that satisfy the binding flags. + + The binding flags. + The constructors. + + + + Gets a event by name, or null if not found. + + The event name. + The binding flags. + The event. + + + + Gets all events of the type that satisfy the binding flags. + + The binding flags. + The events. + + + + Gets a field by name, or null if not found. + + The field name. + The binding flags. + The property. + + + + Gets all fields of the type that satisfy the binding flags. + + The binding flags. + The fields. + + + + Gets a method by name, or null if not found. + + The method name. + The binding flags. + The method. + + + + Gets all methods of the type that satisfy the binding flags. + + The binding flags. + The methods. + + + + Gets a nested type by name, or null if not found. + + The nested type name. + The binding flags. + The nested type. + + + + Gets all nested types of the type that satisfy the binding flags. + + The binding flags. + The nested types. + + + + Gets all properties of the type that satisfy the binding flags. + + The binding flags. + The properties. + + + + Gets a property by name, or null if not found. + + The property name. + The binding flags. + The property. + + + + Gets all pseudo custom attributes associated with a member. + + The pseudo custom attributes. + + + + Gets all of the type's interfaces. + + The type's interfaces. + + + + Gets the type substitution for generic parameters. + + + + + A type substitution specifies how generic parameters are replaced by other types. + It is used by implementors of when returning + types that may be represented as generic parameters. + + + + + Applies a type substitution to the specified generic parameter. + + The generic parameter to substitute. + The substituted type. + Thrown if is null. + + + + Applies a type substitution to the specified type. + + The type to substitute. + The substituted type. + Thrown if is null. + + + + Applies a type substitution to the specified list of types. + + The types to substitute. + The substituted types. + Thrown if is null. + + + + Returns a new substitution formed by composing this substitution with the specified one. + That is to say, each replacement type in this substitution is replaced as described + in the specified substitution. + + The substitution to compose. + The new substitution. + + + + Returns true if this substitution does not contain any of the specified generic parameters. + + The generic parameters. + True if none of the generic parameters are in the substitution. + Thrown if is null. + + + + Gets the empty type substitution. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Returns a new substitution with the specified generic parameters replaced by their respective generic arguments. + + The generic parameters. + The generic arguments. + The resulting substitution. + Thrown if or is null + or contain nulls. + Thrown if does not have the same + number of elements as . + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Returns true if the type substitution does not contain any replacements. + + + + + Compares two static type substitutions for equality. + + The first substitution. + The second substitution. + True if the substitutions are equal. + + + + Compares two static type substitutions for inequality. + + The first substitution. + The second substitution. + True if the substitutions are equal. + + + + A type wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + The declaring type, or null if none. + Thrown if or is null. + + + + Applies a type substitution and returns the resulting type. + + The substitution. + The type after substitution has been performed. + + + + Gets the rank of the array type. + + Thrown if the type is not an array type. + + + + Gets the assembly in which the type is declared. + + + + + Gets the assembly-qualified name of the type, or null if the type is a generic parameter. + + + + + Gets the base type of the type, or null if none. + + + + + Internal implementation of . + + + + + Gets a for this code element. + + The code reference. + + + + Returns true if the type contains unbound generic parameters. + If so, the list will contain one + or more objects. + + + + + Gets the element type, or null if none. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Gets the full name of the type, or null if the type is a generic parameter. + + + + + Gets the generic arguments of the type. + The list may contain objects when + no type has yet been bound to a certain generic parameter slots. + + The generic arguments, or an empty list if there are none. + + + + Gets the generic type definition of this type, or null if the type is not generic. + + + + + Gets all constructors of the type that satisfy the binding flags. + + The binding flags. + The constructors. + + + + Gets a event by name, or null if not found. + + The event name. + The binding flags. + The event. + + + + Gets all events of the type that satisfy the binding flags. + + The binding flags. + The events. + + + + Gets a field by name, or null if not found. + + The field name. + The binding flags. + The property. + + + + Gets all fields of the type that satisfy the binding flags. + + The binding flags. + The fields. + + + + Gets an enumeration of elements from which this code element inherits. + + The inherited code elements. + + + + Gets a method by name, or null if not found. + + The method name. + The binding flags. + The method. + + + + Gets all methods of the type that satisfy the binding flags. + + The binding flags. + The methods. + + + + Gets a nested type by name, or null if not found. + + The nested type name. + The binding flags. + The nested type. + + + + Gets all nested types of the type that satisfy the binding flags. + + The binding flags. + The nested types. + + + + Gets all properties of the type that satisfy the binding flags. + + The binding flags. + The properties. + + + + Gets a property by name, or null if not found. + + The property name. + The binding flags. + The property. + + + + Gets all of the type's interfaces. + + The type's interfaces. + + + + Returns true if the type is abstract and must be overridden. + + + + + Returns true if the type represents an array. + + + + + Returns true if variables of this type can be assigned with values of the specified type. + + The other type, or null if none. + True if the other type is not null and this type is assignable from the other type. + + + + Returns true if the type represents a type that is passed by reference. + + + + + Returns true if the type is a class. + + + + + Returns true if the type represents an enumeration. + + + + + Returns true if the type represents a generic type parameter. + + + + + Returns true if the type is a generic type. + If so, the list will be non-empty. + + + + + Returns true if the type is a generic type definition. + + + + + Returns true if the type is an interface. + + + + + Returns true if the type is nested. + + + + + Returns true if the type is nested and is visible only within its own assembly. + + + + + Returns true if the type is nested and visible only within its own family. + + + + + Returns true if the type is nested and visible only to classes that belong to both its own family and its own assembly. + + + + + Returns true if the type is nested and visible only to classes that belong to either its own family or to its own assembly. + + + + + Returns true if the type is nested and declared private. + + + + + Returns true if the type is nested and declared public. + + + + + Returns true if the type is not declared public. + + + + + Returns true if the type represents a pointer. + + + + + Returns true if the type is declared public. + + + + + Returns true if the type is sealed. + + + + + Returns true if this type is a subclass of the specified type. + + The other type, or null if none. + True if the other type is not null, this type is a subclass of the other type, + and this type not the same as the other type. + + + + Returns true if the type is a value type. + + + + + Gets the kind of code element represented by this instance. + + + + + Makes an array type of the specified rank. + + The array rank. + The array type. + + + + Makes a reference type. + + The reference type. + + + + Makes a generic type instantiation. + + The generic arguments. + The generic type instantiation. + + + + Makes a pointer type. + + The pointer type. + + + + Gets the namespace in which the type is declared. + + + + + Gets the name of the namespace in which the type is declared. + + + + + Resolves the wrapper to its native reflection target. + + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Resolves the wrapper to its native reflection target within the scope + of the specified method. + + The method that is currently in scope, or null if none. + This parameter is used when resolving types that are part of the signature + of a generic method so that generic method arguments can be handled correctly. + If true, throws an exception if the target could + not be resolved, otherwise returns a reflection object that represents an + unresolved member which may only support a subset of the usual operations. + The native reflection target. + Thrown if the target cannot be resolved. + + + + Implementation of + + + + Gets the type attributes. + + + + + Gets the type's . + + + + + A wrapper. + + + + + Creates a wrapper. + + The reflection policy. + The underlying reflection object. + Thrown if or is null. + + + + + + Compares the policy and handle of this wrapper with those of another + using . + + The other wrapper. + + + + + Gets the underlying reflection object. + + + + + Gets the reflection policy. + + + + + Creates instances of unresolved reflection objects based on wrappers. + + + + + Creates an instance of the factory. + + + + + Gets the singleton instance of the factory. + + + + + Creates an wrapper for . + + The adapter. + The unresolved assembly. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved constructor. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved event. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved field. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved method. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved parameter. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved property. + Thrown if is null. + + + + Creates a wrapper for . + + The adapter. + The unresolved type. + Thrown if is null. + + + + Helpers for working with . + + + + + Gets the XML documentation id of a member. + + The member. + The XML documentation id of the member. + Thrown if is null. + + + + Gets the XML documentation for a member. + + The member. + The XML documentation for the member, or null if none available. + Thrown if is null. + + + + Gets the XML documentation resolver. + + + + + Abstract base class for channels implemented using the .Net remoting infrastructure. + + + + + Creates a channel. + + The .Net remoting channel. + The root Uri associated with the channel. + Thrown if or is null. + + + + Gets the associated .Net remoting channel. + + + + + Gets the root Uri associated with the channel. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the channel. + + True if was called directly. + + + + Gets the Uri of a service with the given name that can be accessed using this channel. + + The service name. + The service uri. + Thrown if is null. + + + + Abstract base class for client channels implemented using the .Net + remoting infrastructure. + + + + + Creates a channel. + + The .Net remoting channel. + The root Uri associated with the channel. + Thrown if or is null. + + + + Gets a well-known remote service with the specified name. + + The type of the service. + The name of the service. + The component or a proxy that provides the service. + Thrown if + or is null. + + + + Abstract base class for client channels implemented using the .Net + remoting infrastructure. + + + + + Creates a channel. + + The .Net remoting channel. + The root Uri associated with the channel. + Thrown if or is null. + + + + Disposes the channel. + + True if was called directly. + + + + Registers a well-known service with the specified name. + + The name of the service. + The component that provides the service. + Thrown if or + is null. + + + + A client channel based on an that uses a + . + + + + + Creates a channel. + + The ipc port name to connect to. + Thrown if is null. + + + + A server channel based on an that uses a + . + + + + + Creates a channel. + + The ipc port name to register. + Thrown if is null. + + + + A client channel based on an that uses a + . + + + + + Creates a channel. + + The host name to connect to. + The port number to connect to. + The request timeout or null if none. + Thrown if is null. + + + + A server channel based on an that uses a + . + + + + + Creates a channel. + + The remotely accessed hostname. + The port number. + Thrown if is null. + + + + A client channel manages the client side of a remoting channel. + + + + + Gets a well-known remote service with the specified name. + + The type of the service. + The name of the service. + The component or a proxy that provides the service. + Thrown if + or is null. + + + + A server channel manages the server side of a remoting channel. + + + + + Registers a well-known service with the specified name. + + The name of the service. + The component that provides the service. + Thrown if or + is null. + + + + Base class for long-lived marshal by ref objects. + + + + Initializes a new instance of the class + + + + Obtains a lifetime service object to control the lifetime policy for this instance. + + + An object of type used to control the lifetime policy for this instance. This is the current lifetime service object for this instance if one exists; otherwise, a new lifetime service object initialized to the value of the property. + + + The immediate caller does not have infrastructure permission. + + + + + Impersonate a user according to the specified credentials. + + + + + Starts the impersonation process. + + The name of the user to impersonate. + The domain where the user is defined. + The password. + Thrown if , , + or is null. + Thrown when the impersonation process has failed. + + + + Stops the impersonation process. + + + + + An exception that expresses a problem while trying to impersonata user account. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Describes the difference between a range of the left document and a range of the right document. + + + + + Creates a diff. + + The diff kind which indicates whether there is a change over the range covered by the diff. + The range of the left document that is affected. + The range of the right document that is affected. + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Gets the diff kind which indicateds whether there is a change over the range covered by the diff. + + + + + Gets the range of the left document that is affected. + + + + + Returns true if two diffs are equal. + + The first diff to compare. + The second diff to compare. + True if the diffs are equal. + + + + Returns true if two diffs are not equal. + + The first diff to compare. + The second diff to compare. + True if the diffs are not equal. + + + + Gets the range of the right document that is affected. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Describes whether a difference represents a changed or unchanged region. + + + + + Indicates there is no change between the left and right documents over the ranges described by the diff. + + + + + Indicates there is a change between the left and right documents over the ranges described by the diff. + Text may have been added, removed, or edited. + + + + + A diff set consists of a sequence of differences between a left document and a right document + that indicate changed and unchanged regions. + + + + + Constructs a diff set. + + The list of differences that indicate the changed and + unchanged regions between the left and right documents. The diffs span + the entire range of the left and right documents and are listed in document order. + The left document. + The right document. + Thrown if , + or is null. + Thrown if does not + completely cover the left and right documents or are not listed in the correct order. + + + + Returns true if the list of differences contains changed regions. + + + + + Gets the list of differences that indicate the changed and + unchanged regions between the left and right documents. + + + + + Gets the set of differences between a left document and a right document. + + The left document. + The right document. + The set of differences. + Thrown if or + is null. + + + + Returns true if the list of differences is empty which can only occur when + both document being compared are empty. + + + + + Gets the left document. + + + + + Gets the right document. + + + + + Simplifies the diff for presentation. + + Returns a simplified diff. + + + + Writes the diffs using the + presentation style and no limits on the context length. + + The test log stream writer to receive the highlighted document. + Thrown if if null. + + + + Writes the diffs using the specified + presentation style and no limits on the context length. + + The test log stream writer to receive the highlighted document. + The presentation style. + Thrown if if null. + + + + Writes the diffs using the specified presentation style and max context length. + + The test log stream writer to receive the highlighted document. + The presentation style. + The maximum number of characters of unchanged regions + to display for context, or for no limit. Extraneous context + is split in two with an ellipsis inserted in between both halves. + Thrown if if null. + Thrown if + is negative. + + + + Specifies the presentation style for a . + + + + + Display the left and right document contents and diffs fully interleaved. + + + + + Display only the left document contents. + + + + + Display only the right document contents. + + + + + A range denotes a segment of a string or other indexed data structure. + + + + + Creates a range of indices. + + The starting index of the range. + The number of characters within the range, may be 0. + Thrown if + or is negative. + + + + Creates a new range between the start index (inclusively) and end index (exclusively). + + The start index. + The end index. + The new range. + Thrown if + is negative or greater than . + + + + Gets the ending index of the range, which is the start index plus the length. + The ending index is one past the last character within the range. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Extends a range into an adjacent range and returns the combined range. + + The adjacent range. + The extended range. + Thrown if is not an adjacent range. + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Gets the length of the range. + + + + + Returns true if two ranges are equal. + + The first range to compare. + The second range to compare. + True if the ranges are equal. + + + + Returns true if two ranges are not equal. + + The first range to compare. + The second range to compare. + True if the ranges are not equal. + + + + Gets the starting index of the range. + + + + + Gets a substring of the specified text using this range. + + The source text. + The substring of the source text that represents this range. + Thrown if is null. + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Provides utility functions for working with strings. + + + + + Parses a string of whitespace delimited and possibly quoted arguments and + returns an array of each one unquoted. + + The arguments string, eg. "/foo 'quoted arg' /bar. + The parsed and unquoted arguments. + Thrown if is null. + + + + Parses a key/value pair from an input string of the form "key=value", with the + value optionally quoted and optional surrounding whitespace removed. + + The input string. + The key value pair. + Thrown if is null. + + + + Formats a character value as "'x'" or "'\n'" with support for escaped characters + as a valid literal value. Encloses the char in single quotes ('). + + The character value to format. + The formatted character. + + + + Gets a lowercase hexadecimal digit corresponding to the least significant nybble of + the specified value. + + The value, only the last 4 bits of which are used. + The hexadecimal digit. + + + + Formats a string value as ""abc\ndef"" with support for escaped characters + as a valid literal value. Encloses the string in quotes ("). + + The string value to format. + The formatted string. + + + + Escapes a character value as "x" or "\n". Unlike , + does not enclose the literal in single quotes ('). + + The character value to format. + The unquoted char literal. + + + + Escapes a string value such as "abc\ndef". Unlike , + does not enclose the literal in quotes ("). + + The string value to format. + The unquoted string literal. + + + + Truncates the string to the specified maximum length. + Discards characters at the end of the string with indices greater than + or equal to . + + The string to truncate. + The maximum length of the string to retain. + The truncated string. + Thrown if is null. + Thrown if is negative. + + + + If the string is longer than the specified maximum length, truncates + it and appends an ellipsis mark ("..."). If the maximum length is + less than or equal to 3, omits the ellipsis mark on truncation. + + The string to truncate. + The maximum length of the string to retain + including the ellipsis mark when used. + The truncated string. + Thrown if is null. + Thrown if is negative. + + + + A substring provides a convenient representation for a range within a larger string. + + + + + Creates a substring object defined over the entire range of a string. + + The string. + Thrown if is null. + + + + Creates a substring object. + + The string. + The range within the string. + Thrown if is null. + Thrown if is outside the bounds of the string. + + + + Returns the whole string. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Returns a substring of the substring. + + The index at which to start. + The substring. + Thrown if is negative or + if is greater than . + + + + Returns a substring of the substring. + + The index at which to start. + The length of the substring to produce. + The substring. + Thrown if or + are negative or if their sum is greater than . + + + + Finds the length of the common prefix of this substring and another one. + + The other substring. + The common prefix length, or 0 if the substrings have no prefix in common. + + + + Finds the length of the common suffix of this substring and another one. + + The other substring. + The common suffix length, or 0 if the substrings have no suffix in common. + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Gets the character with a particular index. + + The index. + The character. + Thrown if the index is out of range. + + + + Gets the length of the substring. + + + + + Returns true if two substrings are equal. + + The first substring to compare. + The second substring to compare. + True if the substrings are equal. + + + + Returns true if two substrings are not equal. + + The first substring to compare. + The second substring to compare. + True if the substrings are not equal. + + + + Returns the range of the underlying string represented by the substring. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Interface for a regular expression composite tree leaf. + + + + + Returns a random string that matches the regular expression element. + + A random string. + + + + A lightweight simplified regular expression pattern. + + + + + Constructs a simplified regular expression pattern. + + The input pattern. + Thrown if is null. + Thrown if is invalid. + + + + Returns the random string that matches the regular expression pattern. + + A random string that matches the regular expression pattern. + + + + This exception type is used to signal an error while parsing + a simplified regular expression with the RegexLite parser. + + + + + Creates a exception. + + + + + Creates a exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates a exception with the specified message.. + + The message, or null if none. + + + + Creates a exception with the specified message and the inner exception. + + The message, or null if none. + The inner exception, or null if none. + + + + Utility class for absolute and relative time management. + + + + Initializes a new instance of the class + + + + Gets the time elapsed. + + + + + Returns the local date and time. + + + + + Resets the time and starts the clock. + + + + + Stops the clock. + + + + + Blocks the current thread for a specified time. + + The amount of time for which the thread is blocked. + + + + Blocks the current thread for a specified time. + + The amount of time for which the thread is blocked. + + + + Returns the current date and time, expressed as the Coordinated Universal Time (UTC). + + + + + Utility class for absolute and relative time management. + + + + + Gets the time elapsed. + + + + + Returns the local date and time. + + + + + Resets the time and starts the clock. + + + + + Stops the clock. + + + + + Blocks the current thread for a specified time. + + The amount of time for which the thread is blocked. + + + + Blocks the current thread for a specified time. + + The amount of time for which the thread is blocked. + + + + Returns the current date and time, expressed as the Coordinated Universal Time (UTC). + + + + + Provides a method that may be called by client code to validate that the content + of an object is well-formed. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + An exception that expresses a data validation error. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Validation utilities. + + + + + Validates all non-null items of an enumeration of validatable elements. + + The items to validate. + The item type. + Thrown if the validation fails. + + + + Validates that an item is a valid assembly name. + + The name of the item. + The value to validate. + + + + Validates that all items in a collection are not null. + + The name of the collection. + The collection to validate. + The item type. + Thrown if the validation fails. + + + + Validates that an item is not null. + + The name of the item. + The item to validate. + The item type. + + + + Default IXmlSerializer implementation. + + + + Initializes a new instance of the class + + + + + Saves an object graph to a pretty-printed Xml file using . + + The root object. + The filename. + The root object type. + Thrown if + or is null. + + + + Provides Xml serialization and deserialization services. + + + + + Loads an object graph from an Xml file using . + + The filename. + The root object type. + The root object. + Thrown if is null. + + + + Saves an object graph to a pretty-printed Xml file using . + + The root object. + The filename. + The root object type. + Thrown if + or is null. + + + + Preprocesses XML based on the presence of processing instructions. + + + + + Creates an Xml preprocessor. + + + + + Defines a preprocessor constant. + + The constant. + Thrown if + is null. + + + + Returns true if the specified preprocessor constant is defined. + + The constant. + True if the constant is defined. + Thrown if + is null. + + + + Preprocesses and copies an Xml document from a reader into a writer. + + The Xml reader. + The Xml writer. + Thrown if + or is null. + Thrown if the input Xml is malformed + such as if it contains unbalanced ifdef/endif pairs. + + + + Provides utilities for manipulating Xml. + + + + + Produces an XPathDocument given an action applied to an XmlWriter. + + The action to perform. + The XPathDocument. + Thrown if is null. + + + + Captures screenshot images and videos. + + + + + Adds an overlay to display over screenshot images and videos. + + The overlay to add. + Thrown if is null. + + + + Automatically embeds a video of the test run from this point forward when a trigger event occurs. + + The trigger event. + The name to give the video attachment, or null to assign one automatically. + + + + Automatically embeds a video of the test run from this point forward when a trigger event occurs. + + The trigger event. + The name to give the video attachment, or null to assign one automatically. + The capture parameters. + The number of frames per second to capture. + Thrown if is null. + + + + Automatically embeds a screenshot when a trigger event occurs. + + The trigger event. + The name to give the image attachment, or null to assign one automatically. + + + + Automatically embeds a screenshot when a trigger event occurs. + + The trigger event. + The name to give the image attachment, or null to assign one automatically. + The capture parameters. + Thrown if is null. + + + + Returns true if screenshots can be captured. + + True if the screen can be captured. + + + + Gets the caption overlay to display over of screenshots images and videos. + + The caption overlay. + + + + Gets the overlay manager for the current test context. + + The overlay manager. + + + + Gets the overlay manager for the specified test context. + + The test context. + The overlay manager. + Thrown if is null. + + + + Gets the size of the screen. + + The screen size. + + + + Captures an image of the entire desktop. + + The screenshot. + Thrown if a screenshot cannot be captured at this time. + + + + Captures an image of the entire desktop. + + The capture parameters. + The screenshot. + Thrown if is null. + Thrown if a screenshot cannot be captured at this time. + + + + Sets a caption to display over screenshots images and videos. + + The caption text, an empty string to remove it. + Thrown if is null. + + + + Sets the alignment of the caption to display over screenshots images and videos. + + The horizontal alignment. + The vertical alignment. + + + + Sets the font size of the caption to display over screenshots images and videos. + + The caption font size. + Thrown if is less than 1. + + + + Starts recording a screen capture video of the entire desktop. + + The recorder. + Thrown if a screenshot cannot be captured at this time. + + + + Starts recording a screen capture video of the entire desktop. + + The capture parameters. + The number of frames per second to capture. + The recorder. + Thrown if is null. + Thrown if a screenshot cannot be captured at this time. + + + + Describes the semantics of how objects should be compared. + + + + + Returns true if two values are equal to within a specified delta. + + The expected value. + The actual value. + The inclusive delta between the values. + The type of values to be compared. + The type of the difference produced when the values are + subtracted, for numeric types this is the same as but it + may differ for other types. + True if the values are approximately equal. + + + + Compares two objects. + + The left object, may be null. + The right object, may be null. + The object type. + A value less than zero if the left object if less than + the right object, zero if the left and right objects are equal, or greater than zero if + the left object is greater than the right object. + Thrown if the values cannot be ordered. + + + + Returns true if two objects are equal. + + The left object, may be null. + The right object, may be null. + True if the objects are equal. + + + + Returns true if two objects are equal. + + The left object, may be null. + The right object, may be null. + The object type. + True if the objects are equal. + + + + Returns true if the specified type is a simple enumerable type. + + The object type. + Thrown if is null. + + + + Returns true if two objects are the same. + + The left object, may be null. + The right object, may be null. + The object type, which must be a reference type (class) since a value type + (struct) has no concept of referential identity. + True if both objects are the same. + + + + The diagnostic log provides services for writing diagnostic messages to the console + or runtime log during a test run. + + + + + Writes a message to the diagnostic log. + + The message to write, may be null. + + + + Writes a formatted message to the diagnostic log. + + The message format string, may be null. + The message arguments. + + + + A sandbox is an isolated environments for executing test actions. + + + + + Creates a root sandbox. + + + + + Aborts all actions in progress within this context. + + The outcome to be returned from aborted actions. + A message to be logged when the action is aborted, or null if none. + Thrown if the sandbox was disposed. + + + + An event that is dispatched when is called. + + Thrown if the sandbox was disposed. + + + + Gets a message that will be logged when the sandbox is aborted, or null if none. + + Thrown if the sandbox was disposed. + + + + Returns the passed to , + or null if has not been called. + + Thrown if the sandbox was disposed. + + + + Creates a child sandbox. + + The child sandbox. + Thrown if the sandbox was disposed. + + + + Disposes the sandbox. + + + + + Runs an action inside of a protected context wherein it cannot receive + a thread abort from this . + + An object that when disposed ends the protected block, possibly null if there was no protection necessary. + + + + Runs a test action. + + The log writer for reporting failures. + The action to run. + A description of the action being performed, + to be used as a log section name when reporting failures, or null if none. + The outcome of the action. + Thrown if or is null. + Thrown if the sandbox was disposed. + + + + Uses a specified timeout for all actions run within a block of code. + When the timeout expires, the sandbox will be aborted. + + The execution timeout or null if none. + An object that when disposed ends the timeout block, possibly null if there was no timeout. + Thrown if the sandbox was disposed. + Thrown if is negative. + + + + Returns true if was called. + + Thrown if the sandbox was disposed. + + + + This exception type is used to signal a test outcome silently without logging the exception. + + + + + Creates a silent test exception with the specified outcome. + + The test outcome. + + + + Creates a silent test exception with the specified outcome. + + The test outcome. + The message, or null if none. + + + + Creates a exception from serialization info. + + The serialization info. + The streaming context. + + + + Returns true if the outcome and message (if any) should be used but the exception + stack trace should not be logged. + + + + + The tasks class provides a mechanism for coordinating the actions of multiple + tasks within a test case. + + + + + Creates a new process task but does not start it. + + The path of the executable executable. + The arguments for the executable. + The working directory. + The new thread task. + Thrown if , + or is null. + + + + Creates a new thread task but does not start it. + + The name of the task, or null to create a new name based + on the method associated with the action. + The action to perform. + The new thread task. + Thrown if is null. + + + + Waits for all tasks to complete or for timeout to occur; + then verifies that no failures have occurred in any of the tasks. + + The timeout. + Thrown if some of the tasks did not complete + or if any of the tasks failed. + + + + Starts a new process and begins watching it. + + The path of the executable executable. + The arguments for the executable. + The working directory. + The new thread task. + Thrown if , + or is null. + + + + Starts a new thread task. + + The name of the task, or null to create a new name based + on the method associated with the action. + The action to perform. + The new thread task. + Thrown if is null. + + + + Gets the task container for the current . + + + + + Verifies that no failures have occurred in any of the tasks. + + Thrown if any of the tasks failed. + + + + Adds a new task for the task manager to watch. + + The task to watch. + Thrown if is null. + + + + The test context provides information about the environment in which + a test is executing. A new context is created each time a test or + test step begins execution. + + + + + Adds the specified amount to the assert count atomically. + + The amount to add to the assert count. + + + + Adds metadata to the step that is running in the context. + + The metadata key. + The metadata value. + Thrown if + or is null. + + + + Gets the current assertion count. + + + + + Automatically executes an action when a triggering event occurs. + + The triggering event. + The action to execute when triggered. + Thrown if is null. + + + + Automatically executes an action when a triggering event occurs. + + The triggering event. + The action to execute when triggered. + The action to execute to clean up after triggering or when the test finishes without triggering having occurred, or null if none. + Thrown if is null. + + + + Gets the context of the current thread, or null if there is no + current context. + + + + + Gets the user data collection associated with the context. It may be used + to associate arbitrary key/value pairs with the context. + + + + + Enters this context with the current thread. + + A cookie that can be used to restore the current thread's context to its previous value. + + + + Enters the specified context with the current thread. + + The context to enter, or null to enter a scope + without a context. + A cookie that can be used to restore the current thread's context to its previous value. + + + + The event is raised when the test is finishing to provide + clients with an opportunity to perform additional clean up tasks after all ordinary + test processing is finished. + + + + + Gets the default context for the specified thread. + + The thread. + The default context. + Thrown if is null. + + + + Gets the global context of the environment, or null if there is no + such context. + + + + + Increments the assert count atomically. + + + + + Returns true if the step associated with the context has finished execution + and completed all actions. + + + + + Returns true if a trigger event has been satisfied. + + The trigger event. + True if the trigger event is satisfied. + + + + Gets or sets the lifecycle phase the context is in. + + Thrown if is null. + + + + Gets the log writer for this context. + + + + + Gets the step's outcome or its interim outcome if the test is still running. + + + + + Gets the parent context or null if this context has no parent. + + + + + Gets a copy of the step's final result or null if the test has not finished yet. + + + + + Performs an action as a new step within the current context and associates it + with the specified code reference. Does not verify the outcome of the step. + + The name of the step. + The action to perform. + The step execution timeout, or null if none. + True if the step represents an independent test case. + The associated code element, or null if none. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if is negative. + + + + Performs an action as a new step within the current context and associates it + with the specified code reference. Verifies that the step produced the expected outcome. + + The name of the step. + The action to perform. + The step execution timeout, or null if none. + True if the step represents an independent test case. + The associated code element, or null if none. + The expected outcome of the step. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if is negative. + Thrown if the expected outcome was not obtained. + + + + Gets the sandbox of the test step, or null if none. + + + + + Sets the step's interim . + + Thrown if attempting to set the outcome while the test is not running. + + + + Sets the default context for the specified thread. + + The thread. + The context to associate with the thread, or null to reset the + thread's default context to inherit the once again. + Thrown if is null. + + + + Gets the test associated with the context. + + + + + Gets the test step associated with the context. + + + + + A context cookie is used to unwind the context stack of the current thread + to its previous state prior to a context having been entered. + + + + + Exits the context that was entered when the cookie was granted. + + Thrown if the cookie belongs to a different + or if the context was already exited. + Thrown if the context manager has been disposed. + + + + Exits the context that was entered when the cookie was granted. + + Thrown if the cookie belongs to a different + or if the context was already exited. + Thrown if the context manager has been disposed. + + + + This exception type is an abstract base class for exceptions that are used to + explicitly signal the outcome of a test. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Returns true if the outcome and message (if any) should be used but the exception + stack trace should not be logged. + + + + + When overridden in a derived class, sets the with information about the exception. + + + The that holds the serialized object data about the exception being thrown. + + + The that contains contextual information about the source or destination. + + + The parameter is a null reference (Nothing in Visual Basic). + + + The caller does not have the required permission. + + + + + Returns true if the test exception has a non-default message + + + + + Gets the outcome of the test. + + + + + This exception type is used to signal that a test has failed to satisfy + some predetermined condition established by the test author. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Returns . + + + + + This exception type is used to signal that a test has not produced a conclusive + pass or fail result. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Returns . + + + + + The test log class provides services for writing information to the + execution log associated with a test. + + + + + Attaches an attachment to the execution log. + + The attachment to include. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an HTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The HTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an image attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The image to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XML-serialized object as an XML attachment with mime-type + using the default for the object's type. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The object to serialize and embed, must not be null. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XML-serialized object as an XML attachment with mime-type + using the specified . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The object to serialize and embed, must not be null. + The to use, or null to use the default + for the object's type. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an plain text attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The text to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches a video attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The video to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XHTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The XHTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Attaches an XML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The XML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Begins a marked region. May be nested. + + The marker. + A Disposable object that calls when disposed. This + is a convenience for use with the C# "using" statement. + + + + Begins a section with the specified name. May be nested. + + The name of the section. + A Disposable object that calls when disposed. This + is a convenience for use with the C# "using" statement. + Thrown if is null. + + + + Gets the current stream writer for captured messages. + + + + + Gets the current stream writer for captured messages. + + + + + Gets the current stream writer for captured messages. + + + + + Gets the current stream writer for diagnostic and messages. + + + + + Gets the current stream writer for generic log messages such as those written + using the static methods of this class. + + + + + Embeds an attachment. + + The attachment to embed. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds another copy of an existing attachment. + + The name of the existing attachment to embed. + Thrown if is null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Embeds an HTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The HTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an image attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The image to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XML-serialized object as an XML attachment with mime-type + using the default for the object's type. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The object to serialize and embed, must not be null. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XML-serialized object as an XML attachment with mime-type + using the specified . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The object to serialize and embed, must not be null. + The to use, or null to use the default + for the object's type. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an plain text attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The text to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds a video attachment with a mime-type compatible with its internal representation. + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The video to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XHTML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The XHTML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Embeds an XML attachment with mime-type . + + The name of the attachment to create or null to + automatically assign one. The attachment name must be unique within the scope of the + currently executing test step. + The XML to attach. + The attachment. + Thrown if is null. + Thrown if there is already an attachment + with the same name. + + + + Ends the region most recently started with one of the Begin* methods. + + Thrown if there is no current nested region. + + + + Gets the current stream writer for reporting failure messages and exceptions. + + + + + Flushes the log writer. + + + + + Gets the current stream writer for reporting warning messages. + + + + + Writes a test log stream writable object to the stream. + + The object to write, or null if none. + + + + Writes a character. + + The character value. + + + + Writes an array of characters. + + The array of characters. + + + + Writes an array of characters. + + The character buffer. + The index of the first character in the buffer to write. + The number of characters from the buffer to write. + Thrown if is null. + Thrown if or are out of range. + + + + Writes a formatted object. + + The object value. + + + + Writes a string. + + The string value. + + + + Writes a formatted string. + + The format string. + The format string arguments. + Thrown if is null. + + + + Writes an ellipsis to indicate where content has been elided for brevity. + + + + + Writes an exception. + + The exception data to write. + Thrown if is null. + + + + Writes an exception within its own section which provides additional cues for interpretation. + + The exception data to write. + The section name, or null if none. + Thrown if is null. + + + + Writes an exception. + + The exception to write. + Thrown if is null. + + + + Writes an exception within its own section. + + The exception to write. + The section name, or null if none. + Thrown if , + or is null. + + + + Writes highlighted text. + + The text to write, or null if none. + + + + Writes a line delimiter. + + + + + Writes a character followed by a line delimiter. + + The character value. + + + + Writes an array of characters followed by a line delimiter. + + The array of characters. + + + + Writes a formatted object followed by a line delimiter. + + The object value. + + + + Writes a string followed by a line delimiter. + + The string value. + + + + Writes a formatted string followed by a line delimiter. + + The format string. + The format string arguments. + Thrown if is null. + + + + Gets the current log writer. + + The execution log, never null. + Thrown if there is no current log writer. + + + + Provides functions for manipulating test steps. + + + + + Adds metadata to the step that is running in the context. + + The metadata key. + The metadata value. + Thrown if + or is null. + Thrown if there is no current test context. + + + + Gets reflection information about the current step. + + Thrown if there is no current test context. + + + + Performs an action as a new step within the current context and associates + it with the calling function. Does not verify the outcome of the step. + + The name of the step. + The action to perform. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if there is no current test context. + + + + Performs an action as a new step within the current context and associates + it with the calling function. Does not verify the outcome of the step. + + The name of the step. + The action to perform. + The step execution timeout, or null if none. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if is negative. + Thrown if there is no current test context. + + + + Performs an action as a new step within the current context and associates it + with the specified code reference. Does not verify the outcome of the step. + + The name of the step. + The action to perform. + The step execution timeout, or null if none. + True if the step represents an independent test case. + The associated code element, or null if none. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if is negative. + Thrown if there is no current test context. + + + + Performs an action as a new step within the current context and associates + it with the calling function. Verifies that the step produced the expected outcome. + + The name of the step. + The action to perform. + The expected outcome of the step. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if the expected outcome was not obtained. + Thrown if there is no current test context. + + + + Performs an action as a new step within the current context and associates + it with the calling function. Verifies that the step produced the expected outcome. + + The name of the step. + The action to perform. + The step execution timeout, or null if none. + The expected outcome of the step. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if is negative. + Thrown if the expected outcome was not obtained. + Thrown if there is no current test context. + + + + Performs an action as a new step within the current context and associates it + with the specified code reference. Verifies that the step produced the expected outcome. + + The name of the step. + The action to perform. + The step execution timeout, or null if none. + True if the step represents an independent test case. + The associated code element, or null if none. + The expected outcome of the step. + The context of the step that ran. + Thrown if or + is null. + Thrown if is the empty string. + Thrown if is negative. + Thrown if the expected outcome was not obtained. + Thrown if there is no current test context. + + + + This exception type is used to signal that a test has been terminated with + a particular outcome. + + + + + Creates a silent test exception with the specified outcome. + + The test outcome. + + + + Creates a silent test exception with the specified outcome. + + The test outcome. + The message, or null if none. + + + + Creates an exception. + + The test outcome. + The message, or null if none. + The inner exception, or null if none. + + + + Creates a exception from serialization info. + + The serialization info. + The streaming context. + + + + When overridden in a derived class, sets the with information about the exception. + + + The that holds the serialized object data about the exception being thrown. + + + The that contains contextual information about the source or destination. + + + The parameter is a null reference (Nothing in Visual Basic). + + + The caller does not have the required permission. + + + + + Gets the outcome of the test. + + + + + Specifies a trigger condition for automatic execution of an action. + + + + + Never performs the action. + + + + + Perform the action when the test finishes. + + + + + Perform the action when the test passed. + + + + + Perform the action when the test passed or was inconclusive. + + + + + Perform the action when the test was inconclusive. + + + + + Perform the action when the test failed. + + + + + Perform the action when the test failed or was inconclusive. + + + + + Describes the context in which an assertion is being evaluated. + + + + + Gets the current assertion failure behavior. + + + + + Performs an action and returns an array containing the assertion failures + that were observed within the block. + + The action to invoke. + The assertion failure behavior to use while + executing the block. + Specifies whether to represent an exception + as an assertion failure, otherwise it is rethrown. + The array of failures, may be empty if none. + Thrown if is null. + + + + Gets the current assertion context, or null if there is no current context. + + + + + Gets the pending failures within the current assertion scope. + + The pending failures, or an empty array if none. + + + + Submits an assertion failure. + + The assertion failure. + Thrown if + is null. + + + + Gets the associated test context. + + + + + The exception type used by the Gallio assertion framework to signal assertion failures. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + An assertion failure is an immutable description of a failed assertion and its + cause. It takes into account information about labeled values such as the expected + and actual value. + + + + + Creates an assertion failure object. + + + + + Gets the description of the assertion failure. + + + + + Gets information about the exceptions. + + + + + Gets the nested assertion failures that contributed to the composite assertion + failure described by this instance. + + + + + Gets formatted representations of labeled values as key/value pairs. + + + + + Gets the maximum length of formatted value that can be presented before truncation occurs. + + + + + Gets the maximum length of label that can be presented before truncation occurs. + + + + + Gets the user-supplied message about the assertion failure, + or null if none. + + + + + Get the stack track of the failure, or null if none. + + + + + Formats the failure as a string. + + The formatted string. + + + + Writes the details about the assertion failure to the structured text writer. + + The structured text writer, not null. + + + + Writes the assertion failure to a test log stream. + + The test log stream. + Thrown if is null. + + + + A labeled value describes a named assertion parameter. + + + + + Creates a labeled value with structured text. + + The label. + The formatted value as structured text. + Thrown if or + is null. + Thrown if is empty. + + + + Creates a labeled value with plain text. + + The label. + The formatted value as plain text. + Thrown if or + is null. + Thrown if is empty. + + + + Gets the formatted value as structured text. + + + + + Gets the label. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + Specifies the behavior that should take place when a + is submitted to the . + + + + + When an assertion failure is reported, capture it in a list, log it, and allow + the computation to continue. + + + + + When an assertion failure is reported, capture it in a list, then throw an + to immediately abort the current computation. + + + + + When an assertion failure is reported, capture it in a list, log it, then throw an + to immediately abort the current computation. + + + + + When an assertion failure is reported, discard it (instead of capturing it in a list) + and allow the current computation to continue. + + + + + When an assertion failure is reported, capture it in a list and allow the current + computation to continue. + + + + + An assertion failure builder is used to construct a complete description + of an assertion failure that has occurred. It takes into account information about + the expected and actual value, as well as additional labeled values and exceptions. + + + + + Creates an assertion failure builder with the default formatter. + + The description of the failure. + Thrown if + is null. + + + + Creates an assertion failure builder with the specified formatter. + + The description of the failure. + The formatter to use. + Thrown if or + is null. + + + + Adds an exception to the assertion failure. + + The exception data to add. + The builder, to allow for fluent method chaining. + Thrown if is null. + + + + Adds an exception to the assertion failure. + + The exception to add. + The builder, to allow for fluent method chaining. + Thrown if is null. + + + + Adds a nested assertion failure that contributed to the composite assertion failure + described by this instance. + + The inner assertion failure to add. + The builder, to allow for fluent method chaining. + Thrown if is null. + + + + Adds an enumeration of nested assertion failures that contributed to the composite + assertion failure described by this instance. + + The enumeration of inner assertion failures to add. + The builder, to allow for fluent method chaining. + Thrown if is null or + contains a null. + + + + Adds a labeled value. + + The labeled value. + The builder, to allow for fluent method chaining. + + + + Adds a labeled value as structured text. + + The label. + The formatted value as structured text. + The builder, to allow for fluent method chaining. + Thrown if or is null. + Thrown if is empty. + + + + Adds a labeled value as plain text. + + The label. + The formatted value. + The builder, to allow for fluent method chaining. + Thrown if or is null. + Thrown if is empty. + + + + Adds the raw actual value to be formatted using . + + The actual value. + The builder, to allow for fluent method chaining. + + + + Adds the raw expected and actual values to be formatted using + and includes formatting of their differences. + + The expected value. + The actual value. + The builder, to allow for fluent method chaining. + + + + Adds the raw expected value to be formatted using . + + The expected value. + The builder, to allow for fluent method chaining. + + + + Adds a raw labeled value to be formatted using . + + The label. + The raw unformatted value. + The builder, to allow for fluent method chaining. + Thrown if is null. + Thrown if is empty. + + + + Adds two raw labeled values formatted using and includes + formatting of their differences. + + The left label. + The left value. + The right label. + The right value. + The builder, to allow for fluent method chaining. + Thrown if or + is null. + + + + Creates an assertion failure object. + + + + + Gets the formatted used by the builder. + + + + + Sets the user-supplied assertion failure message. + + The user-supplied assertion failure message, or null if none. + The builder, to allow for fluent method chaining. + + + + Sets the user-supplied assertion failure message to a formatted value. + + The user-supplied assertion failure message format + string, or null if none. + The format arguments, or null or empty if none. + The builder, to allow for fluent method chaining. + + + + Sets the stack trace. + + The stack trace, or null if none. + The builder, to allow for fluent method chaining. + + + + Generates an immutable object that describes the failure. + + The assertion failure. + + + + An exception type that wraps a . + + + + + Creates an exception for a given assertion failure. + + The assertion failure. + True if the assertion failure exception should not be logged because + the information it contains has already been conveyed to the user. + Thrown if is null. + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Returns true if the outcome and message (if any) should be used but the exception + stack trace should not be logged. + + + + + Gets the associated assertion failure, never null. + + + + + When overridden in a derived class, sets the with information about the exception. + + + The that holds the serialized object data about the exception being thrown. + + + The that contains contextual information about the source or destination. + + + The parameter is a null reference (Nothing in Visual Basic). + + + The caller does not have the required permission. + + + + + Returns true if the assertion failure exception should not be logged because + the information it contains has already been conveyed to the user. + + + + + Gets a message that describes the current exception. + + + The error message that explains the reason for the exception, or an empty string(""). + + + + + A delegate for the decorator method which + combines the specified inner failures into a single outer failure with a common explanation. + + The inner failures to combine together. + The composite assertion failure. + + + + Provides utilities to assist with the implementation of new asserts. + + + + Initializes a new instance of the class + + + + Performs an action and returns an array containing the assertion failures + that were observed within the block. If the block throws an exception, it + is reified as an assertion failure. + + The action to invoke. + The array of failures, may be empty if none. + Thrown if is null. + + + + Performs an action and returns an array containing the assertion failures + that were observed within the block. + + The action to invoke. + The assertion failure behavior to use while the action runs. + The array of failures, may be empty if none. + Thrown if is null. + Thrown if there is no current assertion context. + + + + Performs an action and combines the possible assertion failures + that were observed within the block, into a single outer failure with + a common explanation. + + The action to invoke. + A function that takes an array of inner failures and + returns a single outer failure with a common explanation. + Thrown if is null. + Thrown if is null. + + + + Submits a failure if the assertion failure object is non-null. + + Failure to be submited, or null if none. + + + + Verifies that an assertion succeeded. + + The assertion function to evaluate. + Thrown if is null. + + + + Abstract base class for an aggregate data set that combines a list of data + sets according to some algorithm. + + + + Initializes a new instance of the class + + + + Adds a data set to the aggregate. + + The data set to add. + Thrown if is null. + Thrown if is already a member of this aggregate. + + + + Gets the immutable list of combined data sets. + + + + + A base implementation of that + performs argument validation. + + + + Initializes a new instance of the class + + + + Gets a value derived from the . + + The data item. + The value. + Thrown if the data binding fails. + Thrown if is null. + + + + Internal implementation of after argument + validation has been performed. + + The data item, not null. + The value. + Thrown if the data binding fails. + + + + Abstract base class for that validates + input arguments before passing them on to the implementation. + + + + Initializes a new instance of the class + + + + Registers the 's requests to query particular + s with the . + + The data binding context. + The data source resolver. + The data binding accessor to use for obtaining bound values + from s produced by the . + Thrown if or is null. + + + + Implementation of . + + The data binding context, not null. + The data source resolver, not null. + The data binding accessor. + + + + Abstract base class for data items. + + + + Initializes a new instance of the class + + + + Gets an enumeration of the data bindings that may be queried to informally describe + its contents. The enumeration of bindings may not be complete. + + The enumeration of bindings. + + + + Gets the value of the specified binding. + + The data binding, never null. + The value. + Thrown if the + cannot be resolved or if its value cannot be obtained. + + + + Implements . + + The binding, never null. + The associated value. + + + + Returns true if the item contains data that is obtained dynamically from sources + whose content may change over time or may be expensive to query ahead of time. + + + + + Populates the specified metadata map with key/value pairs associated with + the data item, if any. + + The metadata map. + + + + Implements . + + The metadata map to populate, never null. + + + + Abstract base class for that validates + input arguments before passing them on to the implementation. + + + + Initializes a new instance of the class + + + + Returns true if the data set can provide a value for the specified binding. + + The binding. + True if the data set can provide a value for the binding. + Thrown if is null. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Gets the number of columns in an indexed data set. + + + + + Gets an enumeration of data items that can supply values for a given collection of bindings. + It should produce items even if some of the requested bindings cannot be fulfilled. + + The bindings that are requested. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The enumeration of data items. + Thrown if is null. + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + A that simply accesses a value contained + by a data item using a particular . + + + + + Creates a bound data accessor. + + The binding to query. + Thrown if is null. + + + + The combinatorial join strategy combines items by constructing the cartesian + product of the items of each provider. + + + + + Gets the singleton instance of the strategy. + + + + + Joins the items from each provider into a sequence of aggregate items. + + The list of providers. + The list of bindings per provider. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + An enumeration of item-lists consisting of exactly one item from + each provider and indexed in the same order as the + collection. + + + + The concatenation merge strategy combines the items from multiple providers + by simply concatenating the items in the order in which they + appear and proceeding from one provider to the next until all providers + have been fully processed. + + + + + Gets the singleton instance of the strategy. + + + + + Merges the items from each provider into a new sequence. + + The list of providers. + The bindings. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The merged sequence of items. + + + + An implementation of that + returns a constant value, ignoring the data item it is passed. + + + + + Creates a data accessor that returns a specified constant value. + + The constant value to be returned by . + + + + A CSV data set retrieves fields from a CSV document as strings. + + + + + Creates a CSV data set. + + A delegate that provides the text reader for reading the CSV document on demand. + True if the data set should be considered dynamic. + Thrown if is null. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Gets the number of columns in an indexed data set. + + + + + Gets or sets a character that indicates that a line in the source represents a comment. + May be set to '\0' (null) to disable comment handling. + + + + + Gets the name of the location that is providing the data, or null if none. + + + + + Gets or sets the field delimiter character. + + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + Gets or sets whether the CSV document has a header that should be used to provide + aliases for indexed columns. + + + + + Reads data from a Comma Separated Values document. + + + + + Creates a CSV reader. + + The text reader from which to read the contents of the document. + Thrown if is null. + + + + Closes the reader. + + + + + Gets or sets a character that indicates that a line in the source represents a comment. + May be set to '\0' (null) to disable comment handling. + + + + + Gets or sets the field delimiter character. + + + + + Gets the 1-based line number of the previously returned record, + or 0 if no lines have been read yet. + + + + + Reads the list of fields that belong to the next record in the document. + Returns null at the end of the document. + + The record contents as an array of field values, or null if at the end of the document. + Thrown if an I/O error occurs. + + + + A data binding object describes how a data binding is to take place. + + + + + Creates a new data binding with an optional index and path. + + The binding index or null if none. . + The binding path or null if none. . + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Determines whether the specified is equal to the current . + + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + The parameter is null. + + + + + Serves as a hash function for a particular type. + + + A hash code for the current . + + + + + Gets an optional binding index that describes how to locate the bound value + in a data set that is structured as an ordered tuple, such as the ordinal index + of a cell in an array. Null if none. + + + + + Gets an optional binding path that describes how to locate the bound value + in the data set, such as a column name or an XPath expression. Null if none. + + + + + Creates a clone of the data binding with a different index. + + The new index. + The cloned binding. + + + + Returns a debug representation of the binding as a string. + + The string representation. + + + + A tracks a list of s and + s that are used to produce s. + + + + + Creates a data binding context. + + The converter. + Thrown if is null. + + + + Gets the converter service. + + + + + Gets the immutable list of data sets to be enumerated during data binding. + + + + + Gets an enumeration of s. + + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The enumeration of data items. + + + + Returns true if the data binding context contains registered data bindings. + + + + + Registers a data binding for a given data set and adds the data set + to the list of data sets to be enumerated during data binding. + Returns a that may be used to + retrieve the values associated with the binding. + + The data set. + The data binding. + Thrown if or is null. + + + + Gets or sets the to use for combining the + together. + By default the strategy is . + + Thrown if is null. + + + + The type of exception thrown when data binding operations fail. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception with an associated data binding. + + The message. + The associated data binding, or null if none. + + + + Creates an exception with an associated data binding. + + The message. + The associated data binding, or null if none. + The inner exception. + + + + Creates an exception. + + The message. + The inner exception. + + + + A data binding specification describes how values are bound to slots () + of a type or method. The specification can then be used to create new objects or invoke + methods. + + + + + Creates a data binding spec. + + The slot values. + The converter to use for converting slot values + to the required types. + Thrown if + or is null or if + contains a null slot. + + + + Appends formatted generic arguments within angle brackets, if any. + + The string builder, not null. + The arguments, not null. + The formatter, not null. + + + + Appends formatted generic arguments within parentheses, if any. + + The string builder, not null. + The arguments, not null. + The formatter, not null. + + + + Appends formatted values keyed and sorted by name, if any. + This method is used with fields and properties. + + The string builder, not null. + The named values, not null. + The formatter, not null. + + + + Gets the converter. + + + + + Formats the specification to a string for presentation. + + The entity that is qualified by the specification such as the name of a type or method. + The formatter. + The formatted specification. + Thrown if + or is null. + + + + Internal implementation of after argument validation. + + The entity that is qualified by the specification such as the name of a type or method. + The formatter, not null. + The formatted specification. + + + + Resolves a member that may be declared by a generic type using the + resolved type or one of its subtypes. + + The resolved type, not null. + The member, not null. + The type of member. + The resolved member. + + + + Gets the slot values. + + + + + Utilities for . + + + + + Gets the metadata associated with a data item. + + The data item. + The associated metadata. + + + + A data row is a simple immutable value type that encpasulates an + array of values along with associated metadata for use in data binding expressions. + It presents a fluent interface that users may find more convenient than + other implementations. + + + + + Creates a data row with the specified array of values. + + The array of values. + + + + Gets an enumeration of the data bindings that may be queried to informally describe + its contents. The enumeration of bindings may not be complete. + + The enumeration of bindings. + + + + Implements . + + The binding, never null. + The associated value. + + + + Returns true if the item contains data that is obtained dynamically from sources + whose content may change over time or may be expensive to query ahead of time. + + + + + Implements . + + The metadata map to populate, never null. + + + + Returns an augmented data row with added metadata from the + specified metadata map. + + The metadata map. + The augmented data row. + Thrown if + is null. + + + + Returns an augmented data row with added metadata. + + The metadata key. + The metadata value. + The augmented data row. + Thrown if + or is null. + + + + An data source object provides a simple way of aggregating data sets + together. It also provides a simple translation mechanism for mapping + binding paths to binding indexes which is useful for providing named + aliases for columns in indexed data sets. + + + + + Creates a data source with a given name. + + The name of the data source, or an empty string if it is anonymous. + Thrown if is null. + + + + Adds an alias for a binding path to map it to the specified index. + + The binding path to match in a case-insensitive manner. + The associated index to use instead. + Thrown if is null. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + Gets the name of the data source, or an empty string if it is anonymous. + + + + + A data source table manages a collection of named data sources. + + + + Initializes a new instance of the class + + + + + Resolves the data source with the specified name. + + The data source name. + The resolved data source, or null if none found. + Thrown if is null. + + + + A factory data set generates data items by invoking a factory delegate + and interpreting its output in accordance with the factory kind. + + + + + Creates a factory data set. + + The factory delegate. + The kind of factory. + The number of columns in the data items produced + by the factory or 0 if unknown. + Thrown if is null. + Thrown if + is invalid or if is less than 0. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Gets the number of columns in an indexed data set. + + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + Specifies the kind of factory member referenced by . + + + + + Automatically determines the type of factory based on the type of element + returned by the enumeration. + + + + + Specifies that the factory returns an enumeration s + whose items are to be consumed. + + + + + Specifies that the factory returns an enumeration of s + (such as , , or ). + + + + + Specifies that the factory returns an enumeration of object arrays + that describe successive items. + + + + + Specifies that the factory returns an enumeration of single object values. + + + + + A data accessor extracts a value from a . + + + + + Gets a value derived from the . + + The data item. + The value. + Thrown if the data binding fails. + Thrown if is null. + + + + A data binder specifies how to produce values that are suitable for data binding + in some context. + + + + + Registers the 's requests to query particular + s with the . + + The data binding context. + The data source resolver. + The data binding accessor to use for obtaining bound values + from s produced by the . + Thrown if or is null. + + + + A data item is an opaque representation of a collection of values + and metadata that may be retrieved using data bindings that encode + the appropriate lookup rules into the item. + + + + + Gets an enumeration of the data bindings that may be queried to informally describe + its contents. The enumeration of bindings may not be complete. + + The enumeration of bindings. + + + + Gets the value of the specified binding. + + The data binding, never null. + The value. + Thrown if the + cannot be resolved or if its value cannot be obtained. + + + + Returns true if the item contains data that is obtained dynamically from sources + whose content may change over time or may be expensive to query ahead of time. + + + + + Populates the specified metadata map with key/value pairs associated with + the data item, if any. + + The metadata map. + + + + A data provider generates an enumeration of s + given a collection of s to satisfy. + + + + + Gets an enumeration of data items that can supply values for a given collection of bindings. + It should produce items even if some of the requested bindings cannot be fulfilled. + + The bindings that are requested. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The enumeration of data items. + Thrown if is null. + + + + A data set provides data items for data binding and describes whether + is supports particular bindings. + + + + + Returns true if the data set can provide a value for the specified binding. + + The binding. + True if the data set can provide a value for the binding. + Thrown if is null. + + + + Gets the number of columns in an indexed data set. + + + + + Resolves data sources by name. + + + + + Resolves the data source with the specified name. + + The data source name. + The resolved data source, or null if none found. + Thrown if is null. + + + + A join strategy combines items from multiple providers into products + according to some algorithm. + + + + + Joins the items from each provider into a sequence of aggregate items. + + The list of providers. + The list of bindings per provider. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + An enumeration of item-lists consisting of exactly one item from + each provider and indexed in the same order as the + collection. + + + + A merge strategy combines items from multiple providers into a sequence + according to some algorithm. + + + + + Merges the items from each provider into a new sequence. + + The list of providers. + The bindings. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The merged sequence of items. + + + + The intersection merge strategy combines the items from multiple providers + by discarding items whose values do not appear in the items of all other + providers. + + + + + Gets the singleton instance of the strategy. + + + + + Merges the items from each provider into a new sequence. + + The list of providers. + The bindings. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The merged sequence of items. + + + + A data set constructed from a sequence of data items. + + + + + Creates a row data set. + + The sequence of items. + The column count. + Thrown if is null. + Thrown if is negative. + + + + Gets the number of columns in an indexed data set. + + + + + A joined data set is an aggregate data set that joins items from each of zero or more + other data sets according to a . + + + + Initializes a new instance of the class + + + + Adds a data set to the aggregate. + + The data set to add. + Thrown if is null. + Thrown if is already a member of this aggregate. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Gets the number of columns in an indexed data set. + + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + Gets or sets the . + + Thrown if is null. + + + + Translates a binding into one that expresses a query that is scoped over + a particular data set that is associated with this interface. + + The data set. + The binding. + The translated binding. + Thrown if + or is null. + Thrown if + is not a member of this instance. + + + + A list data item contains a list of static data values combined with + optional metadata for the item. Data binding occurs based on the binding + index alone. + + The value type. + + + + Creates a list data item with optional metadata. + + The list of values. + The metadata key/value pairs, or null if none. + True if the item contains dynamic data. + Thrown if is null. + + + + Gets an enumeration of the data bindings that may be queried to informally describe + its contents. The enumeration of bindings may not be complete. + + The enumeration of bindings. + + + + A merged data set is an aggregate data set that selects items from each of zero or more + other data sets according to a . + + + + Initializes a new instance of the class + + + + Adds a data set to the aggregate. + + The data set to add. + Thrown if is null. + Thrown if is already a member of this aggregate. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Gets the number of columns in an indexed data set. + + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + Gets or sets the . + + Thrown if is null. + + + + Encapsulates a specification for invoking a method given values for + its generic parameters and formal parameters. + + + + + Creates a new method specification. + + The non-generic type or generic type instantiation + that declares the method to be invoked or is a subtype of the declaring type. + This parameter is used to resolve the method to its declaring type. + The method or generic method definition to be instantiated. + The slot values. + The converter to use for converting slot values + to the required types. + Thrown if , + , or is null. + Thrown if contains + slots that are declared by different methods or have incompatible values. + + + + Invokes the method. + + The object on which to invoke the method. This value is ignored + if the method is static. + The method result value. + Thrown if is + null but the method is non-static. + Any exception thrown by the invoked method. + + + + Gets the method or generic method definition to be invoked. + + + + + Gets the resolved method arguments. + + + + + Gets the resolved method given any generic method arguments that may have + been provided as slot values. + + + + + Gets the resolved type that declares the method. + + + + + A null data item simply returns a null value on each request. + It has no metadata. + + + + + Gets an enumeration of the data bindings that may be queried to informally describe + its contents. The enumeration of bindings may not be complete. + + The enumeration of bindings. + + + + Gets the singleton null data item instance. + + + + + Returns true if the item contains data that is obtained dynamically from sources + whose content may change over time or may be expensive to query ahead of time. + + + + + Encapsulates a specification for creating objects given values for + a type's generic parameters, constructor parameters, fields and properties. + + + + + Creates a new object specification. + + The type or generic type definition to be instantiated. + The slot values. + The converter to use for converting slot values + to the required types. + Thrown if , + or is null. + Thrown if + has an element type or if contains + slots that are declared by different types or have incompatible values. + + + + Creates an instance of the resolved type and initializes it using + constructor parameter, field and property slot values. + + The new instance, never null. + Thrown if the type is not instantiable. + + + + Gets the resolved constructor, or null if the type was abstract or if it was + a struct and the default struct constructor is being use. + + + + + Gets the resolved constructor arguments. + + + + + Gets the resolved fields and their values. + + + + + Gets the resolved properties and their values. + + + + + Gets the resolved type given any generic type arguments that may have + been provided as slot values. + + + + + Gets the type or generic type definition to be instantiated. + + + + + An object data binder creates objects and binds values to its slots such as + generic type parameters, constructor parameters, fields and properties. + + + + + Creates an object data binder initially without slot binders. + + The type. + Thrown if is null. + + + + Implementation of . + + The data binding context, not null. + The data source resolver, not null. + The data binding accessor. + + + + Sets the binder for a slot. + + The slot. + The binder. + Thrown if + or is null. + + + + The pairwise strategy constructs a limited number of combinations of the + items within the data providers such that they cover all possible pairs + of values from each data source. + + + + + Gets the singleton instance of the strategy. + + + + + Joins the items from each provider into a sequence of aggregate items. + + The list of providers. + The list of bindings per provider. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + An enumeration of item-lists consisting of exactly one item from + each provider and indexed in the same order as the + collection. + + + + A scalar data binder queries a specified data source with a data binding + and converts the resulting value to the requested type. + It does nothing during unbinding. + + + + + Creates a scalar data binder. + + The data binding. + The data source name to query, or an empty string if it is anonymous. + + + + Implementation of . + + The data binding context, not null. + The data source resolver, not null. + The data binding accessor. + + + + A scalar data item represents a single static data value combined with + optional metadata for the item. Data binding occurs whenever the binding + index is 0. + + The value type. + + + + Creates a scalar data item with optional metadata. + + The value to hold. + The metadata key/value pairs, or null if none. + True if the item contains dynamic data. + + + + Gets an enumeration of the data bindings that may be queried to informally describe + its contents. The enumeration of bindings may not be complete. + + The enumeration of bindings. + + + + The sequential join strategy combines items from each data provider sequentially. + If one provider contains fewer items than the others, the sequential join strategy + will insert a in its place until all other providers have been exhausted. + This is similar to performing an "outer join" of multiple sources by ordinal index. + + + + + Gets the singleton instance of the strategy. + + + + + Joins the items from each provider into a sequence of aggregate items. + + The list of providers. + The list of bindings per provider. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + An enumeration of item-lists consisting of exactly one item from + each provider and indexed in the same order as the + collection. + + + + An implementation of that stores the dynamic flag + and metadata. + + + + + Creates a data item. + + The metadata key/value pairs for the item, or null if none. + True if the item is dynamic. + + + + Returns true if the item contains data that is obtained dynamically from sources + whose content may change over time or may be expensive to query ahead of time. + + + + + Implements . + + The metadata map to populate, never null. + + + + The union merge strategy combines the items from multiple providers by + discarding all items whose values duplicate those of other items that + have already been enumerated. + + + + + Gets the singleton instance of the strategy. + + + + + Merges the items from each provider into a new sequence. + + The list of providers. + The bindings. + If true, includes items that may be dynamically + generated in the result set. Otherwise excludes such items and only returns + those that are statically known a priori. + The merged sequence of items. + + + + A data set constructed from an enumerated sequence of values. + + + + + Creates a column sequence data set with optional metadata. + + The sequence of column values, each generating an item. + The metadata key/value pair enumeration, or null if none. + True if the sequence is dynamic. + Thrown if is null. + + + + Gets the number of columns in an indexed data set. + + + + + An XML data set selects nodes from an XML document using XPath + expressions. The selected nodes are returned as objects. + + + + + Creates an XML data set. + + A delegate that produces the XML document on demand. + The XPath expression used to select items within the document. + True if the data set should be considered dynamic. + Thrown if or is null. + + + + Determines whether a binding can be satisfied by the data set. + + The data binding, not null. + True if the binding can be satisfied. + + + + Gets the number of columns in an indexed data set. + + + + + Gets the name of the location that is providing the data, or null if none. + + + + + Enumerates the data items in the data set. + + The data bindings, not null. + If true, includes dynamic items. + The enumeration of data items in the combined data set. + + + + This exception type is used to signal an error while using a data generator. + The exception message, if present, should explain the reason that the test was generator has failed. + + + + + Creates a exception. + + + + + Creates a exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates a exception with the specified message.. + + The message, or null if none. + + + + Creates a exception with the specified message and the inner exception. + + The message, or null if none. + The inner exception, or null if none. + + + + Generic abstract generator of values. + + The type of the values returned by the generator. + + + + Default constructor. + + + + + Checks for the specified value to be not one of the following: + + The property value to be checked. + A friendly name for the property. + The specified property value is invalid. + + + + Checks for the specified value to be not one of the following: + + The property value to be checked. + A friendly name for the property. + The specified property value is invalid. + + + + Filters the specified value. + + The value to be filtered. + True if the value is accepted; false otherwise. + + + + Gets or sets the filter function that can be used + to reject or accept generated values. + + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Generator of values. + + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Generic abstract generator of random values within a given range. + + The type of the value to generate. + + + + Default constructor. + + + + + Gets the length of the sequence of values + created by the generator. + + + + + Returns the sequence of random numbers. + + The sequence of values. + + + + A general purpose pseudo-random number generator. + + + + + Gets the upper bound of the range. + + + + + Gets the lower bound of the range. + + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Generator of random values within a given range. + + + + + Constructs a generator of random numbers. + + + + + Returns the sequence of random numbers. + + The sequence of values. + + + + Generator of random objects based on a regular expression filter mask. + + + + + Constructs a generator of random objects. + + + + + Generates the next random string. + + A random string. + + + + Gets or sets regular expression pattern that serves as a filter mask. + + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Generator of random objects from a predefined list of string values. + + + + + Constructs a generator of random objects. + + + + + Generates the next random string. + + A random string. + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Gets or sets the predefined string values. + + + + + Generator of random objects based on a regular expression filter mask. + + + + + Constructs a generator of random objects. + + + + + Gets or sets the length of the sequence of strings + created by the generator. + + + + + Generates the next random string. + + A random string. + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Generic abstract generator of sequential numeric values. + + The type of the value to generate. + + + + Default constructor. + + + + + Gets or sets the length of the sequence of values + created by the generator. + + + + + Gets or sets the ending point of the sequence. + + + + + Returns the linear sequence constructed by using the , , and properties. + + The sequence of values. + + + + Returns the linear sequence constructed by using the , , and properties. + + The sequence of values. + + + + Returns the linear sequence constructed by using the , , and properties. + + The sequence of values. + + + + Generates the sequence of values. + + An enumeration of generated values. + + + + Gets or sets the starting point of the sequence. + + + + + Gets or sets the increment between each value of the sequence. + + + + + Generator of sequential values. + + + + + Default constructor. + + + + + Returns the linear sequence constructed by using the , , and properties. + + The sequence of values. + + + + Returns the linear sequence constructed by using the , , and properties. + + The sequence of values. + + + + Returns the linear sequence constructed by using the , , and properties. + + The sequence of values. + + + + Associates an annotation message with a code element. When the code element + is processed as part of building some other test, the annotation message will + be emitted. This may be used to signal error, warning, and informational + messages associated with the code element in question. + + + + + Associates an annotation message of the specified type with the code element. + + The annotation type. + The annotation message. + Thrown if is null. + + + + Gets or sets optional detail text of the annotation, or null if none. + + + + + Gets the annotation message. + + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets the annotation type. + + + + + Abstract base class for typical builder implementations. + + + + Initializes a new instance of the class + + + + Registers a deferred action to be performed when is called. + + The associated code element, used to report errors if the deferred action throws an exception. + The order in which the action should be applied, from least order to greatest. + The action to perform. + Thrown if + or is null. + + + + Applies all pending deferred in order and clears the list. + + + + + Gets the test model builder. + + The test model builder. + + + + Abstract base implementation of with do-nothing + implementations. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Returns true if the code element represents a part of a test such as a test method + or a test contribution like a setup or teardown method. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Abstract base class for test component builders. + + + + + Creates a test component builder. + + The associated test model builder. + Thrown if is null. + + + + Adds a metadata key value pair. + + The metadata key. + The value to add. + Thrown if or is null. + + + + Gets a reference to the point of definition of this test + component in the code, or null if unknown. + + + + + Gets the underlying test component. + + The test component. + + + + Gets the test model builder. + + The test model builder. + + + + Gets the stable unique identifier of the component. + + + + + Gets or sets the name of the component. + + Thrown if is null. + + + + Gets the underlying test component. + + The underlying test component. + + + + A contribution method pattern attribute applies decorations to a containing scope + such as by introducing a new setup or teardown action to a test. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + + Applies decorations to the containing test. + + + The containing scope. + The method to process. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a part of a test such as a test method + or a test contribution like a setup or teardown method. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + The data pattern attribute applies a data source to a fixture or test + parameter declaratively. + + + + Initializes a new instance of the class + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets or sets the name of the data source to create so that the values produced + by this attribute can be referred to elsewhere. + + Thrown if is null. + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + A declarative pattern resolver based on . + + + + + Gets the patterns associated with the specified code element. + + The code element. + The enumeration of patterns. + Thrown if is null. + + + + Gets the singleton instance of the declarative pattern resolver. + + + + + A decorator attribute applies contributions to a test component in scope + such as a test or test parameter generated by some other pattern attribute. + + + + Initializes a new instance of the class + + + + Gets or sets the order in which the decorator should be applied. + + + + + Default implementation of a pattern evaluator. + + + + + Creates a pattern evaluator. + + The test model builder. + The pattern resolver. + Thrown if or + is null. + + + + Consumes the specified code element. + + The containing scope. + The code element to consume. + If true, instructs the primary pattern to defer populating child tests. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + Thrown if + or is null. + + + + Finds tests that are declared by the specified . + + The code element. + The enumeration of tests. + Thrown if is null. + + + + Gets all patterns associated with a code element. + + The code element. + The enumeration of patterns, or null if none. + Thrown if is null. + + + + Gets the primary pattern associated with a code element, or null if none. + + The code element. + The primary pattern, or null if none. + Thrown if is null. + Thrown if there are multiple primary patterns associated with the code element. + + + + Finds scopes that are associated with the specified + and returns an enumeration of their objects. + + The code element. + The enumeration of scopes. + Thrown if is null. + + + + Returns true if a code element has one or more associated patterns. + + The code element. + True if the code element has an associated pattern. + Thrown if is null. + + + + Returns true if the code element represents a test. + + The code element. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + True if the code element represents a test. + + + + Returns true if the code element represents a part of a test. + + The code element. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + True if the code element represents a test. + + + + Processes the specified code element. + + The scope. + The code element to process. + Thrown if is null. + + + + Registers the scope so that it can be resolved later by . + + The scope. + Thrown if is null. + + + + Gets the scope of the root test. + + The root scope. + + + + Gets the builder for the test model under construction. + + + + + Default implementation of a pattern scope. + + + + + Creates a new scope. + + The pattern evaluator. + The code element associated with the scope, or null if none. + The test builder in scope. + The test parameter builder in scope, or null if none. + The test data context builder. + True if the scope represents the initial point of declaration + of a given test component. + Thrown if , + or is null. + + + + Adds an action to the scope that enables a pattern to lazily populate the test model + with components generated in nested scopes. This is used when + is called with the option to skip children. + + A supplied by the pattern to populate + its components lazily. + Thrown if is null. + + + + Returns true if a child test can be added to the test within scope. + + + + + Returns true if a test parameter can be added to the test within scope. + + + + + Gets the code element associated with the scope, or null if none. + + + + + Consumes the specified code element using this scope as the containing scope. + + The code element to consume. + If true, instructs the primary pattern to defer populating child tests. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + Thrown if is null. + + + + Creates a child test data context derived from the builders of this scope. + Returns the scope of the newly created child test data context. + + The associated code element, or null if none. + The scope of the newly created child test data context. + + + + Creates a child test with its own child data context derived from the + builders of this scope. Returns the scope of the newly created child test. + + The test name. + The associated code element, or null if none. + The scope of the newly created child test. + Thrown if is null. + Thrown if is null. + + + + Creates and registers a scope for a test component. + + The code element to associate with the scope. + The test builder. + The test parameter builder, or null if the scope + is to be associated to the test only. + The test data context builder. + If true, the scope represents the point of declaration + of the test component with which it is associated. + The new scope. + Thrown if , + , + or is null. + + + + Creates a test parameter for the test in scope with its own + child data context derived from the builders of this scope. Returns + the scope of the newly created test parameter. + + The test parameter name. + The associated code element, or null if none. + The scope of the newly created test parameter. + Thrown if is null. + Thrown if is null. + + + + Gets the pattern evaluator. + + + + + Returns true if the scope represents a test declaration. + + + + + Returns true if the scope represents a test parameter declaration. + + + + + Asks all registered deferred component populators to build components whose + construction had previously been deferred. + + The code element hint to identify the location of the + particular components to populate, or null to populate them all. + + + + Processes the specified code element using this scope as the current scope. + + The code element to process. + Thrown if is null. + + + + Gets a builder for applying contributions to the test currently being + constructed within this scope. Never null. + + + + + Gets a builder for applying contributions to the test component currently being + constructed within this scope. + + + + + Gets a builder for applying contributions to the current test data context within the scope. + + + + + Gets a builder for applying contributions to the test model. + + + + + Gets a builder for applying contributions to the test parameter currently being + constructed within this scope, if there is one, or null if there is no + test parameter in scope. + + + + + Default implementation of a test model builder. + + + + + Creates a test builder. + + The test model builder. + The underlying test. + Thrown if + or is null. + + + + Adds a test dependency. + + The test to add as a dependency. + Thrown if is null. + + + + Gets or sets the apartment state to be used to run the test. + + + + + Creates a child test and returns its builder. + + The test name. + The associated code element, or null if none. + The data context builder for the new test. + The builder for the child test. + Thrown if or is null. + + + + Creates a test parameter and returns its builder. + + The test parameter name. + The associated code element, or null if none. + The data context builder for the new test parameter. + The builder for the test parameter. + Thrown if or is null. + + + + Gets a test parameter builder by name. + + The test parameter name. + The builder for the test parameter, or null if none. + Thrown if is null. + + + + Gets the underlying test component. + + The test component. + + + + Gets or sets whether the test is parallelizable. + + + + + Gets whether this test represents an individual test case + as opposed to a test container such as a fixture or suite. + + + + + Gets or sets the value of the + metadata entry. (This is a convenience method.) + + + + + Gets a locally unique identifier for this test that satisfies some specific conditions. + + The locally unique identifier. + + + + Gets or sets a suggested hint, or null if none. + + The local id hint. + + + + Gets or sets a number that defines an ordering for the test with respect to its siblings. + + + + + Gets the set of actions that describe the behavior of the test. + + + + + Gets the set of actions that describe the behavior of the test's instances. + + + + + Gets or sets the maximum amount of time the whole test including + its setup, teardown and body should be permitted to run. + + Thrown if + represents a negative time span. + + + + Gets the underlying test. + + The underlying test. + + + + Default implementation of a test data context builder. + + + + + Creates a test data context builder. + + The associated test model builder. + The underlying test data context. + Thrown if + or is null. + + + + Creates a child data context. + + The builder for the child context. + + + + Defines a new data source within this data context if one does not exist. + Otherwise returns the existing one. + + The data source name, or an empty string if it is anonymous. + The defined data source. + Thrown if is null. + + + + Gets the test model builder. + + The test model builder. + + + + Gets or sets the offset to add to a test parameter's implicit data binding index to map it + into the containing data context. + + + + + Gets the underlying pattern test data context. + + The underlying pattern test data context. + + + + Default implementation of a test model builder. + + + + + Creates a test model builder. + + The reflection policy. + The underlying test model. + Thrown if + or is null. + + + + Adds an annotation to the test model. + + The annotation to add. + Thrown if is null. + + + + Adds an assembly resolver to the test model's assembly loading policy. + + The resolver to add. + Thrown if is null. + + + + Gets the test model builder. + + The test model builder. + + + + Publishes an exception as an annotation about a particular code element. + + The code element, or null if none. + The exception to publish. + + + + Gets the reflection policy for the model. + + + + + Gets the builder of the root test. + + The builder for the root test. + + + + Gets the underlying test model. + + The underlying test model. + + + + Default implementation of a test parameter builder. + + + + + Creates a test parameter builder. + + The test model builder. + The underlying test parameter. + Thrown if + or is null. + + + + Gets or sets the data binder for the parameter. + + Thrown if is null. + + + + Gets the underlying test component. + + The test component. + + + + Gets the test data context builder for the test parameter. + + + + + Gets the set of actions that describe the behavior of the test parameter. + + + + + Gets the underlying test parameter. + + The underlying test parameter. + + + + Populates components lazily. + + The code element hint to identify the location of the + particular components to populate, or null to populate them all. + + + + Finds and invokes a member of a test fixture, a nested type of the test fixture, + or an external type. + + The type of the result returned by the member invoked. + + + + Constructs a invoker for a member of a test fixture, a nested type of the test fixture, + or an external type. + + The owning type of the searched member, or null if it is assumed to be the fixture class. + The scope of the test. + The name of the searched member. + Thrown if or are null. + + + + Invokes the argument-less member and returns the resulting value. + + The resulting value. + + + + Invokes the member with the specified arguments and returns the resulting value. + + The arguments to pass to the member. + The arguments to pass to the member. + The resulting value. + + + + Invokes the member with the specified arguments and returns the resulting value. + + The arguments to pass to the member. + The resulting value. + + + + Targeted member types for the fixture invoker. + + + + + Default value combining , , and . + + + + + Indicates to find the searched member among the fields. + + + + + Indicates to find the searched member among the properties. + + + + + Indicates to find the searched member among the methods. + + + + + A defines a composable rule for building up a test model + using reflection. + + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Returns true if the code element represents a part of a test such as a test method + or a test contribution like a setup or teardown method. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + A pattern evaluator maintains state that is needed to interpret patterns. + + + + + Consumes the specified code element. + + The containing scope. + The code element to consume. + If true, instructs the primary pattern to defer populating child tests. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + Thrown if + or is null. + + + + Finds tests that are declared by the specified . + + The code element. + The enumeration of tests. + Thrown if is null. + + + + Gets all patterns associated with a code element. + + The code element. + The enumeration of patterns, or null if none. + Thrown if is null. + + + + Gets the primary pattern associated with a code element, or null if none. + + The code element. + The primary pattern, or null if none. + Thrown if is null. + Thrown if there are multiple primary patterns associated with the code element. + + + + Finds scopes that are associated with the specified + and returns an enumeration of their objects. + + The code element. + The enumeration of scopes. + Thrown if is null. + + + + Returns true if a code element has one or more associated patterns. + + The code element. + True if the code element has an associated pattern. + Thrown if is null. + + + + Returns true if the code element represents a test. + + The code element. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + True if the code element represents a test. + + + + Returns true if the code element represents a part of a test. + + The code element. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + True if the code element represents a test. + + + + Processes the specified code element. + + The scope. + The code element to process. + Thrown if is null. + + + + Registers the scope so that it can be resolved later by . + + The scope. + Thrown if is null. + + + + Gets the scope of the root test. + + The root scope. + + + + Gets the builder for the test model under construction. + + + + + The pattern resolver provides a means for obtaining the + objects associated with an . + + + + + Gets the patterns associated with the specified code element. + + The code element. + The enumeration of patterns. + Thrown if is null. + + + + A pattern scope describes the environment in which the pattern is being evaluated. + + + + + Adds an action to the scope that enables a pattern to lazily populate the test model + with components generated in nested scopes. This is used when + is called with the option to skip children. + + A supplied by the pattern to populate + its components lazily. + Thrown if is null. + + + + Returns true if a child test can be added to the test within scope. + + + + + Returns true if a test parameter can be added to the test within scope. + + + + + Gets the code element associated with the scope, or null if none. + + + + + Consumes the specified code element using this scope as the containing scope. + + The code element to consume. + If true, instructs the primary pattern to defer populating child tests. + The default primary pattern to use, if none can be resolved + for the code element. May be null if none. + Thrown if is null. + + + + Creates a child test data context derived from the builders of this scope. + Returns the scope of the newly created child test data context. + + The associated code element, or null if none. + The scope of the newly created child test data context. + + + + Creates a child test with its own child data context derived from the + builders of this scope. Returns the scope of the newly created child test. + + The test name. + The associated code element, or null if none. + The scope of the newly created child test. + Thrown if is null. + Thrown if is null. + + + + Creates and registers a scope for a test component. + + The code element to associate with the scope. + The test builder. + The test parameter builder, or null if the scope + is to be associated to the test only. + The test data context builder. + If true, the scope represents the point of declaration + of the test component with which it is associated. + The new scope. + Thrown if , + , + or is null. + + + + Creates a test parameter for the test in scope with its own + child data context derived from the builders of this scope. Returns + the scope of the newly created test parameter. + + The test parameter name. + The associated code element, or null if none. + The scope of the newly created test parameter. + Thrown if is null. + Thrown if is null. + + + + Gets the pattern evaluator. + + + + + Returns true if the scope represents a test declaration. + + + + + Returns true if the scope represents a test parameter declaration. + + + + + Asks all registered deferred component populators to build components whose + construction had previously been deferred. + + The code element hint to identify the location of the + particular components to populate, or null to populate them all. + + + + Processes the specified code element using this scope as the current scope. + + The code element to process. + Thrown if is null. + + + + Gets a builder for applying contributions to the test currently being + constructed within this scope. Never null. + + + + + Gets a builder for applying contributions to the test component currently being + constructed within this scope. + + + + + Gets a builder for applying contributions to the current test data context within the scope. + + + + + Gets a builder for applying contributions to the test model. + + + + + Gets a builder for applying contributions to the test parameter currently being + constructed within this scope, if there is one, or null if there is no + test parameter in scope. + + + + + An interface shared by and . + + + + + Gets the data context of the component. + + + + + Sets the name of the component. + + + + + A pattern test parameter handler provides the logic that implements the various + phases of the test parameter binding lifecycle. + + + + + Binds a value to a test parameter. + + The test instance state, never null. + The value to bind to the parameter. + + + + Unbinds a test parameter. + + The test instance state, never null. + The value that was bound to the test parameter. + + + + Provides support for performing deferred build actions. + + + + + Registers a deferred action to be performed when is called. + + The associated code element, used to report errors if the deferred action throws an exception. + The order in which the action should be applied, from least order to greatest. + The action to perform. + Thrown if + or is null. + + + + Applies all pending deferred in order and clears the list. + + + + + A test builder applies contributions to a test under construction. + + + + + Adds a test dependency. + + The test to add as a dependency. + Thrown if is null. + + + + Gets or sets the apartment state to be used to run the test. + + + + + Creates a child test and returns its builder. + + The test name. + The associated code element, or null if none. + The data context builder for the new test. + The builder for the child test. + Thrown if or is null. + + + + Creates a test parameter and returns its builder. + + The test parameter name. + The associated code element, or null if none. + The data context builder for the new test parameter. + The builder for the test parameter. + Thrown if or is null. + + + + Gets a test parameter builder by name. + + The test parameter name. + The builder for the test parameter, or null if none. + Thrown if is null. + + + + Gets or sets whether the test is parallelizable. + + + + + Gets whether this test represents an individual test case + as opposed to a test container such as a fixture or suite. + + + + + Gets or sets the value of the + metadata entry. (This is a convenience method.) + + + + + Gets a locally unique identifier for this test that satisfies some specific conditions. + + The locally unique identifier. + + + + Gets or sets a suggested hint, or null if none. + + The local id hint. + + + + Gets or sets a number that defines an ordering for the test with respect to its siblings. + + + + + Gets the set of actions that describe the behavior of the test. + + + + + Gets the set of actions that describe the behavior of the test's instances. + + + + + Gets or sets the maximum amount of time the whole test including + its setup, teardown and body should be permitted to run. + + Thrown if + represents a negative time span. + + + + Gets the underlying test. + + The underlying test. + + + + A test component builder applies contributions to a test or test parameter under construction. + + + + + Adds a metadata key value pair. + + The metadata key. + The value to add. + Thrown if or is null. + + + + Gets a reference to the point of definition of this test + component in the code, or null if unknown. + + + + + Gets the stable unique identifier of the component. + + + + + Gets or sets the name of the component. + + Thrown if is null. + + + + Gets the underlying test component. + + The underlying test component. + + + + A test data context builder applies contributions to a test data context under construction. + + + + + Creates a child data context. + + The builder for the child context. + + + + Defines a new data source within this data context if one does not exist. + Otherwise returns the existing one. + + The data source name, or an empty string if it is anonymous. + The defined data source. + Thrown if is null. + + + + Gets or sets the offset to add to a test parameter's implicit data binding index to map it + into the containing data context. + + + + + Gets the underlying pattern test data context. + + The underlying pattern test data context. + + + + A test model builder applies contributions to a test model under construction. + + + + + Adds an annotation to the test model. + + The annotation to add. + Thrown if is null. + + + + Adds an assembly resolver to the test model's assembly loading policy. + + The resolver to add. + Thrown if is null. + + + + Publishes an exception as an annotation about a particular code element. + + The code element, or null if none. + The exception to publish. + + + + Gets the reflection policy for the model. + + + + + Gets the builder of the root test. + + The builder for the root test. + + + + Gets the underlying test model. + + The underlying test model. + + + + A test builder applies contributions to a test under construction. + + + + + Gets or sets the data binder for the parameter. + + Thrown if is null. + + + + Gets the test data context builder for the test parameter. + + + + + Gets the set of actions that describe the behavior of the test parameter. + + + + + Gets the underlying test parameter. + + The underlying test parameter. + + + + Applies declarative metadata to a test component. + + + + Initializes a new instance of the class + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + The class is the base class for all pattern test framework + attributes. It associates a code element with a for building + up parts of the test model using reflection. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Returns true if the code element represents a part of a test such as a test method + or a test contribution like a setup or teardown method. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Throws a with the specified message + including a short heading that identifies the attribute type. + + The message, not null. + Always thrown. + + + + Throws a with the specified message + including a short heading that identifies the attribute type. + + The message, not null. + The associated exception, or null if none. + Always thrown. + + + + Standard flag combinations for declarations. + + + + + Valid attribute targets for contribution methods. + + + + + Valid attribute targets for data contexts. + + + + + Valid attribute targets for tests. + + + + + Valid attribute targets for test assemblies. + + + + + Valid attribute targets for tests or test parameters. + + + + + Valid attribute targets for test constructors. + + + + + Valid attribute targets for test contracts. + + + + + Valid attribute targets for test methods. + + + + + Valid attribute targets for test parameters. + + + + + Valid attribute targets for test types. + + + + + A test case that has been defined by the . + + + + + Initializes a test initially without a parent. + + The name of the test. + The point of definition of the test, or null if unknown. + The data context. + Thrown if or is null. + + + + Gets or sets the apartment state to be used to run the test. + + + + + Gets the data context of the component. + + + + + Gets or sets whether the test is parallelizable. + + + + + Sets the name of the component. + + + + + Gets the set of actions that describe the behavior of the test. + + + + + Gets the set of actions that describe the behavior of the test's instances. + + + + + Gets or sets the maximum amount of time the whole test including + its setup, teardown and body should be permitted to run. + + Thrown if + represents a negative time span. + + + + Pattern test action provide the logic that implements the various + phases of the test execution lifecycle. + + + + + Creates a test actions object initially configured with empty action chains + that do nothing. + + + + + Cleans up a completed test state after its use. + + + + + Prepares a newly created test state before its use. + + + + + Creates a copy of the test actions. + + The new copy. + + + + Decorates the of a test instance before its + actions have a chance to run. + + + + + Cleans up a test following the execution of its instances. + + + + + Initializes a test prior to the execution of its instances. + + + + + Gets the test instance actions that describes the lifecycle of a test instance. + + + + + Controls the execution of instances. + + + + + Creates a pattern test controller. + + The formatter for data binding. + The converter for data binding. + The test environment manager. + Thrown if , + or is null. + + + + Implementation of called after argument validation has taken place. + + The root test command, not null. + The parent test step, or null if none. + The test execution options, not null. + The progress monitor, not null. + The combined result of the root test command. + + + + A pattern test data context introduces a scope for data source declarations. + + + + + Creates a new data context. + + The containing data context, or null if none. + + + + Creates a child data context. + + A handle for the child context. + + + + Defines a new data source within this data context if one does not exist. + Otherwise returns the existing one. + + The data source name. + The defined data source. + Thrown if is null. + + + + Gets or sets the offset to add to a test parameter's implicit data binding index to map it + into the containing data context. + + + + + Gets the containing data context, or null if none. + + + + + Resolves the data source with the specified name. + + The data source name. + The resolved data source, or null if none found. + Thrown if is null. + + + + Returns the index that should be used to implicitly bind to the nearest + anonymous data source that can be found. + + The implicit data binding index, or null if no anonymous data sources were found. + + + + The pattern test framework is a built-in framework that Gallio provides based on + reflection over attributes that implement . + + + + Initializes a new instance of the class + + + + Gets information about a particular pattern test framework extension. + + The test assembly. + The pattern test framework extension information. + + + + Gets the test driver factory for the framework. + + The test driver factory. + + + + Provides information about a particular pattern test framework extension. + + + + + Creates an information object. + + The unique id of the extension. + The display name of the extension. + Thrown if or + is null. + + + + Gets or sets the extension's test kind which is used to decorate the test + assembly test when a test assembly only contains tests that belong to one + particular framework. May be null if none. + + + + + Gets the unique id of the extension. + + + + + Gets the display name of the extension. + + + + + Pattern test instance actions provide the logic that implements the various + phases of the test instance execution lifecycle. + + + + + Creates a test instance actions object initially configured with empty action chains + that do nothing. + + + + + Cleans up a completed test instance after its use. + + + + + Prepares a newly created test instance state before its use. + + + + + Creates a copy of the test instance actions. + + The new copy. + + + + Decorates the of a child test before its + actions have a chance to run. + + + + + Disposes a test instance that is about to terminate. + + + + + Executes the test instance. + + + + + Initializes a test instance that has just started running. + + + + + Runs the body of the test from the Initialize phase through the Dispose phase. + + + + + Sets up a test instance prior to execution. + + + + + Tears down a test instance following execution. + + + + + Represents the run-time state of a single instance of a + that is to be executed. + + + + + Adds a suffix to the name base. + + The suffix to add. + Thrown if is null. + + + + Gets the data item obtained from the test's + to create this state. + + + + + Gets the converter for data binding. + + + + + Gets the user data collection associated with the test instance state. + + + + + Gets or sets the test fixture instance or null if none. + + + + + Gets or sets the test fixture type or null if none. + + Thrown if + contains unbound generic parameters, is a generic parameter, has an element type. + + + + Gets the formatter for data binding. + + + + + Gets the pattern test instance state from the specified context. + + The context. + The pattern test instance state, or null if none. + Thrown if is null. + + + + Gets a fixture object creation specification using the state's bound . + + The fixture type or generic type definition. + The fixture instance. + Thrown if is null. + Thrown if the slots or values in + are not appropriate for instantiating . + + + + Gets a test method invocation specification using the state's bound . + + The test method or generic method definition, + possibly declared by a generic type or generic type defintion. + The method return value. + Thrown if is null. + Thrown if the slots or values in + or are not appropriate for invoking + Thrown if is null. + + + + Invokes a fixture method using the specified . + + The fixture method or generic method definition, + possibly declared by a generic type or generic type defintion. + The slot values to use for invoking the method. + The method return value. + Thrown if or is null. + Thrown if the slots or values in + or or are not appropriate for + invoking + Thrown if is null. + Any exception thrown by the invoked method. + + + + Invokes the test method specified by , + and . + + The method return value, or null if there was none. + Any exception thrown by the invoked method. + + + + Returns true if the is the + that was created for the test. + + + + + Gets or sets the basic name of the test instance which usually consists of the method or + class name and a description of its bound argument values. + + Thrown if is null. + + + + Gets a mutable dictionary of slots and their bound values. + + + + + Gets the test associated with this test instance state. + + + + + Gets or sets the test method arguments or null if none. + + + + + Gets the test instance actions. + + + + + Gets or sets the test method or null if none. + + Thrown if + is contains unbound generic parameters. + + + + Gets a mutable dictionary of values assigned to test parameters. + + + + + Gets the test state associated with this test instance state. + + + + + Gets the test step used to execute the test instance. + + + + + The test model for the pattern test framework. + + + + + Creates a pattern test model. + + + + + Gets or sets the root test. + + + + + Represents an parameter of a derived from a field, property + or method parameter. + + + + + Creates a test pattern parameter. + + The name of the test parameter. + The code element (usually a slot) represented by the parameter, or null if none. + The data context of the test parameter. + Thrown if + or is null. + + + + Gets or sets the for this test parameter. + + Thrown if is null. + + + + Gets the data context of the component. + + + + + Gets the test that owns this parameter. + + + + + Sets the name of the component. + + + + + Gets the set of actions that describe the behavior of the test parameter. + + + + + + An implementation of based on + actions that can be sequenced and composed as chains. + + + + + + Creates a test parameter actions object initially configured with empty action chains + that do nothing. + + + + + Binds a value to a test parameter. + + The test instance state, never null. + The value to bind to the parameter. + + + + Gets the chain of actions. + + + + + Unbinds a test parameter. + + The test instance state, never null. + The value that was bound to the test parameter. + + + + Gets the chain of actions. + + + + + A delegate used to lazily populate the children of an . + + If true, the populator should recursively populate + all of its newly populated test elements in addition to itself. + + + + Represents the run-time state of a that is to be executed. + + + + + Gets the data binding context of the test. + + + + + Gets the converter for data binding. + + + + + Gets the user data collection associated with the test state. + + + + + Gets the formatter for data binding. + + + + + Gets the pattern test state from the specified context. + + The context. + The pattern test state, or null if none. + Thrown if is null. + + + + Returns true if the test was selected explicitly. + + + + + Gets the primary test step associated with this test state. + + + + + Gets the test associated with this test state. + + + + + Gets the test actions. + + + + + Gets a mutable dictionary of data accessors that will provide + values assigned to test parameters given a data binding item. + + + + + A step that belongs to a . + + + + + Creates a primary step using the same name, code element and metadata + as the test to which it belongs. + + The test to which the step belongs. + The parent test step, or null if creating the root step. + Thrown if is null. + + + + Creates a step. + + The test to which the step belongs. + The parent step, or null if creating a root step. + The step name. + The point of definition of the step, or null if unknown. + True if the test step is primary. + Thrown if + or is null. + + + + Gets the associated test. + + + + + The type of exception thrown when a test declaration is malformed or + contains an error. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates a usage error exception. + + A message that describes how the pattern was misused and possibly what should be done to correct it. + + + + Creates a usage error exception. + + A message that describes how the pattern was misused and possibly what should be done to correct it. + An optional exception that will be used to provide aditional details about the usage error. + + + + The process isolation object saves global process-level context + information when it is created and restores it when it is disposed. + + + + + Saves global process state to be subsequently restored when disposed. + + + + + Restores the saved process state. + + + + + An implementation of a test model builder that is used for reflection only and + does not actually support building tests. + + + + + Creates a test model builder. + + The reflection policy. + Thrown if is null. + + + + Gets the reflection policy for the model. + + + + + Gets the builder of the root test. + + The builder for the root test. + + + + Performs one primitive action of a test and returns its outcome. + + The outcome of the action. + + + + A test assembly decorator pattern attribute applies decorations to an + existing test declared at the assembly-level. + + + + Initializes a new instance of the class + + + + Applies decorations to an assembly-level test. + + The assembly scope. + The assembly. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The assembly. + Thrown if the attribute is being used incorrectly. + + + + Configures runtime parameters while executing tests within a test assembly. + + + + + Specifies the default test case timeout or null if none. + + + + + Specifies the maximum number of concurrent threads to use when tests are run in parallel. + + Thrown if is less than 1. + + + + Resets the globals to default values. + + + + + An assembly initialization attribute gets a chance to perform early initialization + of the system before enumerating the tests within the assembly. + + + + Initializes a new instance of the class + + + + Performs early initialization for the specified assembly. + + The root scope that will eventually contain the assembly-level test. + The assembly to process. + + + + Declares that an assembly generates an assembly-level test. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets a default instance of the assembly pattern attribute to use + when no other pattern consumes an assembly. + + + + + Gets the default pattern to apply to types that do not have a primary pattern, or null if none. + + + + + Initializes a test for an assembly after it has been added to the test model. + + The assembly scope. + The assembly. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Populates the children of the assembly test all at once. + + The assembly scope. + The assembly. + + + + Prepares to populate the children of the assembly test on demand by + adding a deferred populator with . + + The assembly scope. + The assembly. + + + + Applies semantic actions to the assembly-level test to estalish its runtime behavior. + + The test builder. + The assembly. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The assembly. + Thrown if the attribute is being used incorrectly. + + + + Declares that a constructor is used to provide test fixture parameters. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets the default pattern to apply to constructor parameters that do not have a primary pattern, or null if none. + + + + + Gets a default instance of the constructor pattern attribute to use + when no other pattern consumes a contructor. + + + + + Initializes the . + + The data context scope. + The constructor. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a part of a test such as a test method + or a test contribution like a setup or teardown method. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The constructor. + Thrown if the attribute is being used incorrectly. + + + + A test decorator pattern attribute applies decorations to a test defined by an + assembly, type, or method. + + + + Initializes a new instance of the class + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + A dependency pattern attribute creates a dependency on the tests defined + by some other code element. + + + + Initializes a new instance of the class + + + + Gets the code element that declares the tests on which this test should depend. + + The scope. + The code element. + The code element representing the dependency. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + A test decorator pattern attribute applies decorations to an + existing test declared at the method-level. + + + + Initializes a new instance of the class + + + + Applies decorations to a method-level test. + + The method scope. + The method. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + Declares that a method represents a test. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets the default pattern to apply to generic parameters that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to method parameters that do not have a primary pattern, or null if none. + + + + + Executes the test method. + + The test instance state, not null. + + + + Initializes a test for a method after it has been added to the test model. + + The method scope. + The method. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets or sets a number that defines an ordering for the test with respect to its siblings. + + + + + Applies semantic actions to a test to estalish its runtime behavior. + + The test builder. + The test method. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + A test parameter decorator pattern attribute applies decorations to an + existing . + + + + Initializes a new instance of the class + + + + Applies decorations to a . + + The slot scope. + The slot. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The slot. + Thrown if the attribute is being used incorrectly. + + + + Declares that a field, property, method parameter or generic parameter + represents a . + + + + Initializes a new instance of the class + + + + Gets an instance of the parameter pattern attribute to use when no + other pattern consumes the parameter but when the parameter appears to have + other contributing pattern attributes associated with it. + + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets a default instance of the parameter pattern attribute to use + when no other pattern consumes the parameter. + + + + + Initializes a test parameter after it has been added to the containing test. + + The test parameter scope. + The slot. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a part of a test such as a test method + or a test contribution like a setup or teardown method. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The slot. + Thrown if the attribute is being used incorrectly. + + + + A test type decorator pattern attribute applies decorations to an + existing test declared at the type-level. + + + + Initializes a new instance of the class + + + + Applies decorations to a type-level test. + + The type scope. + The type. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The type. + Thrown if the attribute is being used incorrectly. + + + + Declares that a type represents a test. + + + + Initializes a new instance of the class + + + + Gets an instance of the test type pattern attribute to use when no + other pattern consumes the type. + + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Consumes type constructors. + + The scope to be used as the containing scope. + The type whose constructors are to be consumed. + + + + Consumes type members including fields, properties, methods and events. + + The scope to be used as the containing scope. + The type whose members are to be consumed. + + + + Consumes nested types. + + The scope to be used as the containing scope. + The type whose nested types are to be consumed. + + + + Gets the default pattern to apply to constructors that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to events that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to fields that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to generic parameters that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to methods that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to nested types that do not have a primary pattern, or null if none. + + + + + Gets the default pattern to apply to properties that do not have a primary pattern, or null if none. + + + + + Gets the binding flags that should be used to enumerate non-nested type members + of the type for determining their contribution to the test fixture. + + The type. + The binding flags for enumerating members. + + + + Infers whether the type is a test type based on its structure. + + The pattern evaluator. + The type. + True if the type is likely a test type. + + + + Initializes a test for a type after it has been added to the test model. + + The type scope. + The type. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Gets or sets a number that defines an ordering for the test with respect to its siblings. + + + + + Applies semantic actions to a test to estalish its runtime behavior. + + The test builder. + The test type. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The type. + Thrown if the attribute is being used incorrectly. + + + + Runs sample test cases within an embedded copy of the test runner and provides + access to the resulting test report. + + + + + Creates a sample runner. + + + + + Adds a test assembly to the package configuration, if not already added. + + The assembly to add. + Thrown if is null. + + + + Adds a test file to the package configuration, if not already added. + + The file to add. + Thrown if is null. + + + + Adds a test filter to the combined list of filters that select which tests to include in the run, + if not already added. + + The filter to add. + Thrown if is null. + + + + Adds a test fixture type to the list of filters, and automatically adds its containing + test assembly to the package configuration, if not already added. + + The test fixture type to add. + Thrown if is null. + + + + Adds a test method to the list of filters, and automatically adds its containing + test assembly to the package configuration, if not already added. + + The test fixture type. + The test method name. + Thrown if or is null. + + + + Explores the tests but does not run them. + + + + + Gets the primary test step run of a test with the given code reference. + + The code reference of the test. + The first test step run, or null if not found. + + + + Gets the primary test step run that match a predicate. + + The predicate to match. + The first test step run, or null if not found. + + + + Gets all test step runs that represent test cases within a test with + the specified code reference. + + The code reference of the test. + The first test step run, or null if not found. + + + + Gets information about the test with the given code reference. + + The code reference of the test. + The test data, or null if not found. + + + + Gets information about the test that matches a predicate. + + The predicate to match. + The test data, or null if not found. + + + + Gets all test step runs with the given code reference. + + The code reference of the test. + The enumeration of test step runs, or null if not found. + + + + Gets all test step runs that match a predicate. + + The predicate to match. + The enumeration of test step runs, or null if not found. + + + + Gets the test report that was produced by the test run. + + + + + Gets the result of the test run. + + + + + Runs the tests. + + + + + Gets the test package for the test run. + + + + + Gets or sets the name of the test runner factory to use. + + + + + Gets the test runner options. + + + + + Specifies the type of an annotation. + + + + + An informational annotation. + + + + + A warning annotation. + + + + + An error annotation. + + + + + A base test driver that does nothing. + + + + Initializes a new instance of the class + + + + Describes tests via reflection over code elements. + + The reflection policy. + The list of code elements, usually + and objects, that might contain tests to be described. + The test exploration options. + The message sink to receive test exploration messages. + The progress monitor. + Thrown if , + , , + or is null. + + + + Describes tests via reflection over code elements. + + The reflection policy, not null. + The enumeration of code elements, usually + and objects, that might contain tests to be described, not null. + The test exploration options, not null. + The message sink to receive test exploration messages, not null. + The progress monitor, not null. + + + + Explores tests in a test package. + + The test isolation context. + The test package. + The test exploration options. + The message sink to receive test exploration messages. + The progress monitor. + The test report. + Thrown if , + , , + or is null. + + + + Explores tests from a test package. + + The test isolation context, not null. + The test package, not null. + The test exploration options, not null. + The message sink to receive test exploration messages, not null. + The progress monitor, not null. + The test report. + + + + Returns true if the code element represents a test. + + The reflection policy. + The code element. + True if the code element represents a test. + Thrown if + or is null. + + + + Returns true if the code element represents a test. + + The reflection policy, not null. + The code element, not null. + True if the code element represents a test. + + + + Returns true if the code element represents a part of a test such as a setup or teardown method. + + The reflection policy. + The code element. + True if the code element represents a part of a test. + Thrown if + or is null. + + + + Returns true if the code element represents a part of a test such as a setup or teardown method. + + The reflection policy, not null. + The code element, not null. + True if the code element represents a part of a test. + + + + Runs tests from a test package. + + The test isolation context. + The test package. + The test exploration options. + The test execution options. + The message sink to receive test exploration and execution messages. + The progress monitor. + The test report. + Thrown if , + , , , + or is null. + + + + Runs tests from a test package. + + The test isolation context, not null. + The test package, not null. + The test exploration options, not null. + The test execution options, not null. + The message sink to receive test exploration and execution messages, not null. + The progress monitor, not null. + The test report. + + + + Abstract base class for test framework implementations. + + + + Initializes a new instance of the class + + + + Gets the test driver factory for the framework. + + The test driver factory. + + + + Default implementation of a test framework manager. + + + + + Creates a test framework manager. + + The test framework handles. + The fallback test framework handle. + The file type manager. + Thrown if , + or is null. + + + + Gets the handle of the fallback test framework used when no other + framework supports a given test file. + + + + + Gets an aggregate test driver for selected frameworks. + + The test framework selector. + The logger for the test driver. + The test driver. + Thrown if + or is null. + + + + Selects the test frameworks to use for a collection of code elements. + + The test framework selector. + The code elements. + The map of test framework selections to their associated code elements. + Thrown if + or is null or contains null. + + + + Selects the test frameworks to use for a collection of files. + + The test framework selector. + The test files. + The map of test framework selections to their associated test files. + Thrown if + or is null or contains null. + + + + Gets handles for all registered test frameworks. + + + + + Default implementation of . + + + + Initializes a new instance of the class + + + + Default implementation of a . + + + + + Creates a test kind manager. + + The test kind handles. + Thrown if is null. + + + + Gets handles for all registered test kinds. + + + + + A base test driver that is intended to support exploring and executing tests + inside .Net assemblies. + + + + Initializes a new instance of the class + + + + Configures the host setup prior to the initialization of the script runtime. + + The host setup, not null. + The test package, not null. + The assembly path, not null. + The assembly metadata, not null. + + + + Configures the host for a particular assembly. + + The host setup, not null. + The test assembly path, not null. + + + + Creates a host setup for a particular assembly within a test package. + + The test package, not null. + The assembly path, not null. + The assembly metadata, not null. + The host setup setup. + + + + Explores tests in an assembly. + + The test assembly, not null. + The test exploration options, not null. + The message sink, not null. + The progress monitor, not null. + + + + Explores tests from a test package. + + The test isolation context, not null. + The test package, not null. + The test exploration options, not null. + The message sink to receive test exploration messages, not null. + The progress monitor, not null. + The test report. + + + + Gets arguments used to construct the a remote instance of the test driver. + + + + + + + Runs tests in an assembly. + + The test assembly, not null. + The test exploration options, not null. + The test execution options, not null. + The message sink, not null. + The progress monitor, not null. + + + + Runs tests from a test package. + + The test isolation context, not null. + The test package, not null. + The test exploration options, not null. + The test execution options, not null. + The message sink to receive test exploration and execution messages, not null. + The progress monitor, not null. + The test report. + + + + A test driver implementation used when no test framework supports a given test file. + + + + + Creates the fallback test driver. + + The test framework options. + Thrown if is null. + + + + Describes tests via reflection over code elements. + + The reflection policy, not null. + The enumeration of code elements, usually + and objects, that might contain tests to be described, not null. + The test exploration options, not null. + The message sink to receive test exploration messages, not null. + The progress monitor, not null. + + + + Explores tests from a test package. + + The test isolation context, not null. + The test package, not null. + The test exploration options, not null. + The message sink to receive test exploration messages, not null. + The progress monitor, not null. + The test report. + + + + Gets the fallback explanation. + + + + + Runs tests from a test package. + + The test isolation context, not null. + The test package, not null. + The test exploration options, not null. + The test execution options, not null. + The message sink to receive test exploration and execution messages, not null. + The progress monitor, not null. + The test report. + + + + A test framework implementation used when no test framework supports a given test file. + + + + Initializes a new instance of the class + + + + The test framework option key used to explain why the fallback test framework is being used. + + + + + Gets the test driver factory for the framework. + + The test driver factory. + + + + Provides test framework services for exploring and running tests. + + + + + Describes tests via reflection over code elements. + + The reflection policy. + The list of code elements, usually + and objects, that might contain tests to be described. + The test exploration options. + The message sink to receive test exploration messages. + The progress monitor. + Thrown if , + , , + or is null. + + + + Explores tests in a test package. + + The test isolation context. + The test package. + The test exploration options. + The message sink to receive test exploration messages. + The progress monitor. + The test report. + Thrown if , + , , + or is null. + + + + Returns true if the code element represents a test. + + The reflection policy. + The code element. + True if the code element represents a test. + Thrown if + or is null. + + + + Returns true if the code element represents a part of a test such as a setup or teardown method. + + The reflection policy. + The code element. + True if the code element represents a part of a test. + Thrown if + or is null. + + + + Runs tests from a test package. + + The test isolation context. + The test package. + The test exploration options. + The test execution options. + The message sink to receive test exploration and execution messages. + The progress monitor. + The test report. + Thrown if , + , , , + or is null. + + + + The test framework service provides support for enumerating and executing + tests that belong to some test framework. + + + + + Gets the test driver factory for the framework. + + The test driver factory. + + + + Provides services based on the installed set of test frameworks. + + + + + Gets the handle of the fallback test framework used when no other + framework supports a given test file. + + + + + Gets an aggregate test driver for selected frameworks. + + The test framework selector. + The logger for the test driver. + The test driver. + Thrown if + or is null. + + + + Selects the test frameworks to use for a collection of code elements. + + The test framework selector. + The code elements. + The map of test framework selections to their associated code elements. + Thrown if + or is null or contains null. + + + + Selects the test frameworks to use for a collection of files. + + The test framework selector. + The test files. + The map of test framework selections to their associated test files. + Thrown if + or is null or contains null. + + + + Gets handles for all registered test frameworks. + + + + + Describes a test kind. + + + + + Manages the list of test kinds. + + + + + Gets handles for all registered test kinds. + + + + + Defines the names of common test step lifecycle phases. + + + + + The test step's context is being disposed. + + + + + The test step is executing its main body. + + + + + The test step is finishing. + + + + + The test is being initialize. (Fixture construction, etc.) + + + + + The test step is being set up. + + + + + The test step is starting. + + + + + The test step is being torn down. + + + + + Provides common metadata keys. + + + + + The metadata key for the author's email. + + + + + The metadata key for the author's homepage. + + + + + The metadata key for the author's name. + + + + + The metadata key for the name of a category to which a test belongs. + + + + + The matadata key for the location of an assembly as a local + file path or as a Uri. + + + + + The metadata key for the name of the company associated with a test. + + + + + The metadata key for build/release configuration information associated with a test. + + + + + The metadata key for a copyright associated with a test. + + + + + The metadata key for specifying the origin of data used by a test. + + + + + The metadata key for the description of a test component. + + + + + The metadata key for the expected exception type which should be the name, + full name or assembly-qualified name of the expected exception type. + + + + + The metadata key for the expected exception message. + May be a substring of the actual exception message. + + + + + The metadata key that describes the reason that a test should be run explicitly. + + + + + The metadata key for a file associated with a test. + + + + + The metadata key for a file version number associated with a test. + + + + + The metadata key for the test framework name associated with a test assembly in the test tree. + + + + + The metadata key that describes the reason that a test is being ignored. + + + + + The metadata key for the importance of a test component as the + string representation of one of the TestImportance constants in MbUnit + or its equivalent. + + + + + The metadata key for an informational version number associated with a test. + + + + + The metadata key that describes the reason that a test is pending. + + + + + The metadata key for a product associated with a test. + + + + + The metadata key used to describe the kind of a test as the + string representation of one of the constants. + + + + + The metadata key for the name of the type being tested. + + + + + The metadata key for a title associated with a test. + + + + + The metadata key for a trademark associated with a test. + + + + + The metadata key for a version number associated with a test. + + + + + The metadata key for the XML documentation of the test derived from + XML code documentation comments. + + + + + The type of exception thrown when test model and test framework + operations fail. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Utilities for normalizing test model contents. + + + + + Normalizes the message or details of an annotation. + + The text, or null if none. + The normalized text, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a lifecycle phase. + + The lifecycle phase, or null if none. + The normalized lifecycle phase, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a log message. + + The text, or null if none. + The normalized text, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a metadata collection. + + The metadata collection, or null if none. + The normalized metadata collection, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a metadata key. + + The metadata key, or null if none. + The normalized metadata key, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a metadata value. + + The metadata value, or null if none. + The normalized metadata value, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a test, step or parameter id. + + The id, or null if none. + The normalized id, or null if none. May be the same instance if + was already normalized. + + + + Normalizes a test, step or parameter name. + + The name, or null if none. + The normalized name, or null if none. May be the same instance if + was already normalized. + + + + Provides utility functions for manipulating the object model. + + + + + Populates the provided metadata map with asembly-level metadata derived + from custom attributes. + + The assembly. + The metadata map. + + + + A factory for test drivers. + + The component handles of frameworks which share this test driver factory, not null. + The test framework options, not null. + The logger for the test driver, not null. + + + + Provides options that control how test execution occurs. + + + + + Creates a default set of test execution options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets or sets whether the filter exactly specifies all tests to select. + + + + + Gets or sets the filter set. + + Thrown if is null. + + + + Gets a read-only collection of configuration properties for test execution. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Gets or sets whether to run tests within a single thread. This ensures that the + tests will run on the same thread as the initial call to the test harness (unless + the test framework itself spawns any new threads). + + + + + Gets or sets whether to skip running tests that use dynamic data items. + + + + + Gets or sets whether to skip the execution of tests. + + + + + Provides options that control how test exploration occurs. + + + + + Creates a default set of test execution options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets a read-only collection of configuration properties for test exploration. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Specifies how Gallio responds to test files that do not match any frameworks. + + + + + Default match: always fallback to the fallback test framework when + a file does not satisfy the constraits of any other + test framework exactly. + + + + + Approximate match: fallback to the fallback test framework when + a file does not satisfy the constraints of any other + test framework exactly but appears to be an approximate match + for one of them (perhaps differing in version only). Otherwise + the file is not considered a test file. + + + + + Strict match: no fallback. If a file does not satisfy the + constraints of any framework exactly then it is not considered a test file. + + + + + Provides options that configure a test framework. + + + + + Creates a default set of test framework options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets a read-only collection of configuration properties for the test framework. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Specifies a test frameworks that has been selected by a . + + + + + Creates a test framework selection. + + The selected test framework handle. + The test framework options. + True if the selection includes the fallback test + framework because a test file is not supported by any other registered + test framework. + Thrown if + or is null. + + + + Returns true if the selected test framework is a fallback because no other + registered test framework supports the requested test resources. + + + + + Gets the selected test framework handle. + + + + + Gets the test framework options. + + + + + Provides options for selecting test frameworks. + + + + + Creates a test framework filter initialized to defaults. + + + + + Gets or sets the fallback mode used to specify when the + should be used if a test file is not supported by any other test framework. + + + + + Gets or sets a filter predicate for selecting test frameworks to include, or null if all + frameworks should be considered. + + + + + Gets or sets the test framework options. + + Thrown if is null. + + + + Describes traits of an component. + + + + + Creates test framework traits. + + The framework's display name. + Thrown if is null. + + + + Gets or sets the list of file types ids recognized by the framework as test files. + + Thrown if is null. + + + + Gets or sets the list of framework assembly signatures that are recognized and supported + by this framework component. + + Thrown if is null. + + + + Gets or sets the framework's icon, or null if none. + + + + + Returns true if at least one of the assembly references is in . + + The assembly references. + True if the framework is compatible. + Thrown if is null. + + + + Returns true if the file type is the same or a subtype of one of those specified by . + + The file type. + The file type manager used to resolve file type ids to file types. + True if the framework is compatible. + Thrown if or is null. + + + + Gets the framework's display name. + + + + + The version of the test framework. + + + + + A list of standard test kind names provided by Gallio. + + + + + The test represents the tests contained in a single test assembly. + + + + + The test represents the tests contained in a single test file. + + + + + The test represents a test fixture. + + + + + The test represents a grouping of tests for descriptive purposes. + + + + + The test represents the tests contained in a single test namespace. + + + + + The test represents the root of the test tree. + + + + + The test represents a test suite. + + + + + The test represents a test case. + + + + + The test is a placeholder for an unsupported test file or element. + + + + + Specifies traits for . + + + + + Creates test kind traits. + + The test kind name. + The test kind description. + Thrown if + or is null. + + + + Gets the description of the test kind. + + + + + Gets or sets the icon for the test kind, or null if none. + + + + + Gets the name of the test kind. + + + + + Describes the outcome of a test. + + + + + Creates a test outcome with no category. + + The test . + + + + Creates a test outcome with an optional category. + + The test + The test , or null or an empty string if none. + + + + Gets a standard outcome for a test that has an inconclusive outcome because it was canceled. + + The outcome. + + + + Gets the test outcome category, or null if none. Never an empty string. + + + + + If the other outcome is more severe than this one, returns it. + Otherwise returns this outcome. + + The other outcome. + The combined outcome. + + + + Gets the name of the outcome as it should be displayed. + + + + + Indicates whether the current object is equal to another object of the same type. + + + An object to compare with this object. + + true if the current object is equal to the parameter; otherwise, false. + + + + + Indicates whether this instance and a specified object are equal. + + + Another object to compare to. + + true if and this instance are the same type and represent the same value; otherwise, false. + + + + + Gets a standard outcome for a test that failed due to an error. + + The outcome. + + + + Gets a standard outcome for a test that did not run because it must be selected explicitly. + The test may be particularly expensive or require manual supervision by an operator. + + The outcome. + + + + Gets a standard outcome for a test that failed. + + The outcome. + + + + Produces an outcome with the same status but omitting the category information. + + The generalized outcome. + + + + Returns the hash code for this instance. + + + A 32-bit signed integer that is the hash code for this instance. + + + + + Gets a standard outcome for a test that did not run because the user is choosing + to ignore it. Perhaps the test is broken or non-functional. + + The outcome. + + + + Gets a standard outcome for a test that was inconclusive. + + The outcome. + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Compares two outcomes for equality. + + The first outcome. + The second outcome. + True if the outcomes are equal. + + + + Compares two outcomes for inequality. + + The first outcome. + The second outcome. + True if the outcomes are not equal. + + + + Gets a standard outcome for a test that passed. + + The outcome. + + + + Gets a standard outcome for a test that did not run because it has unsatisfied + prerequisites. The test may depend on functionality that has not yet been implemented + or perhaps the test itself has yet to be implemented. + + The outcome. + + + + Provides the Xml schema for this element. + + The schema set. + The schema type of the element. + + + + Gets a standard outcome for a test that did not run. + + The outcome. + + + + Gets the test status. + + + + + Gets a standard outcome for a test that failed because it ran out of time. + + The outcome. + + + + Returns the of the outcome. + + The display name. + + + + A test package specifies the test files, assemblies, and configuration options + that govern test execution. + + + + + Creates an empty test package. + + + + + Adds an excluded test framework id if it is not already in the test package. + + The test framework id to add. + Thrown if is null. + + + + Adds a test file if it is not already in the test package. + + The file to add. + Thrown if is null. + + + + Adds a hint directory if it is not already in the test package. + + The directory to add. + Thrown if is null. + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Gets or sets the application base directory, or null to use the directory + containing each group of test files or some other suitable default chosen by the test framework. + + + + + Applies the settings of another test package as an overlay on top of this one. + + The test package to overlay on top of this one. + Thrown if is null. + + + + Clears the list of test files. + + + + + Clears the list of hint directories. + + + + + Clears the collection of properties. + + + + + Clears the list of excluded test framework ids. + + + + + Creates a copy of the test package. + + The new copy. + + + + Creates a host setup based on the package properties. + + The host setup. + + + + Creates a test framework selector based on the package properties. + + The test framework selector. + + + + Gets or sets the debugger setup options, or null if not debugging. + + + + + Gets the read-only list of test framework IDs that are to be excluded from the test + exploration process. + + + + + Gets the read-only list of test files. + + + + + Gets the read-only list of hint directories used to resolve test assemblies and other files. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Gets a read-only collection of properties for the test runner. + + + + + Removes an excluded test framework id. + + The test framework id to remove. + Thrown if is null. + + + + Removes a test file. + + The file to remove. + Thrown if is null. + + + + Removes a hint directory. + + The directory to remove. + Thrown if is null. + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Gets or sets the .Net runtime version, or null to auto-detect. + + + + + Gets or sets whether assembly shadow copying is enabled. + + + + + Gets or sets the test framework fallback mode. + + + + + Gets or sets the test framework options. + + Thrown if is null. + + + + Gets or sets the working directory, or null to use the directory containing + each group of test files or some other suitable default chosen by the test framework. + + + + + A test result describes the final result of having executed a test. + + + + + Creates a test result with an inconclusive outcome. + + + + + Creates a test result with a particular outcome. + + The outcome. + + + + Gets or sets the number of assertions evaluated by the test, including its children. + + + + + Creates a copy of the test result. + + The copy. + + + + Gets or sets the test duration, including its children. + + + + + Gets or sets the test duration in seconds, including its children. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the test outcome, including its children (unless they were skipped + or are otherwise irrelevant to the outcome of their parent). + + + + + Describes whether a test passed, failed, was skipped or was inconclusive. + + + + + The test passed. + + + + + The test did not run so nothing is known about its status. + + + + + The test did not run or its result was inconclusive. + + + + + The test failed or encountered an error during execution. + + + + + Generates test commands from a tree of tests using topological sort to + order tests by dependencies and a test order strategy for tie-breaking. + + + + + Creates a test command factory with a default test order strategy. + + + + + Recursively builds a tree of test commands. + + The test model. + The filter set for the test model. + If true, only the specified tests are included, otherwise children + of the selected tests are automatically included. + The test context manager. + The root test command or null if none of the tests in + the subtree including matched the filter. + Thrown if , + or is null. + Thrown if an invalid test dependency is found. + + + + Gets or sets the test order strategy to use when deciding how test commands + should be sorted. + + Thrown if is null. + + + + Defines the test ordering strategy. + + + + Initializes a new instance of the class + + + + Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other. + + + The first object to compare. + + + The second object to compare. + + + Value + + Condition + + Less than zero + is less than . + + Zero + equals . + + Greater than zero + is greater than . + + + + + A test command requests the execution of a tree of s. + The test command hierarchy mirrors a filtered subset of the test hierarchy. + + + + + Returns true if all of the dependencies of this test command have + been satisfied including transitive dependencies. + + True if the dependencies of this test command have been satisfied. + + + + Gets the list of child commands to run within the scope of this command. + + + + + Gets the list of other commands that this command depends upon. + + + + + Gets a list consisting of this command and all of its descendants as + enumerated by pre-order tree traversal. + + The list of all command. + + + + Returns true if the test was explicitly selected by a filter. + + + + + Enumerates this command and all of its descendants in pre-order tree + traversal. + + + + + Gets the number of times that a root step of this test has failed. + + + + + Starts the primary step of the test associated with this command as a child + of the specified test step and returns its test context. + + The parent test step, or null if none. + The test context for the new primary test step. + + + + Starts a new step of the test using the specified test step object. + + The test step to start. + The test context for the test step. + Thrown if is null. + Thrown if does not + belong to the test associated with this test command. + + + + Gets the test that is to be executed. + + + + + Gets the total number of tests in the command subtree, including itself. + + + + + Generates test commands from a tree of tests. + + + + + Recursively builds a tree of test commands. + + The test model. + The filter set for the test model. + If true, only the specified tests are included, otherwise children + of the selected tests are automatically included. + The test context manager. + The root test command or null if none of the tests in + the subtree including matched the filter. + Thrown if , + or is null. + Thrown if an invalid test dependency is found. + + + + A implementation based on a . + + + + + Creates a test command. + + The test context manager. + The test. + True if the test is being executed explicitly. + + + + Adds a child test command. + + The child to add. + + + + Adds a test command dependency. + + The dependency to add. + + + + Returns true if all of the dependencies of this test command have + been satisfied including transitive dependencies. + + True if the dependencies of this test command have been satisfied. + + + + Gets the list of child commands to run within the scope of this command. + + + + + Gets the list of children as an array. + + The array of children. + + + + Clears the children of the command. + + + + + Gets the list of other commands that this command depends upon. + + + + + Gets a list consisting of this command and all of its descendants as + enumerated by pre-order tree traversal. + + The list of all command. + + + + Returns true if the test was explicitly selected by a filter. + + + + + Enumerates this command and all of its descendants in pre-order tree + traversal. + + + + + Gets the number of times that a root step of this test has failed. + + + + + Starts the primary step of the test associated with this command as a child + of the specified test step and returns its test context. + + The parent test step, or null if none. + The test context for the new primary test step. + + + + Starts a new step of the test using the specified test step object. + + The test step to start. + The test context for the test step. + Thrown if is null. + Thrown if does not + belong to the test associated with this test command. + + + + Gets the test that is to be executed. + + + + + Gets the total number of tests in the command subtree, including itself. + + + + + Returns a description of the test command for debugging purposes. + + A description of the test command. + + + + The default context tracker tracks the current context by way + of the thread's and . + + + + + Initializes the context tracker. + + + + + Gets the context of the current thread, or null if there is no + current context. + + + + + Enters a context. + + The context to enter, or null to enter a scope without a context. + A cookie that can be used to restore the current thread's context to its previous value when disposed. + + + + Gets the default context for the specified thread. + + The thread. + The default context of the thread. + Thrown if is null. + + + + Gets or the global context of the environment, or null if there is no + such context. + + + + + Sets the default context for the specified thread. + + The thread. + The context to associate with the thread, or null to reset the + thread's default context to inherit the once again. + Thrown if is null. + + + + The context provides information about the environment in which + a test is executing. A new context is created each time a test or + test step begins execution. + + + + + Adds the specified amount to the assert count atomically. + + The amount to add to the assert count. + Thrown if the test is not running. + + + + Adds metadata to the step that is running in the context. + + The metadata key. + The metadata value. + Thrown if + or is null. + Thrown if the test is not running. + + + + Gets the current assertion count. + + + + + This method informs the test context that it may be finished on a + different thread than it started. This changes how the test context + will exit when finished. + + + + + Gets the user data collection associated with the context. + + + + + The event is raised when the test step + is finishing to perform resource reclamation or other updates. + + + + + Finishes a step and submits its final result. + + The final test outcome. + The actual duration of the step, if null the step monitor + will record the duration as the total amount of time since the step monitor was started. + The final test result. + + + + Returns true if the step associated with the context has finished execution + and completed all actions. + + + + + Gets or sets the lifecycle phase the context is in. + + Thrown if is null. + Thrown if attempting to set the phase while the test is not running. + + + + Gets the log writer for the test executing in this context. + + + + + Gets the message sink to which custom test messages may be published. + + + + + Gets the step's outcome or its interim outcome if the test is still running. + + + + + Gets the parent context or null if this context has no parent. + + + + + Gets the final test result or null if the test has not yet finished running. + + + + + Sets the step's interim . + + Thrown if attempting to set the outcome while the test is not running. + + + + Starts a child step of the test and returns its context. + + The step to start. + The context of the child step. + Thrown if the step has finished. + Thrown if is null. + Thrown if is not a child + of the this step. + + + + Gets the test step associated with the context. + + + + + A test context manager provides access to the + and creates new s with the help of the tracker. + + + + + Gets the test context tracker. + + + + + Starts a test step and returns its associated test context. + + The test step. + The test context associated with the test step. + Thrown if is null. + + + + The context tracker tracks the associated with threads. + + + + + Gets the context of the current thread, or null if there is no + current context. + + + + + Enters a context. + + The context to enter, or null to enter a scope without a context. + A cookie that can be used to restore the current thread's context to its previous value when disposed. + + + + Gets the default context for the specified thread. + + The thread. + The default context of the thread. + Thrown if is null. + + + + Gets or the global context of the environment, or null if there is no + such context. + + + + + Sets the default context for the specified thread. + + The thread. + The context to associate with the thread, or null to reset the + thread's default context to inherit the once again. + Thrown if is null. + + + + An observable test context manager creates and tracks test contexts and + publishes test messages back to a . + + + + + Creates a test context manager. + + The test context tracker. + The message sink to which test message are published. + Thrown if + or is null. + + + + Gets the test context tracker. + + + + + Gets the message sink to which test messages are published. + + + + + Starts a test step and returns its associated test context. + + The test step. + The test context associated with the test step. + Thrown if is null. + + + + A log writer that sends messages to a . + + + + + Creates a log writer. + + The test listener to which test messages are published. + The step id. + Thrown if or + is null. + + + + Adds an attachment to the markup document. + + The attachment to write, never null. + Thrown if there is already an attachment + with the same name. + + + + Closes the markup document writer. + + + + + Begins a marked region in a markup stream. + + The markup stream name. + The marker. + + + + Begins a section in a markup stream. + + The markup stream name. + The name of the section to begin, never null. + + + + Embeds an attachment into a markup stream. + + The markup stream name. + The name of the attachment to write, never null. + Thrown if no attachment with the specified + name has been previously attached. + + + + Ends the current region started with one of the Begin* methods in a markup stream. + + The markup stream name. + Thrown if there is no current nested region. + + + + Writes a text string to a markup stream. + + The markup stream name. + The text to write, never null. + + + + A stub implementation of using a . + + + + + Creates a stub context. + + + + + Adds the specified amount to the assert count atomically. + + The amount to add to the assert count. + Thrown if the test is not running. + + + + Adds metadata to the step that is running in the context. + + The metadata key. + The metadata value. + Thrown if + or is null. + Thrown if the test is not running. + + + + Gets the current assertion count. + + + + + This method informs the test context that it may be finished on a + different thread than it started. This changes how the test context + will exit when finished. + + + + + Gets the user data collection associated with the context. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + The event is raised when the test step + is finishing to perform resource reclamation or other updates. + + + + + Finishes a step and submits its final result. + + The final test outcome. + The actual duration of the step, if null the step monitor + will record the duration as the total amount of time since the step monitor was started. + The final test result. + + + + Returns true if the step associated with the context has finished execution + and completed all actions. + + + + + Gets or sets the lifecycle phase the context is in. + + Thrown if is null. + Thrown if attempting to set the phase while the test is not running. + + + + Gets the log writer for the test executing in this context. + + + + + Gets the message sink to which custom test messages may be published. + + + + + Gets the step's outcome or its interim outcome if the test is still running. + + + + + Gets the parent context or null if this context has no parent. + + + + + Gets the final test result or null if the test has not yet finished running. + + + + + Sets the step's interim . + + Thrown if attempting to set the outcome while the test is not running. + + + + Starts a child step of the test and returns its context. + + The step to start. + The context of the child step. + Thrown if the step has finished. + Thrown if is null. + Thrown if is not a child + of the this step. + + + + Gets the test step associated with the context. + + + + + The stub context tracker is a dummy implementation of + that is used in situations where the runtime environment has not been initialized. + + + + + Creates a stub context tracker. + + + + + Static service locator for . + + + + + Gets the global test context tracker singleton. + + + + + Base implementation of a test environment. + + + + Initializes a new instance of the class + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Sets up the current test Thread. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Sets up console I/O streams. + + + + Initializes a new instance of the class + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + A contextual log text writer messages to a named log stream in the log associated + with the test execution context that is active at the time each message is written. + + + + + Creates a text writer that writes to the specified execution log stream. + + The execution log stream name. + + + + When overridden in a derived class, returns the in which the output is written. + + + The Encoding in which the output is written. + + + + + Gets or sets the line terminator string used by the current TextWriter. + + + The line terminator string for the current TextWriter. + + + + + Writes a character to the text stream. + + + The character to write to the text stream. + + + The is closed. + + + An I/O error occurs. + + + + + Writes a subarray of characters to the text stream. + + + The character array to write data from. + + + Starting index in the buffer. + + + The number of characters to write. + + + The buffer length minus is less than . + + + The parameter is null. + + + or is negative. + + + The is closed. + + + An I/O error occurs. + + + + + Writes a string to the text stream. + + + The string to write. + + + The is closed. + + + An I/O error occurs. + + + + + A contextual log trace listener messages to a named log stream in the log associated + with the test execution context that is active at the time each message is written. + + + + + Creates a trace listener that writes to the specified execution log stream. + + The execution log stream name. + + + + Gets a value indicating whether the trace listener is thread safe. + + true if the trace listener is thread safe; otherwise, false. The default is false. + + + + + When overridden in a derived class, writes the specified message to the listener you create in the derived class. + + + A message to write. + + + + + When overridden in a derived class, writes a message to the listener you create in the derived class, followed by a line terminator. + + + A message to write. + + + + + Default implementation of a test environment manager. + + + + + Creates a test environment manager. + + The environments, not null. + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Sets up the current test Thread. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + The test environment configures global behavior related to preparing + the test execution environment for running tests and tearing them down. + + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Sets up the current test Thread. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + The test environment manager configures test AppDomains and threads. + + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Sets up the current test Thread. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + A thread task that uses the to configure + the test environment for the thread. + + + + + Creates a task that will execute code within a new locally running thread + test thread and a configured test environemnt. + When the task terminates successfully, its result will contain the value null. + + The name of the task. + The action to perform within the thread. + The test environment manager, or null to use the default environment manager. + Thrown if + or is null. + + + + Creates a task that will execute code within a new locally running thread + test thread and a configured test environemnt. + When the task terminates successfully, its result will contain the value + returned by . + + The name of the task. + The function to perform within the thread. + The test environment manager, or null to use the default environment manager. + Thrown if + or is null. + + + + Performs an action within the thread after the task's main action runs. + + + + + Performs an action within the thread before the task's main action runs. + + + + + Specifies traits for . + + + + Initializes a new instance of the class + + + + Sets up trace listeners. + + + + Initializes a new instance of the class + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Logs unhandled exceptions instead of killing the AppDomain. + + + + Initializes a new instance of the class + + + + Sets up the current test AppDomain. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + Ensures Windows Forms applications can be tested safely. + + + + Initializes a new instance of the class + + + + Sets up the current test Thread. + + Returns an object that when disposed causes the test environment to be torn down, or null if none. + + + + A filter combinator that matches a value when all of its constituent filters + match the value. + + + + + Creates an AND-filter. + + The filters that must all jointly be matched. + If the list is empty, the filter matches everything. + Thrown if is null. + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Gets the filters that must jointly be matched. + + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter that matches anything and always returns true. + + + + Initializes a new instance of the class + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter that matches objects whose + matches the specified assembly name filter. + + + + + Creates an assembly filter. + + A filter for the assembly name that is used + to match one of the following values: + Full name as returned by .Simple name (aka. partial name) as returned by . + Thrown if is null. + + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + An equality filter compares values for strict equality. + + + + + Creates an equality filter. + + The value to compare for equality. + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Gets the value to compare for equality. + + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter is a serializable predicate. + + + + Initializes a new instance of the class + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Determines whether the filter matches the value. + + The value to consider, never null. + True if the filter matches the value. + + + + Formats the filter to a string suitable for parsing by . + + The formatted filter expression. + + + + Formats filters in such manner that they can be reparsed using the + . + + + + Initializes a new instance of the class + + + + Gets the formatted filter contents. + + The formatted filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + The type of exception thrown when a filter cannot be parsed. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + A filter parser constructs filters from its textual representation as a filter + expression. + + + + + Creates a filter parser. + + The factory to use for constructing + filters based on filter keys and a filter rule for matching string values. + Thrown if is null. + + + + Creates a filter from its textual representation as a filter expression. + + The filter expression. + The parsed filter. + + + + Creates a filter set from its textual representation as a filter set expression + consisting of inclusion and exclusion rules. + + The filter set expression. + The parsed filter set. + + + + Specifies an inclusion or exclusion filter rule. + + + + + Creates a filter rule. + + The rule type: inclusion or exclusion. + The filter. + Thrown if is null. + + + + Gets the filter. + + + + + Gets the filter rule type: inclusion or exclusion. + + + + + Specifies whether a filter rule is an inclusion or exclusion rule. + + + + + The filter rule is an inclusion rule. + + + + + The filter rule is an exclusion rule. + + + + + A filterset combines zero or more filters as a sequence of inclusion and exclusion rules. + + + + + Creates a filter set consisting of a single inclusion filter. + + The inclusion filter. + Thrown if is null. + + + + Creates a filter set consisting of a collection of rules. + + The filter rules. + Thrown if is null. + + + + Returns an empty filter set. + + + + + Evaluates the rules of this filter set and indicates whether the item is included, excluded + or not matched by the list of rules. + + The item. + The result. + + + + Returns true if the filter set has at least one inclusion rule. + + + + + Returns true if the filter set is empty. + + + + + Gets the read-only list of filter rules. + + + + + Formats the filter set to a string suitable for parsing by . + + The formatted filter set expression. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Specifies whether a filter set includes, excludes or does not match a particular item. + + + + + The filter set neither includes nor excludes the item. + + + + + The filter set includes the item. + + + + + The filter set excludes the item. + + + + + Provides utilities for manipulating filters. + + + + + Parses a test filter. + + The filter expression. + The parsed filter. + + + + Parses a test filter set. + + The filter expression. + The parsed filter set. + + + + A filter that matches objects whose + matches the specified id filter. + + + + + Creates an identity filter. + + A filter for the id. + Thrown if is null. + + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Creates filters of a given type based on a specification that + consists of a filter key and a rule for matching values. + + The filter type. + + + + Creates a filter from a specification + + The filter key that identifies the kind of filter to create. + The filter to use as a rule for matching values. + The filter. + + + + Visits the structure of filters. + + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Visits a . + + The filter. + + + + Describes characteristics of a test. + + + + + Gets the code element associated with the test, or null if none. + + + + + Gets the test id. + + + + + Gets the test metadata. + + + + + Gets the test name. + + + + + A filter that matches objects whose + matches the specified member name filter. This filter should normally be used together with + a to ensure the accuracy of the member match. + + + + + Creates a member filter. + + A filter for the member name as returned by . + Thrown if is null. + + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter that matches objects whose + has a key with a value that matches the value filter. + + + + + Creates a metadata filter. + + The metadata key to look for. + A filter for the metadata value to match. + Thrown if or is null. + + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter that matches objects whose + matches the specified name filter. + + + + + Creates a name filter. + + A filter for the name. + Thrown if is null. + + + + Determines whether the filter matches the value. + + The value to consider, never null. + True if the filter matches the value. + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter that matches objects whose + matches the specified namespace name. + + + + + Creates a namespace filter. + + A filter for the namespace name + obtained via reflection on types. + Thrown if is null. + + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter that matches nothing and always returns false. + + + + Initializes a new instance of the class + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter combinator that is the negation of another filter. + + + + + Creates a NOT-filter. + + The filter to be negated. + Thrown if is null. + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Gets the filter to be negated. + + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A filter combinator that matches a value when at least one of its constituent filters + matches the value. + + + + + Creates an OR-filter. + + The filters from which at least one match must be found. + If the list is empty, the filter matches everything. + Thrown if is null. + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Gets the filters from which at least one match must be found. + + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Abstract base class for filters that encapsulate a rule + for selecting some property of an object to be compared + against a string value filter. + + + + + Creates a filter for some property by string value. + + The string value filter. + Thrown if is null. + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Gets the key that represents the filtered property. + + + + + Gets the string value filter. + + + + + A regex filter matches strings against a given . + + + + + Creates an regex filter. + + The regular expression for matching strings. + Thrown if is null. + + + + Accepts a visitor and performs double-dispatch. + + The visitor, never null. + + + + Determines whether the filter matches the value. + + The value to consider, never null. + True if the filter matches the value. + + + + Gets the regular expression for matching strings. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Builds filters for objects. + + The subtype. + + + Initializes a new instance of the class + + + + Creates a filter from a specification + + The filter key that identifies the kind of filter to create. + The filter to use as a rule for matching values. + The filter. + + + + A filter that matches objects whose + matches the specified type name. + + + + + Creates a type filter. + + A filter to match the type name obtained via reflection + on the type in one of the following ways: + Fully qualified by namespace and assembly as returned by Qualified by namespace as returned by Unqualified as returned by the type's + If true, subclasses and interface implementations of the specified + type are also matched by the filter if they can be located. + Thrown if is null. + + + + + Gets the key that represents the filtered property. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A test controller that recursively traverses a hierarchy of test commands and + delegates to another test controller based on a . + + + + + Creates a recursive test controller. + + The test controller provider which provides + the test controller to which the execution of a subtree of tests should be delegated. + Thrown if + is null. + + + + Implementation of called after argument validation has taken place. + + The root test command, not null. + The parent test step, or null if none. + The test execution options, not null. + The progress monitor, not null. + The combined result of the root test command. + + + + A simple test driver explores tests using a + and runs them using a . + + + + Initializes a new instance of the class + + + + Creates a test command factory for generating s from + a . + + The test command factory. + + + + Creates a test context manager for tracking test context and publishing + test messages to a message sink. + + The message sink to which test messages are published. + The test command factory. + + + + Creates a test controller to run tests. + + The test controller. + + + + Creates a test explorer to describe and explore tests. + + The test explorer. + + + + Creates a test harness to configure the test environment. + + The test harness. + + + + Describes tests via reflection over code elements. + + The reflection policy, not null. + The enumeration of code elements, usually + and objects, that might contain tests to be described, not null. + The test exploration options, not null. + The message sink to receive test exploration messages, not null. + The progress monitor, not null. + + + + Explores tests in an assembly. + + The test assembly, not null. + The test exploration options, not null. + The message sink, not null. + The progress monitor, not null. + + + + Gets the name of the framework as it should appear in progress messages. + + + + + Runs tests in an assembly. + + The test assembly, not null. + The test exploration options, not null. + The test execution options, not null. + The message sink, not null. + The progress monitor, not null. + + + + A test controller executes tests defined by a tree of s. + + + + Initializes a new instance of the class + + + + Disposes the test controller. + + + + + Disposes the test controller. + + True if was called directly. + + + + Runs the tests. + + The root test monitor. + The parent test step, or null if starting a root step. + The test execution options. + The progress monitor. + The combined result of the root test command. + Thrown if , or is null. + + + + Implementation of called after argument validation has taken place. + + The root test command, not null. + The parent test step, or null if none. + The test execution options, not null. + The progress monitor, not null. + The combined result of the root test command. + + + + Recursively generates single test steps for each and + sets the final outcome to . + + The root test command. + The parent test step. + The combined result of the test commands. + + + + Gets a test controller for a subtree of tests. + + The test. + The test controller or null if there is no specific controller + available for the test so the test should be executed using a default rule. + + + + A test harness implementation based on . + + + + + Creates the test harness. + + The test environment manager. + Thrown if is null. + + + + Sets up the test AppDomain. + + Returns an object that when disposed causes the changes to be torn down, or null if none. + + + + Sets up the test Thread. + + Returns an object that when disposed causes the changes to be torn down, or null if none. + + + + A test explorer generates a from test code. + + + + Initializes a new instance of the class + + + + Creates the . + + The test model. + + + + Disposes the test explorer. + + + + + Disposes the test explorer. + + True if was called directly. + + + + Explores tests defined by the specified code element and populates the explorer's test model. + + The reflection policy. + The code element. + Thrown if , + is null. + + + + Explores tests defined by the specified code element and populates the explorer's test model. + + The reflection policy, not null. + The code element, not null. + + + + Finishes populating the model. + + + + + Gets the test model. + + + + + A test harness configures the test environment during test exploration and execution. + + + + + Creates the test harness. + + + + + Disposes the test harness. + + + + + Disposes the test harness. + + True if was called directly. + + + + Sets up the test AppDomain. + + Returns an object that when disposed causes the changes to be torn down, or null if none. + + + + Sets up the test Thread. + + Returns an object that when disposed causes the changes to be torn down, or null if none. + + + + An abstract base implementation of a test isolation context. + + + + Initializes a new instance of the class + + + + Begins a batch of isolated tasks. + + The status reporter. + Returns an object that when disposed causes the batch to be terminated, or null if none. + Thrown if is null. + + + + Begins a batch of isolated tasks. + + The status reporter, not null. + Returns an object that when disposed causes the batch to be terminated, or null if none. + + + + Disposes the test isolation context. + + + + + Disposes the test isolation context. + + True if was called directly. + + + + Gets or sets whether the test isolation context requires test drivers to try to run test + code within the same thread on which the isolated task is executed. + + + + + Runs an isolated task within the test isolation context. + + The host setup parameters for the isolated task. + The status reporter. + The task arguments, or null if none. Must be serializable. + The isolated task subclass. + The task result, or null if none. Must be serializable. + Thrown if + or is null. + + + + Runs an isolated task within the test isolation context. + + The host setup parameters for the isolated task, not null. + The status reporter, not null. + The task arguments, or null if none. Must be serializable. + The isolated task subclass. + The task result, or null if none. Must be serializable. + + + + An abstract base implementation of a test isolation provider. + + + + Initializes a new instance of the class + + + + Creates a test isolation context. + + The test isolation options. + The logger. + The test isolation context. + Thrown if + or is null. + + + + Creates a test isolation context. + + The test isolation options, not null. + The logger, not null. + The test isolation context. + + + + A hosted test isolation context created by . + + + + + Creates a hosted test isolation context. + + The host factory. + The test isolation options. + The logger. + Thrown if , + or is null. + + + + Gets the host factory. + + + + + Gets the logger. + + + + + Runs an isolated task within the test isolation context. + + The host setup parameters for the isolated task, not null. + The status reporter, not null. + The task arguments, or null if none. Must be serializable. + The isolated task subclass. + The task result, or null if none. Must be serializable. + + + + Runs an isolated task in a host. + + The host setup which includes the test isolation option properties copied down, not null. + The status reporter, not null. + The task arguments. + The isolated task type. + The task result. + + + + Gets the test isolation options. + + + + + A test isolation provider based on . + + + + + Creates a hosted test isolation provider. + + The host factory. + Thrown if + is null. + + + + Creates a test isolation context. + + The test isolation options, not null. + The logger, not null. + The test isolation context. + + + + An isolated task runs in a . + + + + Initializes a new instance of the class + + + + Runs the task. + + + + + Runs the task. + + + + + A test isolation context is responsible for running test code in an isolated + (possibly remote) environment. + + + + + Begins a batch of isolated tasks. + + The status reporter. + Returns an object that when disposed causes the batch to be terminated, or null if none. + Thrown if is null. + + + + Gets or sets whether the test isolation context requires test drivers to try to run test + code within the same thread on which the isolated task is executed. + + + + + Runs an isolated task within the test isolation context. + + The host setup parameters for the isolated task. + The status reporter. + The task arguments, or null if none. Must be serializable. + The isolated task subclass. + The task result, or null if none. Must be serializable. + Thrown if + or is null. + + + + A test isolation provider creates instances. + + + + + Creates a test isolation context. + + The test isolation options. + The logger. + The test isolation context. + Thrown if + or is null. + + + + Reports a status update. + + + + + Manages the client end of a remote connection that runs isolated tasks provided by the server. + + + + + Creates a test isolation client. + + The IPC port name. + The unique id of the client/server pair. + Thrown if is null. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the client. + + True if was called directly. + + + + Runs isolated tasks until the server shuts down. + + + + + The type of exception thrown when test isolation operations fail. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Provides options that control test isolation. + + + + + Creates a default set of options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets a read-only collection of configuration properties for the test isolation context. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Manages the server end of a remote connection that dispatches isolated tasks to a client. + + + + + Creates a test isolation server. + + The IPC port name. + The unique id of the client/server pair. + Thrown if is null. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the server. + + True if was called directly. + + + + Runs an isolated task on the client. + + The type of isolated task to run. + The isolated task arguments. + The isolated task result. + Thrown if is null. + + + + Instructs a client to shutdown nicely. + + The maximum amount of time to wait for the client to receive the shutdown message. + + + + Tells the server that the client has finished processing an isolated task. + + + + Initializes a new instance of the class + + + + Gets or sets the exception data. + + + + + Gets or sets the unique id of the isolated task. + + + + + Gets or sets the isolated task result. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Tells the server that the client is active. + + + + Initializes a new instance of the class + + + + Tells the client to run an isolated task. + + + + Initializes a new instance of the class + + + + Gets or sets the isolated task arguments. + + + + + Gets or sets the unique id of the isolated task. + + + + + Gets or sets the type of isolated task. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Tells the client to shut down. + + + + Initializes a new instance of the class + + + + Provides functions for converting a into a sequence of + messages and back. + + + + + Creates a message sink that populates the test model as test and annotation + discovered messages are published. + + The test model to populate. + The message sink. + Thrown if is null. + + + + Publishes the contents of the test model to a message sink as test + and annotation discovered messages. + + The test model to publish. + The message sink. + Thrown if + or is null. + + + + Notifies that a test step has finished execution. + + + + Initializes a new instance of the class + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the test result, not null. + + + + + Gets or sets the id of the test step, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a test step has changed lifecycle phase. + + + + Initializes a new instance of the class + + + + Gets or sets the lifecycle phase name, not null. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that an attachment has been added to a test step log. + + + + Initializes a new instance of the class + + + + Gets or sets the attachment, not null. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a marker block has been started within a test step log stream. + + + + Initializes a new instance of the class + + + + Gets or sets the marker. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Gets or sets the stream name, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a section block has been started within a test step log stream. + + + + Initializes a new instance of the class + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the section name, not null. + + + + + Gets or sets the id of the test step, not null. + + + + + Gets or sets the stream name, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that an attachment has been embedded into a test step log stream. + + + + Initializes a new instance of the class + + + + Gets or sets the attachment name, not null. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Gets or sets the stream name, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a block started with Begin* has finished within a test step log stream. + + + + Initializes a new instance of the class + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Gets or sets the stream name, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that text has been written to a test step log stream. + + + + Initializes a new instance of the class + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Gets or sets the stream name, not null. + + + + + Gets or sets the text, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a test step has dynamically added metadata to itself. + + + + Initializes a new instance of the class + + + + Gets or sets the metadata key, not null. + + + + + Gets or sets the metadata value, not null. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the test step, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a test step has started execution and provides its definition. + + + + Initializes a new instance of the class + + + + Gets or sets the code element associated with the test step, or null if none. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets information about the test step that is about to start, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that an annotation has been discovered by the test exploration process. + + + + Initializes a new instance of the class + + + + Gets or sets the annotation, not null. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a test has been discovered by the test exploration process. + + + + Initializes a new instance of the class + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the parent test, or null if the test is the root. + + + + + Gets or sets information about the test that was discovered, not null. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Notifies that a diagnostic log message has been submitted. + + + + Initializes a new instance of the class + + + + Gets or sets the exception, or null if none. + + + + + Gets or sets the log message. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the log severity. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Describes an annotation in a portable manner for serialization. + + + + + Creates an annotation. + + The annotation type. + The code location. + The code reference. + The annotation message. + Additional details such as exception text or null if none. + Thrown if is null. + + + + Copies the contents of an annotation. + + The source annotation. + Thrown if is null. + + + + Gets or sets the code element or null if none. (not serialized) + + + + + Gets or sets the code location associated with the annotation. + + + + + Gets or sets the code reference associated with the annotation. + + + + + Gets or sets additional details such as exception text, or null if none. + + + + + Writes the annotation to a logger for presentation. + + The logger. + If true, includes an identifying prefix to describe + the annotation type, otherwise we assume that the logger will do its own + thing based on the log severity. + Thrown if is null. + + + + Gets or sets the annotation message. + + Thrown if is null. + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Recreates a object from the annotation data. + + The annotation. + + + + Gets or sets the annotation type. + + + + + Describes a test model component in a portable manner for serialization. + + + + + Creates an uninitialized instance for Xml deserialization. + + + + + Copies the contents of a test component. + + The source object. + + + + Creates a test component. + + The component id. + The component name. + Thrown if or is null. + + + + Gets or sets the code element or null if none. (not serialized) + + + + + Gets or sets the code location or if not available. + + + + + Gets or sets the code reference or if not available. + + + + + Gets or sets the test component id. (non-null) + + Thrown if is null. + + + + Gets or sets the metadata map. (non-null) + + Thrown if is null. + + + + Gets or sets the test component name. (non-null) + + Thrown if is null. + + + + Describes a test in a portable manner for serialization. + + + + + Copies the contents of a test recursively including its children. + + The source test. + Thrown if is null. + + + + Copies the contents of a test. + + The source test. + If true, does not recursively populate the children of the test. + Thrown if is null. + + + + Creates a test data object. + + The component id. + The component name. + The full name of the test. + Thrown if , , + or is null. + + + + Recursively enumerates this test and all of its descendants. + + + + + Gets the mutable list of children. + + + + + Gets or sets the full name of the test. + + Thrown if is null. + + + + Gets or sets whether this node is a test case. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets the mutable list of parameters. + + + + + Recreates a object from the test data. + + The test. + + + + The test model captures the root of the test data tree along with an index by id. + + + + + Creates an empty test model with just a root test. + + + + + Creates a test model. + + The root test. + Thrown if is null. + + + + Copies the contents of a test model. + + The source test model. + Thrown if is null. + + + + Recursively enumerates all tests including the root test. + + + + + Gets the mutable list of annotations. + + + + + Gets the number of error annotations on the model. + + The numer of error annotations present. + + + + Gets a test by its id. + + The test id. + The test, or null if not found. + Thrown if is null. + + + + Merged a subtree of tests into the model. + + The id of the parent test, or null if adding the root. + The top test of the subtree to add. + The merged test, if the test was already present in the tree. + Thrown if is null. + + + + Resets the test index by id in case the test model has been modified. + + + + + Gets or sets the root test in the model. + + Thrown if is null. + + + + Describes a test package in a portable manner for serialization. + + + + + Creates an empty test package. + + + + + Copies the contents of a test package. + + The source test package. + Thrown if is null. + + + + Gets or sets the application base directory, or null to use the directory + containing each group of test files or some other suitable default chosen by the test framework. + + + + + Gets or sets whether to attach the debugger to the host. + + + + + Gets the list of test framework IDs that are to be excluded from the test + exploration process. + + + + + Gets the list of relative or absolute paths of test files. + + + + + Gets the list of hint directories used to resolve test assemblies and other files. + + + + + Initializes a test package with the contents of this structure. + + The test package to populate. + Thrown if is null. + + + + Makes the test package paths absolute given the specified base path. + + The base path. + Thrown if is null. + + + + Makes the test package paths relative to the specified base path. + + The base path. + Thrown if is null. + + + + Gets or sets the properties for the test runner. (non-null) + + Thrown if is null. + + + + Gets or sets the .Net runtime version, or null to auto-detect. + + + + + Gets or sets whether assembly shadow copying is enabled. + + + + + Creates a test package with the contents of this structure. + + The test package. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Gets or sets the working directory, or null to use the directory containing + each group of test files or some other suitable default chosen by the test framework. + + + + + Describes a test parameter in a portable manner for serialization. + + + + + Copies the contents of a test parameter. + + The source test parameter. + Thrown if is null. + + + + Creates a parameter data object. + + The component id. + The component name. + Thrown if or + is null. + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Recreates a object from the test data. + + The test parameter. + + + + Describes a test step in a portable manner for serialization. + + + + + Copies the contents of a test step. + + The source test step. + Thrown if is null. + + + + Creates a step. + + The step id. + The step name. + The full name of the step. + The test id. + Thrown if , , + or is null. + + + + Gets or sets the full name of the step. + + Thrown if is null. + + + + Gets or sets whether the test step is dynamic. + + + + + Gets or sets whether the test step is primary. + + + + + Gets or sets whether the test step represents a test case. + + + + + Obtains a normalized copy of the object or the original instance if it is already normalized. + + The original instance or a normalized copy. + + + + Gets or sets the id of the parent step. + + + + + Gets or sets the id of the test to which the step belongs. + + Thrown if is null. + + + + Recreates a object from the test data. + + The test to which the step belongs. + The parent test step, or null if none. + The test step. + Thrown if is null. + + + + An annotation associates a message with a source code location + to inform the user about a problem. + + + + + Creates an annotation with no details. + + The annotation type. + The associated code element, or null if none. + The annotation message. + Thrown if is null. + + + + Creates an annotation with a detail exception. + + The annotation type. + The associated code element, or null if none. + The annotation message. + The exception to use as additional details or null if none. + Thrown if is null. + + + + Creates an annotation with a detail message string. + + The annotation type. + The associated code element, or null if none. + The annotation message. + Additional details such as exception text or null if none. + Thrown if is null. + + + + Gets the code element associated with the annotation. + + + + + Gets additional details such as exception text, or null if none. + + + + + Gets the annotation message. + + + + + Gets the annotation type. + + + + + The root test in the test tree. + + + + + Creates the root test. + + + + + Gets the root test name. + + + + + A test object represents a parameterized test case or test + container. The test parameters are used as placeholders for + data-binding during test execution. A single test can + produce multiple steps () at runtime. + + + + + Initializes a test initially without a parent. + + The name of the test. + The point of definition of the test, or null if unknown. + Thrown if is null. + + + + Adds a child test and sets its property. + + The test to add as a child. + Thrown if is null. + Thrown if is already + the child of some other test. + + + + Adds a test dependency. + + The test to add as a dependency. + Thrown if is null. + + + + Adds a test parameter and sets its property. + + The test parameter to add. + Thrown if is null. + Thrown if is already + owned by some other test. + + + + Gets a read-only list of the children of this test. + + + + + Clears the list of children. + + + + + Clears the list of dependencies. + + + + + Clears the list of test parameters. + + + + + Gets a read-only list of the dependencies of this test. + + + + + Gets the full name of the test. The full name is derived by concatenating the + of the followed by a slash ('/') + followed by the of this test. + + + + + Obtains a unique local id for a child of this test. + + A suggested id which will be used if no conflicts occur. + The unique local id to use. + Thrown if is null. + + + + Gets or sets the stable unique identifier of the component. + + Thrown if is null. + + + + Gets whether this test represents an individual test case + as opposed to a test container such as a fixture or suite. + + + + + Gets a locally unique identifier for this test that satisfies the following conditions: + + The locally unique identifier. + + + + Gets or sets a suggested hint, or null if none. + + The local id hint. + + + + Gets or sets a number that defines an ordering for the test with respect to its siblings. + + + + + Gets a read-only list of the parameters of this test. + + + + + Gets or sets the parent of this test, or null if this is the root test. + + + + + Removes a child test and resets its property. + + The child test to remove. + Thrown if is null. + Thrown if is not a child of this test. + + + + Removes a test dependency. + + The test to remove as a dependency. + Thrown if is null. + + + + Removes a test parameter and resets its property. + + The test parameter to remove. + Thrown if is null. + Thrown if is not owned by this test. + + + + Returns a that represents the current . + + + A that represents the current . + + + + + Common interface for elements in the test object model. + + + + + Initializes a test component. + + The name of the component. + The point of definition of the component, or null if unknown. + Thrown if is null. + + + + Gets or sets a reference to the point of definition of this test + component in the code, or null if unknown. + + + + + Gets or sets the stable unique identifier of the component. + + Thrown if is null. + + + + Gets or sets the value of the + metadata entry. + + + + + Gets the metadata of the component. + + + + + Gets or sets the name of the component. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + The test model provides access to the contents of the test tree + generated from a test package by the test enumeration process. + + + + + Creates a test model with a new empty root test. + + + + + Adds an annotation. + + The annotation to add. + Thrown if is null. + + + + Recursively enumerates all tests including the root test. + + + + + Gets the read-only list of annotations. + + + + + Clears the list of annotations. + + + + + Finds a test by its id. + + The test id. + The test, or null if not found. + Thrown if is null. + + + + Removes an annotation. + + The annotation to remove. + Thrown if is null. + + + + Gets or sets the root test in the model. + + Thrown if is null. + + + + A test parameter describes a formal parameter of a + to which a value may be bound and used during test execution. + + + + + Initializes a test parameter. + + The name of the test parameter. + The point of definition of the parameter, or null if unknown. + Thrown if is null. + + + + Gets or sets the stable unique identifier of the component. + + Thrown if is null. + + + + Gets or sets the test that owns this parameter, or null if this parameter + does not yet have an owner. + + + + + A test step is a delimited region of a test defined at run-time. + + + + + Creates a primary step using the same name, code element and metadata + as the test to which it belongs. + + The test to which the step belongs. + The parent test step, or null if creating the root step. + Thrown if is null. + + + + Creates a step. + + The test to which the step belongs. + The parent step, or null if creating a root step. + The step name. + The point of definition of the step, or null if unknown. + True if the test step is primary. + Thrown if + or is null. + + + + Gets the full name of the step. + + + + + Gets or sets the stable unique identifier of the component. + + Thrown if is null. + + + + Gets or sets whether the test step is dynamic. + + + + + Returns true if the test step is the top node of a hierarchy of test steps that are + all associated with the same test. + + + + + Gets or sets whether the test step represents a distinct test case. + + + + + Gets the step that contains this one, or null if this instance represents the + root step of the test step tree. + + + + + Gets the test to which this step belongs. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A default implementation of . + + + + + Creates a test runner. + + The test isolation provider. + The test framework manager. + Thrown if + or is null. + + + + Disposes the test runner. Does nothing if already disposed or if not initialized. + + The progress monitor. + Thrown if is null. + + + + Gets the event dispatcher for the test runner. + + + + + Explores tests in a test package. + + The test package. + The test exploration options. + The progress monitor. + The test report. + Thrown if , + , or is null. + Thrown if the operation failed. + Thrown if the runner has been disposed. + + + + Initializes the test runner. + + The test runner options. + The logger. + The progress monitor. + Thrown if , + or is null. + Thrown if the runner is already initialized. + Thrown if the runner has been disposed. + + + + Gets the logger, or null if the test runner has not been initialized. + + + + + Registers a test runner extension. + + The test runner extension to register. + Thrown if is null. + Thrown if the test runner has already been initialized. + + + + Explores and runs tests in a test package. + + The test package. + The test exploration options. + The test execution options. + The progress monitor. + The test report. + Thrown if , + , , or is null. + Thrown if the operation failed. + Thrown if the runner has been disposed. + + + + Gets the test runner options, or null if the test runner has not been initialized. + + + + + A factory for . + + + + + Creates a test runner factory. + + The test isolation provider. + The test framework manager. + The extension manager. + Thrown if + or is null. + + + + Creates a test runner. + + The test runner. + + + + The default implementation of . + + + + + Creates a test runner manager. + + The factory handles. + Thrown if is null. + + + + Creates a test runner. + + The name of the test runner factory, matched case-insensitively. + The test runner. + Thrown if is null. + + + + Gets the factory by name, or null if none. + + The name of the test runner factory, matched case-insensitively. + The test runner. + Thrown if is null. + + + + Gets handles for all registered test runner factories. + + + + + A test runner provides the basic functionality for loading, exploring and running tests. + + + + + Disposes the test runner. Does nothing if already disposed or if not initialized. + + The progress monitor. + Thrown if is null. + + + + Gets the event dispatcher for the test runner. + + + + + Explores tests in a test package. + + The test package. + The test exploration options. + The progress monitor. + The test report. + Thrown if , + , or is null. + Thrown if the operation failed. + Thrown if the runner has been disposed. + + + + Initializes the test runner. + + The test runner options. + The logger. + The progress monitor. + Thrown if , + or is null. + Thrown if the runner is already initialized. + Thrown if the runner has been disposed. + + + + Registers a test runner extension. + + The test runner extension to register. + Thrown if is null. + Thrown if the test runner has already been initialized. + + + + Explores and runs tests in a test package. + + The test package. + The test exploration options. + The test execution options. + The progress monitor. + The test report. + Thrown if , + , , or is null. + Thrown if the operation failed. + Thrown if the runner has been disposed. + + + + A test tunner factory is a service that creates an + given a set of options. + + + + + Creates a test runner. + + The test runner. + + + + A test runner manager enumerates the names of the + services that are available and + provides a mechanism for creating instances. + + + + + Creates a test runner. + + The name of the test runner factory, matched case-insensitively. + The test runner. + Thrown if is null. + + + + Gets the factory by name, or null if none. + + The name of the test runner factory, matched case-insensitively. + The test runner. + Thrown if is null. + + + + Gets handles for all registered test runner factories. + + + + + Base arguments for events raised to indicate the completion of an operation. + + + + + Initializes the event arguments. + + True if the operation completed successfully. + + + + Returns true if the operation completed successfully. + + + + + Base arguments for events raised to indicate the beginning of an operation. + + + + + Initializes the event arguments. + + + + + Describes the result codes used by the application. + + + + + The tests were canceled. + + + + + Some tests failed. + + + + + A fatal runtime exception occurred. + + + + + Invalid arguments were supplied on the command-line. + + + + + No tests were found. + + + + + The tests ran successfully or there were no tests to run. + + + + + The type of exception thrown when the test runner or one of its + supportive components like a test domain fails in an unrecoverable manner. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Provides constant names for the standard test runner factories. + + + + + Runs the test runner in an isolated AppDomain of the current process. + + + + + Runs the test runner in an isolated process. + + + + + Runs the test runner in the local AppDomain. + + + + + The test launcher encapsulated the entire test execution lifecycle from + start to finish and provides a simplified pattern for running tests. + + + + + Creates a launcher with default options and no test assemblies specified. + + + + + Adds a file pattern if not already added to the launcher. + + The file path or a wildcard pattern to add. + Thrown if is null. + + + + Adds a report format if not already added to the launcher. + + The report format to add. + Thrown if is null. + + + + Cancels the test run and prevents a new one from starting. + + + + + Clears the list of file patterns. + + + + + Clears the list of report formats. + + + + + Gets or sets whether to skip test execution. + + + + + Controls whether the test runner will echo result to the + as each test finishes. + + + + + Gets a read-only list of test file patterns (with wildcards) or test project files + that are to be resolved and included in the test package prior to execution. + + + + + Gets or sets whether to ignore annotations when determining the result code. + + + + + Gets or sets the logger to use. + + Thrown if is null. + + + + Gets or sets the progress monitor provider to use. + + Thrown if is null. + + + + Removes a file pattern. + + The file pattern to remove. + Thrown if is null. + + + + Removes a report format. + + The report format to remove. + Thrown if is null. + + + + Gets a read-only list of report formats to generate. + + + + + Gets or sets the report formatter options. + + Thrown if is null. + + + + Runs the test package as configured. + + A result object. + + + + Gets or sets the maximum amount of time the tests can run before they are canceled. + + + + + Gets or sets the to use for automatically initializing + the runtime during test execution or null if the runtime is already initialized. + + + + + Gets or sets whether to show the reports after the test run finishes. + + + + + Gets or sets the test execution options. + + Thrown if is null. + + + + Gets or sets the test exploration options. + + Thrown if is null. + + + + Gets or sets the test project. + + Thrown if is null. + + + + Gets or sets the test runner options. + + Thrown if is null. + + + + Contains the result of a complete test run. + + + + + Creates a launcher result object. + + The test report. + + + + Adds a new report document path. + + The report document path. + Thrown if is null. + + + + Generates reports of the desired forms. + + The report directory. + The report name. + The report formats to generate. + The report formatter options. + The report manager. + A progress monitor for the operation. + Thrown if , + , , , + , or is null. + + + + Gets the test report. + + + + + Gets the full paths of the formatted report documents. + + The full paths of the formatted report documents. + + + + Gets the result code. + + + + + Gets a short summary with the number of test that passed, failed and so on. + + + + + Sets the result code of the result. + + The new result code. + + + + Shows the report documents enumerated in the launcher result. + + True if the report documents were successfully opened. + + + + Gets the statistics of the execution from the report + or an empty statistics object if none. + + + + + Describes traits of an component. + + + + + Creates test runner factory traits. + + The unique name of the kind of test runner created by the factory. + The description of test runner created by the factory. + + + + Gets the description of test runner created by the factory. + + + + + Gets the unique name of the kind of test runner created by the factory. + + + + + Provides options that control the operation of the test runner. + + + + + Creates a default set of options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets a read-only collection of configuration properties for the test runner. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Provides helper functions for test runner tools. + + + + + Creates a test runner given its factory name. + + The test runner factory name. + The test runner. + Thrown if is null. + + + + Presents a generated report to the user using the default viewing + application for the report's document type. + + The path of the report. + True if the report document was successfully opened. + + + + Arguments for an event raised to signal that an annotation has been discovered and + added to the test model. + + + + + Initializes the event arguments. + + The report. + The annotation that was added. + Thrown if is null. + + + + Gets the annotation that was added. + + + + + Gets the report. + + + + + Arguments for an event raised to indicate that the test runner disposal has finished. + + + + + Initializes the event arguments. + + True if the disposal was completed successfully. + + + + Arguments for an event raised to indicate that the test runner disposal has started. + + + + + Initializes the event arguments. + + + + + Arguments for an event raised to indicate that test exploration has finished. + + + + + Initializes the event arguments. + + True if test exploration was successful. + The report, including test model data on success. + Thrown if is null. + + + + Gets the report, including test model data on success. + + + + + Arguments for an event raised to indicate that test exploration has started. + + + + + Initializes the event arguments. + + The test package configuration. + The test exploration options. + The report lock-box which may be used to access the report asynchronously during execution. + Thrown if + or is null. + + + + Gets the report lock-box which may be used to access the report asynchronously during execution. + + + + + Gets the test exploration options. + + + + + Gets the test package. + + + + + Arguments for an event raised to indicate that the test runner initialization has finished. + + + + + Initializes the event arguments. + + True if the test runner was successfully initialized. + + + + Arguments for an event raised to indicate that the test runner initialization has started. + + + + + Initializes the event arguments. + + The test runner options. + Thrown if is null. + + + + Gets the test runner options. + + + + + Declares all of the events that may be raised by a . + + + + + The event raised to indicate that an annotation was added to the test model. + + + + + The event raised to indicate that the test runner disposal has finished. + + + + + The event raised to indicate that the test runner disposal has started. + + + + + The event raised to indicate that test exploration has finished. + + + + + The event raised to indicate that test exploration has started. + + + + + The event raised to indicate that the test runner initialization has finished. + + + + + The event raised to indicate that the test runner initialization has started. + + + + + The event raised to indicate that a log message was written by the test runner. + + + + + The event raised to indicate that a raw message was received by the test runner. + + + + + The event raised to indicate that test execution has finished. + + + + + The event raised to indicate that test execution has started. + + + + + The event raised to indicate that a subtree of tests was merged into the test model. + + + + + The event raised to indicate that a test step has finished execution. + + + + + The event raised to indicate that a test step has entered a new lifecycle phase. + + + + + The event raised to indicate that an attachment has been added to a test step log. + + + + + The event raised to indicate that a marker has been started within a test step log stream. + + + + + The event raised to indicate that a section has been started within a test step log stream. + + + + + The event raised to indicate that an attachment has been embedded into a test step log stream. + + + + + The event raised to indicate that a block has finished within a test step log stream. + + + + + The event raised to indicate that text has been written to a test step log stream. + + + + + The event raised to indicate that a test step dynamically added metadata to itself. + + + + + The event raised to indicate that a test step has started execution. + + + + + Arguments for an event raised when a raw message is received. + + + + + Initializes the event arguments. + + The message that was received. + Thrown if is null. + + + + Gets the message that was received. + + + + + Arguments for an event raised to indicate that test execution has finished. + + + + + Initializes the event arguments. + + True if test execution was successful. + The report, including test package run data on success. + Thrown if is null. + + + + Gets the report, including test package run data on success. + + + + + Arguments for an event raised to indicate that test execution has started. + + + + + Initializes the event arguments. + + The test package. + The test exploration options. + The test execution options. + The report lock-box which may be used to access the report asynchronously during execution. + Thrown if , + or is null. + + + + Gets the report lock-box which may be used to access the report asynchronously during execution. + + + + + Gets the test execution options. + + + + + Gets the test exploration options. + + + + + Gets the test package. + + + + + Arguments for an event raised to signal that a test was discovered and added to the test model. + + + + + Initializes the event arguments. + + The report. + The test at the top of the subtree that was added. + Thrown if is null. + + + + Gets the report. + + + + + Gets the test at the top of the subtree that was merged. + + + + + Dispatches test runner events to listeners. + + + + Initializes a new instance of the class + + + + The event raised to indicate that an annotation was added to the test model. + + + + + The event raised to indicate that the test runner disposal has finished. + + + + + The event raised to indicate that the test runner disposal has started. + + + + + The event raised to indicate that test exploration has finished. + + + + + The event raised to indicate that test exploration has started. + + + + + The event raised to indicate that the test runner initialization has finished. + + + + + The event raised to indicate that the test runner initialization has started. + + + + + The event raised to indicate that a log message was written by the test runner. + + + + + The event raised to indicate that a raw message was received by the test runner. + + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + Dispatches the event. + + The event arguments. + + + + The event raised to indicate that test execution has finished. + + + + + The event raised to indicate that test execution has started. + + + + + Subscribes to another event object such that the events will be forwarded + to the handlers registered on this dispatcher. + + The other events object. + Thrown if is null. + + + + The event raised to indicate that a subtree of tests was merged into the test model. + + + + + The event raised to indicate that a test step has finished execution. + + + + + The event raised to indicate that a test step has entered a new lifecycle phase. + + + + + The event raised to indicate that an attachment has been added to a test step log. + + + + + The event raised to indicate that a marker has been started within a test step log stream. + + + + + The event raised to indicate that a section has been started within a test step log stream. + + + + + The event raised to indicate that an attachment has been embedded into a test step log stream. + + + + + The event raised to indicate that a block has finished within a test step log stream. + + + + + The event raised to indicate that text has been written to a test step log stream. + + + + + The event raised to indicate that a test step dynamically added metadata to itself. + + + + + The event raised to indicate that a test step has started execution. + + + + + Base arguments for an event raised to provide information about a test step. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + Thrown if , + or is null. + + + + Gets the kind of step described using the metadata key. + + The step kind. + + + + Gets the report. + + + + + Gets the test data of the test that contains the test step. + + + + + Gets the test step run. + + + + + Arguments for an event raised to indicate that a test step has finished execution. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + Thrown if , + or is null. + + + + Arguments for an event raised to indicate that a test step has entered a new lifecycle phase. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The lifecycle phase name. + Thrown if , , or is null. + + + + Gets the lifecycle phase name. + + + + + Arguments for an event raised to indicate that an attachment has been added to a test step log. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The attachment. + Thrown if , or is null. + + + + Gets the attachment. + + + + + Arguments for an event raised to indicate that a marker block has been started within a test step log stream. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The log stream name. + The marker. + Thrown if , or is null. + + + + Gets the marker. + + + + + Arguments for an event raised to indicate that a section has been started within a test step log stream. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The log stream name. + The name of the section that was started. + Thrown if , , , or is null. + + + + Gets the name of the section that was started. + + + + + Arguments for an event raised to indicate that an attachment has been embedded into a test step log stream. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The log stream name. + The name of the attachment that was embedded. + Thrown if , , , or is null. + + + + Gets the name of the attachment that was embedded. + + + + + Arguments for an event raised to indicate that a block has been finished within a test step log stream. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The log stream name. + Thrown if , or is null. + + + + Base arguments for an event raised to indicate that a test step log stream has been modified in some way. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The log stream name. + Thrown if , or is null. + + + + Gets the log stream name. + + + + + Arguments for an event raised to indicate that text has been written to a test step log stream. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The log stream name. + The text that was written. + Thrown if , or is null. + + + + Gets the text that was written. + + + + + Arguments for an event raised to indicate that a test step dynamically added metadata to itself. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + The metadata key. + The metadata value. + Thrown if , , or is null. + + + + Gets the metadata key. + + + + + Gets the metadata value. + + + + + Arguments for an event raised to indicate that a test step has started execution. + + + + + Initializes the event arguments. + + The report. + The test data. + The test step run. + Thrown if , + or is null. + + + + Monitors events and writes debug messages to the + runner's logger. + + + + Initializes a new instance of the class + + + + Initializes the extension as part of extension installation. + + + + + Default implementation of + + + + Creates a test runner extension manager. + + The factory handles, not null. + The runtime, not null. + + + + Registers auto-activated extensions with the test runner. + + The test runner. + Thrown if is null. + + + + A test runner extension plugs augments the behavior oa + by attaching new behaviors to its event handlers. + + + + + Installs the extension into a test runner. + + The test runner events, not null. + The logger, not null. + + + + Gets or sets configuration parameters for the extension. + + + + + Creates instances of . + + + + + Creates the extension. + + The extension to create. + + + + Manages the set of available test runner extensions. + + + + + Registers auto-activated extensions with the test runner. + + The test runner. + Thrown if is null. + + + + The log extension writes a summary of test execution progress to the test runner's logger + so the user can monitor what's going on. + + + + Initializes a new instance of the class + + + + Initializes the extension as part of extension installation. + + + + + Logs an annotation. + + The annotation to log. + + + + Logs a message about a non-test case that has finished with some problem that + may have prevented other test cases from running correctly. + + The event. + + + + Logs a message about a test case that has finished. + + The event. + + + + Logs a message about a test case that has started. + + The event. + + + + Abstract implementation of a test runner extension. + for more details. + + + + Initializes a new instance of the class + + + + Gets the test runner event extension point. + + + + + Initializes the extension as part of extension installation. + + + + + Installs the extension into a test runner. + + The test runner events, not null. + The logger, not null. + + + + Gets the logger. + + + + + Gets or sets configuration parameters for the extension. + + + + + Provides traits for . + + + + Initializes a new instance of the class + + + + Gets or sets a condition (using the syntax of that + governs whether the extension provided by the factory should be automatically + installed on every run. + + + + + Provides utilities for manipulating test runner extensions. + + + + + Creates an extension from its specification. + + The extension specification. + The extension. + Thrown if the extension cannot be instantiated and configured. + Thrown if is null. + + + + Default implementation of a test project manager. + + + + + Constructor. + + The file system. + The Xml serializer. + + + + Loads a saved test project. + + The test project file to load. + The loaded test project. + Thrown if is null. + Thrown if the test project cannot be loaded. + Thrown if the test project is malformed. + + + + Creates a new project. + + The location of the project to be created. + The loaded test project. + Thrown if the project name is null or empty. + + + + Saves a test project. + + The test project. + The test project file to save. + Thrown if or + is null. + Thrown if the test project cannot be saved. + Thrown if the test project is malformed. + + + + Provides services for loading and saving test projects. + + + + + Loads a saved test project. + + The test project file to load. + The loaded test project. + Thrown if is null. + Thrown if the test project cannot be loaded. + Thrown if the test project is malformed. + + + + Creates a new project. + + The location of the project to be created. + The loaded test project. + Thrown if the project name is null or empty. + + + + Saves a test project. + + The test project. + The test project file to save. + Thrown if or + is null. + Thrown if the test project cannot be saved. + Thrown if the test project is malformed. + + + + A test project consists of a test package with a list of test files, a list + of test extensions, and report options. + + + + + Creates an empty test project. + + + + + Adds a test filter if not already added. + + The filter to add. + Thrown if is null. + + + + Adds a test runner extension if not already added. + + The test runner extension to add. + Thrown if is null. + + + + Adds a test runner extension specification if not already added. + + The test runner extension specification to add. + Thrown if is null. + + + + Applies the settings of another test project as an overlay on top of this one. + + The test project to overlay on top of this one. + Thrown if is null. + + + + Clears the list of test filters. + + + + + Clears the list of test runner extensions. + + + + + Clears the list of test runner extension specifications. + + + + + Creates a copy of the test project. + + The new copy. + + + + The default report directory relative path. + + + + + The default report name format. + + + + + The default test runner factory name. + + + + + The file extension for Gallio project files. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Returns true if has been set explicitly. + + + + + Removes a test filter. + + The filter to remove. + Thrown if is null. + + + + Removes a test runner extension. + + The test runner extension to remove. + Thrown if is null. + + + + Removes a test runner extension specification. + + The test runner extension specification to remove. + Thrown if is null. + + + + Gets or sets the folder to save generated reports to. + + Thrown if is null. + + + + The format for the filename of generated reports. + + Thrown if is null. + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Resets to its default value and sets to false. + + + + + Gets a read-only list of test filters. + + + + + Gets or sets the test package. + + Thrown if is null. + + + + Gets a read-only list of test runner extensions. + + + + + Gets a read-only list of test runner extension specifications. + + + + + Gets or sets the name of a to use for constructing + the at test execution time. + + Thrown if is null. + + + + Filter record for Gallio project. + + + + + Creates a filter description. + + The name of the filter. + The filter expression. + Thrown if or + is null. + + + + Creates a copy of the filter. + + The new copy. + + + + Gets or sets a string representation of the filter expression. + + Thrown if is null. + + + + Gets or sets the name of the filter. + + Thrown if is null. + + + + + Describes a test project in a portable manner for serialization. + + + + + Creates an empty test project. + + + + + Copies the contents of a test project. + + The source test project. + Thrown if is null. + + + + Initializes a test project with the contents of this structure. + + The test project to populate. + Thrown if is null. + + + + Makes the test project paths absolute given the specified base path. + + The base path. + Thrown if is null. + + + + Makes the test project paths relative to the specified base path. + + The base path. + Thrown if is null. + + + + Gets or sets the folder to save generated reports to. + + Thrown if is null. + + + + Gets or sets the format for the filename of generated reports. + + Thrown if is null. + + + + Gets a mutable list of named test filters for the project. + + + + + Gets or sets the test package. + + Thrown if is null. + + + + Gets a mutable list of test runner extensions used by the project. + + + + + Creates a test project with the contents of this structure. + + The test project. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + The default implementation of . + + + + + Creates a report manager. + + The report formatter handles. + Thrown if is null. + + + + Gets a report reader to load a report from the specified container. + + The report container. + The report reader. + Thrown if is null. + + + + Gets a report writer to save or format a report to the specified container. + + The report. + The report container. + The report writer. + Thrown if or is null. + + + + Formats the report indicated by the report writer. + + The report writer. + The formatter name. + The report formatter options. + The progress monitor. + Thrown if , , + or is null. + Thrown if there is no formatter with the specified name. + + + + Gets handles for all registered formatters. + + + + + Gets the report formatter with the specified name, or null if none. + + The formatter name. + The formatter, or null on failure. + Thrown if is null. + + + + Default implementation of a report reader. + + + + + Creates a report reader. + + The report container. + Thrown if is null. + + + + Loads the report from an XML file. + + If true, loads attachment + contents in referenced content files if they were not embedded otherwise + the attachment contents are not loaded (but may be loaded later using ). + The progress monitor. + The loaded report. + Thrown if is null. + + + + Loads referenced report attachments from the container. + + The report whose attachments are to be loaded. + The progress monitor. + Thrown if or is null. + + + + Gets the report container. + + + + + Default implementation of a report writer. + + + + + Creates a report writer for the specified report. + + The report. + The report container. + Thrown if or is null. + + + + Adds the path of a report document that has been created within the report container. + + The document path. + + + + Gets the report being generated. + + + + + Gets the report container. + + + + + Gets the paths of all report documents that have been generated within + the report container. + + + + + Saves the report as an XML file. + + The content disposition to use for all attachments. If + the content disposition is then + this method will automatically call to save the attachments. + The progress monitor. + Thrown is null. + + + + Saves all report attachments as individual content files to the container. + + The progress monitor. + Thrown if is null. + + + + Serializes the report to XML. + + The XML writer. + The content disposition to use for all attachments. + Thrown if is null. + + + + A file-system based representation of a report container that uses + ordinary files and folders to store report contents. + + + + + Creates a file-system based representation of a report container. + + The report directory path. + The report name. + Thrown if or + is null. + Thrown if is an empty string. + + + + Deletes the entire contents of the report in all of its formats. + + Thrown if an I/O error occurs. + + + + Replaces invalid characters in a file or directory name with underscores + and trims it if it is too long. + + The file or directory name. + The encoded file or directory name. + Thrown if is null. + + + + Opens a report file for reading. + + The relative path of the report file within the container. + The stream. + Thrown if is null. + Thrown if an I/O error occurs. + + + + Opens a report file for writing, overwriting any previous file with the same name. + + The path of the report file. + The content type of the file, or null if not specified. + The text encoding of the file, or null if not specified or if the file is binary. + The stream. + Thrown if is null. + Thrown if an I/O error occurs. + + + + Gets the full-path of the report directory. + + + + + Gets the base name of the report. + + + + + A report container that is used to load or save the contents of a report. + + + + + Deletes the entire contents of the report in all of its formats. + + Thrown if an I/O error occurs. + + + + Replaces invalid characters in a file or directory name with underscores + and trims it if it is too long. + + The file or directory name. + The encoded file or directory name. + Thrown if is null. + + + + Opens a report file for reading. + + The relative path of the report file within the container. + The stream. + Thrown if is null. + Thrown if an I/O error occurs. + + + + Opens a report file for writing, overwriting any previous file with the same name. + + The path of the report file. + The content type of the file, or null if not specified. + The text encoding of the file, or null if not specified or if the file is binary. + The stream. + Thrown if is null. + Thrown if an I/O error occurs. + + + + Gets the base name of the report. + + + + + A report formatter provides a strategy for formatting reports for human consumption. + + + + + Formats the report indicated by the report writer. + + The report writer. + The report formatter options. + The progress monitor. + Thrown if , + or is null. + + + + The report manager provides services for manipulating reports. + + + + + Gets a report reader to load a report from the specified container. + + The report container. + The report reader. + Thrown if is null. + + + + Gets a report writer to save or format a report to the specified container. + + The report. + The report container. + The report writer. + Thrown if or is null. + + + + Formats the report indicated by the report writer. + + The report writer. + The formatter name. + The report formatter options. + The progress monitor. + Thrown if , , + or is null. + Thrown if there is no formatter with the specified name. + + + + Gets handles for all registered formatters. + + + + + Gets the report formatter with the specified name, or null if none. + + The formatter name. + The formatter, or null on failure. + Thrown if is null. + + + + A report writer provides services for loading a previously saved report + from a . + + + + + Loads the report from an XML file. + + If true, loads attachment + contents in referenced content files if they were not embedded otherwise + the attachment contents are not loaded (but may be loaded later using ). + The progress monitor. + The loaded report. + Thrown if is null. + + + + Loads referenced report attachments from the container. + + The report whose attachments are to be loaded. + The progress monitor. + Thrown if or is null. + + + + Gets the report container. + + + + + A report writer provides services for formatting or saving a report + to a . + + + + + Adds the path of a report document that has been created within the report container. + + The document path. + + + + Gets the report being generated. + + + + + Gets the report container. + + + + + Gets the paths of all report documents that have been generated within + the report container. + + + + + Saves the report as an XML file. + + The content disposition to use for all attachments. If + the content disposition is then + this method will automatically call to save the attachments. + The progress monitor. + Thrown is null. + + + + Saves all report attachments as individual content files to the container. + + The progress monitor. + Thrown if is null. + + + + Serializes the report to XML. + + The XML writer. + The content disposition to use for all attachments. + Thrown if is null. + + + + Utilities for working with . + + + + + Recursively copies files and folders from the source path in the native + file system to the destination path within the report container. + + The container. + The source file or directory path in the native file system. + The destination file or directory path in the report container. + Thrown if , + or is null. + + + + Provides options to report formatters. + + + + + Creates a default set of options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets a read-only collection of configuration properties for the report formatter. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Describes traits of an component. + + + + + Creates report formatter traits. + + The unique name of the report format. + The description of report format. + + + + Gets the description of the report format. + + + + + Gets the unique name of the report format. + + + + + Describes a log entry for reporting purposes. + + + + Initializes a new instance of the class + + + + Gets or sets the log message details, such as an exception. + + + + + Gets or sets the log message. + + + + + Gets or sets the log message severity. + + + + + A report includes a description of the test package, the model objects, + the combined results of all test runs and summary statistics. + + + + + Creates an empty report. + + + + + Adds a log entry to the report. + + The log entry to add. + Thrown if is null. + + + + Gets a mutable list of log entries. + + + + + Gets or sets the test model, or null if none. + + + + + Gets or sets the test package configuration, or null if none. + + + + + Gets or sets the test package run results, or null if none. + + + + + Collects summary statistics about test execution for reporting purposes. + + + + + Creates an empty statistics record. + + + + + Updates the test outcome statistics counters with an the outcome of a test. + + The test outcome. + + + + Gets or sets the number of assertions evaluated. + + + + + Gets or sets the total duration summarized tests in seconds. + + + + + Gets or sets the number of test cases that ran and failed. + + + + + Formats a single line of text summarizing test case results. + + + + + Gets the number of tests with the specified outcome. + + The outcome. + The number of tests with the specified outcome. + + + + Gets or sets the number of test cases that ran and were inconclusive. + + + + + Merges statistics from a test step run, incrementing the relevant counters. + + The test step run. + Thrown if is null. + + + + Gets or sets the test outcome summaries. + + Thrown if is null. + + + + Gets or sets the number of test cases that ran and passed. + + + + + Gets or sets the number of test cases that were run. + + + + + Ssets the number of tests with the specified outcomee. + + The outcome. + The count. + Thrown if is less than 0. + + + + Gets or sets the number of test cases that did not run. + + + + + Gets or sets the total number of test steps. + + + + + Gets or sets the total number of test cases. + + + + + Describes the number of test cases with a particular . + + + + Initializes a new instance of the class + + + + Gets or sets the number of test cases with the specified outcome. + + + + + Gets or sets the outcome. + + + + + Summarizes the execution of a test package for reporting purposes. + + + + + Creates an empty package run. + + + + + Recursively enumerates all test step runs including the root test step run. + + + + + Gets or sets the time when the package run ended. + + + + + Gets or sets the root test step run, or null if the root test has not run. + + + + + Gets or sets the time when the package run started. + + + + + Gets or sets the statistics for the package run. + + Thrown if is null. + + + + Summarizes the execution of a single test step for reporting purposes. + + + + + Creates a test run step. + + Information about the step. + Thrown if is null. + + + + Recursively enumerates all test step runs including this one. + + + + + Gets the list of child step runs. + + + + + Gets or sets the time when the test run ended. + + + + + Gets or sets the test result from the run. + + Thrown if is null. + + + + Gets or sets the time when the test run started. + + + + + Gets or sets information about the step. + + Thrown if is null. + + + + Gets or sets the test log. + + Thrown if is null. + + + + Default implementation of . + + + + + Initializes the runtime. + + The registry. + The plugin loader. + The assembly loader. + The runtime setup options. + Thrown if , + , or + is null. + + + + Adds a log listener that will receive log messages dispatched to the runtime logger. + + The log listener to add. + Thrown if is null. + + + + Gets the runtime assembly loader. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Gets the list of all plugin assembly bindings. + + The assembly bindings. + + + + Gets a deep copy of the runtime setup used to configure this runtime. + + The runtime setup. + + + + Initializes the runtime. + + Thrown if the runtime could not be initialized. + + + + Gets the runtime logger. + + + + + An event that is fired when a log message is sent to the runtime logger. + + + + + Gets the plugin, service and component registry. + + + + + Removes a log listener so that it will no longer receive log messages dispatched to the runtime logger. + + The log listener to remove. + Thrown if is null. + + + + Gets the resource locator. + + + + + Gets the condition context that is used to enable or disable plugins, + components and services based on characteristics of the runtime environment. + + + + + Gets the service locator. + + + + + Verifies that the runtime is correctly installed. Writes details to the log. + + True if the installation appears ok. + + + + A configuration section handler for Gallio used to register + Gallio components in applications and in plugins. + + + + Initializes a new instance of the class + + + + Creates a configuration section handler. + + + Parent object. + + + Configuration context object. + + + Section XML node. + + + The created section handler object. + + + + + The name of the Gallio section: "gallio". + + + + + Describes the configuration of a Gallio installation. + + + + Initializes a new instance of the class + + + + Adds an additional plugin directory if not already in the configuration. + + The relative or absolute path of a directory to be + searched for plugin configuration files in addition to the + primary Gallio directories. + Thrown if is null. + + + + Gets a read-only list of additional plugin directories. + + + + + Clears the list of additional plugin directories. + + + + + Get or sets the folder where Gallio was installed, or null if Gallio is not installed. + + + + + Gets or sets the unique id of this Gallio installation. + + + + + Get or sets the version that was installed, or null if Gallio is not installed. + + + + + Loads the configuration from the registry. + + The installed configuration. + + + + Removes an additional plugin directory. + + The plugin directory to remove. + Thrown if is null. + + + + Saves the additional plugin directories into the registry. + + + + + Saves the installation id into the registry. + + + + + The runtime is instantiated within the test runner to provide a suitable + hosting environment for test enumeration and execution. + + + + + Adds a log listener that will receive log messages dispatched to the runtime logger. + + The log listener to add. + Thrown if is null. + + + + Gets the runtime assembly loader. + + + + + Gets the list of all plugin assembly bindings. + + The assembly bindings. + + + + Gets a deep copy of the runtime setup used to configure this runtime. + + The runtime setup. + + + + Initializes the runtime. + + Thrown if the runtime could not be initialized. + + + + Gets the runtime logger. + + + + + An event that is fired when a log message is sent to the runtime logger. + + + + + Gets the plugin, service and component registry. + + + + + Removes a log listener so that it will no longer receive log messages dispatched to the runtime logger. + + The log listener to remove. + Thrown if is null. + + + + Gets the resource locator. + + + + + Gets the condition context that is used to enable or disable plugins, + components and services based on characteristics of the runtime environment. + + + + + Gets the service locator. + + + + + Verifies that the runtime is correctly installed. Writes details to the log. + + True if the installation appears ok. + + + + Provides functions for obtaining runtime services. + + + + + Gets the runtime's assembly loader. + + Thrown if the runtime has not been initialized. + + + + Gets the runtime instance. + + Thrown if the runtime has not been initialized. + + + + The event dispatched when the value of the current runtime + changes. + + + + + Returns true if the runtime has been initialized. + + + + + Gets the runtime's logger, or a if the runtime is not initialized. + + + + + Gets the runtime's registry. + + Thrown if the runtime has not been initialized. + + + + Gets the runtime's resource locator. + + Thrown if the runtime has not been initialized. + + + + Gets the path of the Gallio runtime components. + + The runtime path. + + + + Gets the runtime's service locator. + + Thrown if the runtime has not been initialized. + + + + Sets the runtime instance. + + The runtime instance, or null if none. + + + + Initializes and shuts down the runtime. + + + + + Initializes the runtime. + + The runtime setup parameters. + The logger to attach, or null if none. + An object that when disposed automatically calls . + This is particularly useful in combination with the C# "using" statement + or its equivalent. + Thrown if is null. + Thrown if the runtime has already been initialized. + + + + Shuts down the runtime if it is currently initialized. + + + + + A condition context that is used to enable or disable plugins, + components and services based on characteristics of the runtime environment. + + + + Initializes a new instance of the class + + + + Returns true if the context contains a value for a given property. + + The property namespace, not null. + The property identifier, not null. + True if the context has the specified property. + + + + An exception that expresses a problem performing a runtime service. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Provides configuration parameters for setting up the . + + + + + Creates a default runtime setup. + + + + + Adds a plugin directory if not already in the configuration. + + The relative or absolute path of a directory to be + searched for plugin configuration files in addition to the + primary Gallio directories. + Thrown if is null. + + + + Makes all paths in this instance absolute. + + The base directory for resolving relative paths, + or null to use the current directory. + + + + Clears the list of plugin directories. + + + + + Gets or sets the path of the primary configuration file to be + loaded by the runtime (if it exists). + + + + + Creates a deep copy of the runtime setup parameters. + + The copy. + + + + Gets or sets the installation configuration which specifies characteristics + about the Gallio installation on the local machine, or null to determine it automatically. + + + + + Gets a read-only list of relative or absolute paths of directories to be + searched for plugin configuration files in addition to the + primary Gallio directories. + + + + + Removes a plugin directory. + + The plugin directory to remove. + Thrown if is null. + + + + Gets or sets the runtime path, or null to determine it automatically + based on the location of the application itself. + + + + + Sets the configuration file path to the *.config file associated with an assembly. + + The assembly. + Thrown if is null. + + + + Allows control of command line parsing. + + + + + Allows control of command line parsing. + + Specifies the error checking to be done on the argument. + + + + The description of the argument. + + + + + The error checking to be done on the argument. + + + + + Returns true if the argument did not have an explicit long name specified. + + + + + Returns true if the argument did not have an explicit short name specified. + + + + + The long name of the argument. + + + + + The short name of the argument. + + + + + Gets or sets an array of additional synonyms that are silently accepted. + + + + + The description of the argument value. + + + + + Used to control parsing of command line arguments. + + + + + Indicates that this field is required. An error will be displayed + if it is not present when parsing arguments. + + + + + Only valid in conjunction with Multiple. + Duplicate values will result in an error. + + + + + Inidicates that the argument may be specified more than once. + Only valid if the argument is a collection + + + + + The default type for non-collection arguments. + The argument is not required, but an error will be reported if it is specified more than once. + + + + + For non-collection arguments, when the argument is specified more than + once no error is reported and the value of the argument is the last + value which occurs in the argument list. + + + + + The default type for collection arguments. + The argument is permitted to occur multiple times, but duplicate + values will cause an error to be reported. + + + + + Parser for command line arguments. + + + + + Creates a new command line argument parser. + + The argument type containing fields decorated + with . + Thrown if is null. + + + + Creates a new command line argument parser. + + The argument type containing fields decorated + with + The delegate to use for reading response files instead of the default, + or null to disable reading from response files. + Thrown if is null. + + + + Parses an argument list. + + The arguments to parse. + The destination of the parsed arguments. + The error reporter. + True if no parse errors were encountered. + + + + Prints a user friendly usage string describing the command line argument syntax. + + The command line output. + + + + Prints a user friendly usage string describing the command line argument syntax in a message box. + + The message box caption. + Thrown if is null. + + + + A delegate used in error reporting. + + + + + Responsible for creating output. + + + + + Initializes new instance of CommandLineOutput. + + The console. + + + + Initializes new instance of CommandLineOutput that outputs to specified stream. + + Text writer. + + + + Initializes new instance of CommandLineOutput that outputs to specified stream. + + Text writer. + The output width. + + + + Maximum line length allowed before the text will be wraped. + + + + + Prints out a new line. + + + + + Output Stream + + + + + Prints help for a specified argument. + + The argument prefix, such as "/", or null or empty if none. + The argument's long name, or null or empty if none. + The argument's short short name, or null or empty if none. + The argument's description, or null or empty if none. + The argument's value label such as "path", or null or empty if none. + The argument's value type, or null if none. + + + + Outputs text with specified indentation. + + Text to output possibly including newlines. + Number of blank spaces to indent the first line. + + + + Outputs text with specified indentation. + + Text to output possibly including newlines. + Number of blank spaces to indent all but the first line. + Number of blank spaces to indent the first line. + + + + A base class for implementing robust console applications. + + + + Initializes a new instance of the class + + + + Gets or sets the application name. + + Thrown if is null. + + + + Get or sets the application title. + + Thrown if is null. + + + + Gets or sets the application version. + + Thrown if is null. + + + + Gets the argument parser. + + + + + Gets or sets the parsed command-line arguments. + + Thrown if is null. + + + + Gets the command-line output formatter, or null if the program is not running. + + + + + Gets the console, or null if the program is not running. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Handles a fatal exception that escaped the method. + + The exception. + The exit code to return. + + + + Parses the arguments. + + The command-line arguments. + True if the arguments were parsed successfully. + + + + Runs the program. + + The console. + The command-line arguments. + Thrown if + or is null. + Thrown if the program has already started running. + + + + Runs the program. + + The command-line arguments. + The program exit code. + + + + Displays an error message to the console. + + The error message. + + + + Displays help text to the console. + + + + + Indicates that this argument is the default argument. + + + + + Indicates that this argument is the default argument. + + Specifies the error checking to be done on the argument. + + + + When set to true, the default argument will consume any unrecognized command switches. + Otherwise an error will be thrown if an unrecognized switch is used. + + + + + A rich console provides a number of services that enable a console to be + shared among several cooperating tasks that are independently updating + different portions of the display. + + + + + The event raised when console cancelation occurs. + + + + + Gets the zero-based column index the cursor is located at. + + Thrown if is true. + + + + Gets the zero-based row index the cursor is located at. + + Thrown if is true. + + + + Gets the error stream writer. + + + + + Gets or sets whether the footer is visible. + + + + + Gets or sets the foreground color of the console. + + + + + Gets or sets whether the cancelation function is enabled. + If false, cancelation events will not be sent. + + + + + Gets or sets whether cancelation has occurred. + + + + + Returns true if the console is being redirected and therefore the + output should be as simple as possible. + + + + + Gets the output stream writer. + + + + + Resets the console colors. + + + + + Sets a pair of delegates that together display a footer at the bottom + of the console. + + A delegate to display the footer. + A delegate to hide the footer, leaving the custor at + the beginning of the line where the footer used to begin. + + + + Gets a synchronization object that a task can lock to ensure + that it is the only thread currently accessing the console. + + + + + Gets or sets the console's title. + + Thrown if is true. + + + + Gets the width of the console. + + + + + Writes a character. + + The character to write. + + + + Writes a string. + + The string to write. + + + + Writes a new line. + + + + + Writes a string followed by a new line. + + The string to write. + + + + An implementation of that targets the + native . + + + + + The event raised when console cancelation occurs. + + + + + Gets the zero-based column index the cursor is located at. + + Thrown if is true. + + + + Gets the zero-based row index the cursor is located at. + + Thrown if is true. + + + + Gets the error stream writer. + + + + + Gets or sets whether the footer is visible. + + + + + The application will forcibly terminate if the cancel key is pressed + times within no more than + milliseconds. + + + + + The application will forcibly terminate if the cancel key is pressed + times within no more than + milliseconds. + + + + + Gets or sets the foreground color of the console. + + + + + Gets the singleton instance of the native console. + + + + + Gets or sets whether the cancelation function is enabled. + If false, cancelation events will not be sent. + + + + + Gets or sets whether cancelation has occurred. + + + + + Returns true if the console is being redirected and therefore the + output should be as simple as possible. + + + + + Gets the output stream writer. + + + + + Resets the console colors. + + + + + Sets a pair of delegates that together display a footer at the bottom + of the console. + + A delegate to display the footer. + A delegate to hide the footer, leaving the custor at + the beginning of the line where the footer used to begin. + + + + Gets a synchronization object that a task can lock to ensure + that it is the only thread currently accessing the console. + + + + + Gets or sets the console's title. + + Thrown if is true. + + + + Gets the width of the console. + + + + + Writes a character. + + The character to write. + + + + Writes a string. + + The string to write. + + + + Writes a new line. + + + + + Writes a string followed by a new line. + + The string to write. + + + + Reads the contents of a response file. + + The response file name, never null. + The plain text contents of the file. + + + + A logger that sends all output to the console and displays messages in color + according to their status. + + + + + Creates a logger. + + The console. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + Converts arrays from one-dimensional arrays of one element type to another. + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + An abstract base class implementation of + that mostly validates arguments and provides a default implement for + based on . + + + + Initializes a new instance of the class + + + + Determines whether the converter can convert a value of type + to type . + + The source type. + The target type. + True if the converter supports this conversion. + Thrown if or + is null. + + + + Implements . + + The source type, never null. + The target type, never null. + True if the conversion is supported. + + + + Converts the value to type . + + The value to convert. + The target type. + The converted value. + Thrown if is null. + Thrown the requested conversion was not supported. + + + + Implements + The source value. + The target type, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type. + The target type. + The conversion cost. + Thrown if or + is null. + + + + Implements . + + The source type, never null. + The target type, never null. + The conversion cost. + + + + Describes the relative cost of performing a conversion so that different + conversions can be ranked by cost. + + + + + Creates a conversion cost. + + The number of units of work required by the conversion. + Thrown if is negative. + + + + Adds this conversion cost with the other and returns the sum. + + The other conversion cost. + The summed conversion cost. + + + + The conversion is the best possible conversion available. + + + + + Compares the current object with another object of the same type. + + + An object to compare with this object. + + + A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings: + + Value + + Meaning + + Less than zero + + This object is less than the parameter. + + Zero + + This object is equal to . + + Greater than zero + + This object is greater than . + + + + + The conversion is a poor default choice. It costs a sufficient number of units + of work to perform to ensure that a non-default conversion will be chosen if possible. + + + + + The conversion is not supported. + + + + + Returns true if the conversion is not supported. + + + + + The conversion costs the maximum possible amount of work to perform. + + + + + Returns the fully qualified type name of this instance. + + + A containing a fully qualified type name. + + + + + The conversion costs a typical amount of work to perform. + + + + + Gets the cost value. + + + + + The conversion has zero cost because no work is required. + + + + + Service locator for . + + + + + Gets the global conveter singleton. + + + + + Converts values among types. + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + A conversion rule encapsulates an algorithm for converting a value from a source + type to a target type. + + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + A converter converts a value from a source type to a target type. + + + + + Determines whether the converter can convert a value of type + to type . + + The source type. + The target type. + True if the converter supports this conversion. + Thrown if or + is null. + + + + Converts the value to type . + + The value to convert. + The target type. + The converted value. + Thrown if is null. + Thrown the requested conversion was not supported. + + + + Gets the cost of converting a value of type + to type . + + The source type. + The target type. + The conversion cost. + Thrown if or + is null. + + + + A null implementation of a converter that does not actually support + converting values. + + + + Initializes a new instance of the class + + + + Implements + The source value. + The target type, never null. + The converted value. + + + + Implements . + + The source type, never null. + The target type, never null. + The conversion cost. + + + + Gets a singleton instance of the null converter. + + + + + Converts an into a using . + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + A rule-based converter uses a set of s to + perform conversions. + + + + + Creates a rule-based converter. + + The rules to use. + Thrown if is null. + + + + Implements + The source value. + The target type, never null. + The converted value. + + + + Implements . + + The source type, never null. + The target type, never null. + The conversion cost. + + + + Converts a into an assuming + the string is valid xml. + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + Converts objects to objects. + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + Converts an into a by value or outer xml. + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + Converts objects to XML serializable + objects that have the . + + + + Initializes a new instance of the class + + + + Converts the value to type . + + The value to convert, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The converted value. + + + + Gets the cost of converting a value of type + to type . + + The source type, never null. + The target type, never null. + A converter that may be used to recursively + convert the contents of a composite object from one type to another, never null. + The conversion cost. + + + + Describes different possible outcomes from attaching a debugger to a process. + + + + + The debugger could not attach to the process. + + + + + The debugger was already attached to the process. + + + + + The debugger has just been attached to the process. + + + + + Provides options that configure the debugger. + + + + + Creates a default set of debugger options. + + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Clears the collection of properties. + + + + + Creates a copy of the options. + + The copy. + + + + Gets a read-only collection of configuration properties for the debugger. + + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Default implementation of a debugger manager. + + + + Initializes a new instance of the class + + + + Gets a debugger. + + The debugger setup options. + The logger for writing progress and failure messages. + The debugger. + Thrown if or is null. + + + + Describes different possible outcomes from detaching a debugger from a process. + + + + + The debugger could not be detached from the process and remains attached. + + + + + The debugger was already detached from the process. + + + + + The debugger has just been detached from the process. + + + + + Provides control over a debugger. + + + + + Attaches the debugger to a process. + + The process to which the debugger should be attached. + A result code to indicate whether the debugger was attached. + Thrown if is null. + + + + Detaches the debugger from a process. + + The process from which the debugger should be detached. + A result code to indicate whether the debugger was detached. + Thrown if is null. + + + + Returns true if the debugger is attached to a process. + + The process to which the debugger should be attached. + True if the debugger is already attached. + Thrown if is null. + + + + Launches a process and attaches the debugger. + + The process start information. + The process that was started, or null if the process could not be launched with the debugger. + Thrown if is null. + + + + Obtains a reference to a debugger. + + + + + Gets a debugger. + + The debugger setup options. + The logger for writing progress and failure messages. + The debugger. + Thrown if or is null. + + + + A null implementation of a debugger. All services return do nothing results. + + + + Initializes a new instance of the class + + + + Attaches the debugger to a process. + + The process to which the debugger should be attached. + A result code to indicate whether the debugger was attached. + Thrown if is null. + + + + Detaches the debugger from a process. + + The process from which the debugger should be detached. + A result code to indicate whether the debugger was detached. + Thrown if is null. + + + + Returns true if the debugger is attached to a process. + + The process to which the debugger should be attached. + True if the debugger is already attached. + Thrown if is null. + + + + Launches a process and attaches the debugger. + + The process start information. + The process that was started, or null if the process could not be launched with the debugger. + Thrown if is null. + + + + A caching plugin loader. + + + + + Creates a caching plugin loader. + + + + + Clears the plugin cache belonging to the current user. + + + + + Loads plugins by recursively searching the plugin paths for *.plugin files. + + A function that receives plugin metadata as it + becomes available, not null. + + + + A handle for a lazily instantiated component and its traits. + + + + + Creates an instance of a typed component handle for the specified descriptor. + + The component descriptor. + The service type. + The traits type. + The appropriately typed component handle. + Thrown if is null. + Thrown if the described component's service or traits are not compatible with a handle of this type. + Thrown if the described component's service type or traits type cannot be resolved. + + + + Creates an instance of a typed component handle for the specified descriptor. + + The component descriptor. + The appropriately typed component handle. + Thrown if is null. + Thrown if the described component's service type or traits type cannot be resolved. + + + + Creates an instance of a typed component handle for the specified component and traits instance. + The component handle will have a stub component descriptor for testing purposes. + + The component id. + The component instance. + The component traits. + The service type. + The traits type. + The appropriately typed component handle. + Thrown if , + or is null. + Thrown if the described component's service or traits are not compatible with a handle of this type. + Thrown if the described component's service type or traits type cannot be resolved. + + + + Gets the component descriptor. + + + + + Gets the component instance. + + The component instance. + Thrown if the component cannot be resolved. + + + + Gets the component traits. + + The component traits. + Thrown if the traits cannot be resolved. + + + + Gets the component id. + + + + + Returns true if the specified type is a component handle type. + + The type to examine. + True if the type is a component handle type. + Thrown if is null. + + + + Gets the service type. + + The service type. + + + + Returns the component's id. + + The component id. + + + + Gets the traits type. + + The traits type. + + + + A typed handle for a lazily instantiated component and its traits. + + The type of service implemented by the component. + The type of traits provided by the component. + + + + Gets the component instance. + + The component instance. + Thrown if the component cannot be resolved. + + + + Gets the component traits. + + The component traits. + Thrown if the traits cannot be resolved. + + + + Gets the service type. + + The service type. + + + + Gets the traits type. + + The traits type. + + + + Provides information used to register a component. + + + + + Creates a component registration. + + The plugin to which the component will belong. + The service implemented by the component. + The component id. + The component type name, or null to use the default component type specified by the service. + Thrown if , , + is null. + + + + Gets or sets the component handler factory. + + Thrown if is null. + + + + Gets or sets the component id. + + Thrown if is null. + + + + Gets or sets the component properties. + + Thrown if is null. + + + + Gets or sets the component type name, or null to use the default component type specified by the service. + + + + + Gets or sets the plugin to which the component will belong. + + Thrown if is null. + + + + Gets or sets the service implemented by the component. + + Thrown if is null. + + + + Gets or sets the traits properties. + + Thrown if is null. + + + + Resolves object dependencies that are discovered during dependency injection + with the help of a service locator, a resource locator, and a built in set of conversions. + + + + + Creates an object dependency resolver. + + The service locator. + The resource locator. + Thrown if , + is null. + + + + Resolves a dependency. + + The parameter name. + The parameter type. + An optional configuration argument that supplies a value + for the parameter or describes the means by which the value should be obtained, or null if none. + An object that describes whether the dependency was satisfied and the value it was assigned. + Thrown if or + is null. + + + + Default plugin implementation. + + + + Initializes a new instance of the class + + + + Specifies the result of an attempt to resolve a dependency. + + + + + Returns true if the dependency was satisfied. + + + + + Creates a result object that represents a satisfied dependency. + + The value provided for the dependency. + The result object. + + + + Creates a result object that represents an unsatisfied dependency. + + The result object. + + + + Returns the value used to satisfy the dependency. + + Thrown if the dependency was not satisfied. + + + + Describes a component. + + + + + Gets the component handler factory. + + + + + Gets the component's id. + + + + + Gets the parameter properties. + + + + + Gets the component type name. + + + + + Gets the reason the component was disabled. + + Thrown if is false. + + + + Returns true if the plugin that provides the component is disabled + or if the service implemented by the component is disabled. + + + + + Gets the descriptor of the plugin that provides the component. + + + + + Resolves the component instance. + + The component instance. + Thrown if an error occurs during resolution. + + + + Resolves the component handler. + + The component handler. + Thrown if an error occurs during resolution. + + + + Resolves the component type. + + The component type. + Thrown if an error occurs during resolution. + + + + Resolves the component traits. + + The component traits. + Thrown if an error occurs during resolution. + + + + Resolves the traits handler. + + The traits handler. + Thrown if an error occurs during resolution. + + + + Gets the descriptor of the service implemented by the component. + + + + + Gets the traits properties. + + + + + Provides a view of registered components along with methods for resolving them. + + + + + Gets descriptors for all components that implement a service with a given id. + + The service id. + The list of component descriptors. + Thrown if is null. + + + + Gets descriptors for all components that implement a service of a given type. + + The service type. + The list of component descriptors. + Thrown if is null. + + + + Gets descriptors for all components that implement a service of a given type by name. + + The service type name. + The list of component descriptors. + Thrown if is null. + + + + Gets a component descriptor by its id, or null if not found. + + The component id. + The component descriptor, or null if not found. + Thrown if is null. + + + + A handler activates instances of a plugin, component or traits object. + + + + + Activates the instance. + + The activated instance. + + + + A handler factory creates handlers for activating plugin, component and traits instances. + + + + + Creates a handler. + + The object dependency resolver, not null. + The contract type: the handler will ensure that the objects it produces are subclasses or implementations of the contract type. + The object type: the handler will produce objects that are (possibly decorated) instances of the object type. + The configuration properties for the objects produced by the handler. + The handler. + + + + A handler factory for pre-manufactured instances. + + + + + Creates an instance handler factory given a particular pre-manufactured instance. + + The instance to be returned by the handler. + Thrown if is null. + + + + Creates a handler. + + The object dependency resolver, not null. + The contract type: the handler will ensure that the objects it produces are subclasses or implementations of the contract type. + The object type: the handler will produce objects that are (possibly decorated) instances of the object type. + The configuration properties for the objects produced by the handler. + The handler. + + + + Resolves object dependencies and parameters. + + + + + Resolves a dependency. + + The parameter name. + The parameter type. + An optional configuration argument that supplies a value + for the parameter or describes the means by which the value should be obtained, or null if none. + An object that describes whether the dependency was satisfied and the value it was assigned. + Thrown if or + is null. + + + + Represents an activated plugin. + + + + + A plugin catalog describes the configuration of a collection of plugins that + are to be installed in a registry. + + + + + Adds a plugin to the catalog. + + The plugin to add. + The plugin base directory. + Thrown if + or is null. + + + + Registers the contents of the catalog into the specified registry. + + The registry. + Thrown if is null. + + + + Describes a plugin. + + + + + Gets the list of plugin assembly bindings. + + + + + Gets the base directory that contains the plugin's definition and associated resources. + + + + + Disables the plugin. + + The reason the plugin was disabled. + Thrown if is null. + + + + Gets the reason the plugin was disabled. + + Thrown if is false. + + + + Gets a condition governing the activation of the plugin, + or null if there is no condition. The plugin will be disabled if a + condition is provided but is not satisfied. + + + + + Gets the paths of files that belong to the plugin relative to the + plugin base directory. + + + + + Gets an enumeration of all absolute paths to be searched in order to find a given resource. + + The relative or absolute path of the resource to find or null to return + the paths of the search directories themselves. + An enumeration of search paths. + + + + Returns true if the plugin is disabled. + + + + + Gets the list of plugins upon which this plugin depends directly or indirectly. + + + + + Gets the plugin handler factory. + + + + + Gets the plugin's id. + + + + + Gets the plugin properties. + + + + + Gets the plugin type name. + + + + + Gets the list of additional relative or absolute probing paths in which to attempt to locate + referenced assemblies. + + + + + Gets the recommended installation path for the plugin files relative to + the runtime installation directory, or null if there is no preference. + + + + + Resolves the plugin instance. + + The plugin instance. + Thrown if an error occurs during resolution. + + + + Resolves the plugin handler. + + The plugin handler. + Thrown if an error occurs during resolution. + + + + Resolves the plugin type. + + The plugin type. + Thrown if an error occurs during resolution. + + + + Resolves the plugin traits. + + The plugin traits. + Thrown if an error occurs during resolution. + + + + Resolves the traits handler. + + The traits handler. + Thrown if an error occurs during resolution. + + + + Gets the traits properties. + + + + + Populates a plugin catalog with plugin metadata. + + + + + Adds a plugin path. + + The plugin path to add. + Thrown if is null. + + + + Adds a plugin definition as XML. + + The plugin xml. + The plugin base directory. + Thrown if + or is null. + + + + Defines a constant to be used by the preprocessor. + + The constant name. + Thrown if is null. + + + + Gets or sets the installation id. + + + + + Populates a catalog with plugin metadata derived from the currently + registered plugin data sources. + + The plugin catalog to populate. + Thrown if + is null. + + + + Provides a view of registered plugins along with methods for resolving them. + + + + + Gets a plugin descriptor by its id, or null if not found. + + The plugin id. + The plugin descriptor, or null if not found. + Thrown if is null. + + + + A registry of plugins, services and components. + + + + + Gets a view of all registered components. + + + + + Gets a view of all registered plugins. + + + + + Registers a component and returns its descriptor. + + The component registration. + The new component descriptor. + Thrown if is null. + Thrown if there is already a component registered with the same id + or if the plugin or service does not belong to this registry or if the component implements a service + provided by a plugin that was not listed as a plugin dependency of the component's plugin. + + + + Registers a plugin and returns its descriptor. + + The plugin registration. + The new plugin descriptor. + Thrown if is null. + Thrown if there is already a plugin registered with the same id + or if the registration contains errors. + + + + Registers a service and returns its descriptor. + + The service registration. + The new service descriptor. + Thrown if is null. + Thrown if there is already a service registered with the same id or type name + or if the plugin does not belong to this registry. + + + + Gets a resource locator based on the contents of the registry. + + + + + Gets a service locator based on the contents of the registry. + + + + + Gets a view of all registered services. + + + + + Locates resources owned by plugins and other components. + + + + + Resolves a resource Uri to a full path. + + The resource Uri. + The resolved full path of the resource. + Thrown if is null. + Thrown if the uri cannot be resolved. + + + + Describes a service. + + + + + Gets the default component type name for this service, or null if there is no default component type. + + + + + Gets the reason the service was disabled. + + Thrown if is false. + + + + Returns true if the plugin that provides the service is disabled. + + + + + Gets the descriptor of the plugin that provides the service. + + + + + Resolves the service type. + + The service type. + Thrown if an error occurs during resolution. + + + + Resolves the traits type. + + The traits type. + Thrown if an error occurs during resolution. + + + + Gets the service's id. + + + + + Gets the service type name. + + + + + Gets the traits handler factory. + + + + + Resolves runtime services. + + + + + Returns true if there is a component registered with the given component id and it has not been disabled. + + The component id. + True if there is a component registered with the given component id. + Thrown if is null. + + + + Returns true if the there is a service registered with the specified type and it has not been disabled. + + The service type. + True if there is at least one component registered for the given service type. + Thrown if is null. + + + + Resolves a single component instance that implements a given service type. + + The service type. + The component instance that implements the service. + Thrown if no component was found + or if a component could not be resolved. + + + + Resolves a single component instance that implements a given service type. + + The service type. + The component instance that implements the service. + Thrown if is null. + Thrown if no component was found + or if a component could not be resolved. + + + + Resolves all component instances that implement a given service type. + + The service type. + The list of component instances that implement the service. + Thrown if a component could not be resolved. + + + + Resolves all component instances that implement a given service type. + + The service type. + The list of component instances that implement the service. + Thrown if is null. + Thrown if a component could not be resolved. + + + + Resolves handles for all components that implement a given service type. + + The service type. + The traits type. + The list of handles of components that implement the service. + Thrown if a component could not be resolved. + + + + Resolves handles for all components that implement a given service type. + + The service type. + The list of handles of components that implement the service. + Thrown if is null. + Thrown if a component could not be resolved. + + + + Resolves a single component instance with a given component id. + + The component id. + The component instance. + Thrown if no component was found + or if a component could not be resolved. + Thrown if is null. + + + + Resolves a handle for a single component that implements a given service type. + + The service type. + The traits type. + The handle for the component that implements the service. + Thrown if no component was found + or if a component could not be resolved. + + + + Resolves a handle for a single component that implements a given service type. + + The service type. + The handle for the component implements the service. + Thrown if is null. + Thrown if no component was found + or if a component could not be resolved. + + + + Resolves a handle for a single component with a given component id. + + The component id. + The component handle. + Thrown if no component was found + or if a component could not be resolved. + Thrown if is null. + + + + Provides a view of registered components along with methods for resolving them. + + + + + Gets a service descriptor by its type, or null if not found. + + The service type. + The service descriptor, or null if not found. + Thrown if is null. + + + + Gets a service descriptor by its type name, or null if not found. + + The service type name. + The service descriptor, or null if not found. + Thrown if is null. + + + + Gets a service descriptor by its id, or null if not found. + + The service id. + The service descriptor, or null if not found. + Thrown if is null. + + + + Builds objects and performs dependency injection via a service locator. + + + + + Creates an object factory. + + The dependency resolver. + The object type. + The object properties. + Thrown if , + or is null. + + + + Creates an instance of the object described by this factory. + + The instance, not null. + + + + A plugin catalog implementation that verifies plugin dependencies and assembly references. + + + + + Creates an empty plugin catalog. + + + + + + + Details of a plugin that has just been loaded. + + + + + Constructor. + + The loaded plugin. + The base directory. + The plugin file path. + + + + The base directory for the plugin. + + + + + The loaded plugin. + + + + + The file path of the plugin. + + + + + Loads plugins by recursively scanning plugin paths in the file system + for *.plugin files that contain plugin metadata. + + + + + Creates a file system plugin loader. + + + + + Adds a plugin path. + + The plugin path to add. + Thrown if is null. + + + + Adds a plugin definition as XML. + + The plugin xml. + The plugin base directory. + Thrown if + or is null. + + + + Defines a constant to be used by the preprocessor. + + The constant name. + Thrown if is null. + + + + Gets the collection of initial preprocessor constants. + + + + + Gets or sets the installation id. + + + + + Loads plugins by recursively searching the plugin paths for *.plugin files. + + A function that receives plugin metadata as it + becomes available, not null. + + + + Gets the list of plugin paths. + + + + + Populates a catalog with plugin metadata derived from the currently + registered plugin data sources. + + The plugin catalog to populate. + Thrown if + is null. + + + + The plugin callback type used by . + + + + + Provides information used to register a plugin. + + + + + Creates a plugin registration. + + The plugin id. + The plugin type name. + The plugin base directory. + Thrown if , + or is null. + + + + Gets or sets the list of plugin assembly bindings. + + Thrown if is null. + + + + Gets or sets the base directory. + + Thrown if is null. + + + + Gets or sets a condition governing the activation of the plugin, + or null if there is no condition. The plugin will be disabled if a + condition is provided but is not satisfied. + + + + + Gets or sets the paths of files that belong to the plugin relative to the + plugin base directory. + + Thrown if is null. + + + + Gets or sets the list of plugin dependencies. + + Thrown if is null. + + + + Gets or sets the plugin handler factory. + + Thrown if is null. + + + + Gets or sets the plugin id. + + Thrown if is null. + + + + Gets or sets the plugin properties. + + Thrown if is null. + + + + Gets or sets the plugin type name. + + Thrown if is null. + + + + Gets or sets the list of probing paths in which to + attempt to locate referenced assemblies. + + Thrown if is null. + + + + Gets or sets the recommended installation path for the plugin files relative to + the runtime installation directory, or null if there is no preference. + + + + + Gets or sets the traits properties. + + Thrown if is null. + + + + Describes the traits of a component. + + + + + Creates a plugin traits object. + + The localized display name of the plugin. + + + + Gets or sets the localized plugin description, or null if none. + + + + + Gets or sets the plugin icon, or null if none. + + + + + Gets the localized display name of the plugin. + + + + + Gets or sets the plugin version number, or null if none. + + + + + Provides a configurable registry of plugins, services and components. + + + + + Creates an empty registry. + + + + + Gets a view of all registered components. + + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the registry. + + True if disposing. + + + + Gets a view of all registered plugins. + + + + + Registers a component and returns its descriptor. + + The component registration. + The new component descriptor. + Thrown if is null. + Thrown if there is already a component registered with the same id + or if the plugin or service does not belong to this registry or if the component implements a service + provided by a plugin that was not listed as a plugin dependency of the component's plugin. + + + + Registers a plugin and returns its descriptor. + + The plugin registration. + The new plugin descriptor. + Thrown if is null. + Thrown if there is already a plugin registered with the same id + or if the registration contains errors. + + + + Registers a service and returns its descriptor. + + The service registration. + The new service descriptor. + Thrown if is null. + Thrown if there is already a service registered with the same id or type name + or if the plugin does not belong to this registry. + + + + Gets a resource locator based on the contents of the registry. + + + + + Gets a service locator based on the contents of the registry. + + + + + Gets a view of all registered services. + + + + + A resource locator implementation based on a registry. + + + + + Creates a resource locator based on a registry. + + The registry. + Thrown if is null. + + + + Gets the registry. + + + + + Resolves a resource Uri to a full path. + + The resource Uri. + The resolved full path of the resource. + Thrown if is null. + Thrown if the uri cannot be resolved. + + + + A service locator implementation based on a registry. + + + + + Creates a service locator based on a registry. + + The registry. + Thrown if is null. + + + + Returns true if there is a component registered with the given component id and it has not been disabled. + + The component id. + True if there is a component registered with the given component id. + Thrown if is null. + + + + Returns true if the there is a service registered with the specified type and it has not been disabled. + + The service type. + True if there is at least one component registered for the given service type. + Thrown if is null. + + + + Gets the registry. + + + + + + Resolves a single component instance that implements a given service type. + + The service type. + The component instance that implements the service. + Thrown if is null. + Thrown if no component was found + or if a component could not be resolved. + + + + + Resolves all component instances that implement a given service type. + + The service type. + The list of component instances that implement the service. + Thrown if is null. + Thrown if a component could not be resolved. + + + + + Resolves handles for all components that implement a given service type. + + The service type. + The list of handles of components that implement the service. + Thrown if is null. + Thrown if a component could not be resolved. + + + + Resolves a single component instance with a given component id. + + The component id. + The component instance. + Thrown if no component was found + or if a component could not be resolved. + Thrown if is null. + + + + + Resolves a handle for a single component that implements a given service type. + + The service type. + The handle for the component implements the service. + Thrown if is null. + Thrown if no component was found + or if a component could not be resolved. + + + + Resolves a handle for a single component with a given component id. + + The component id. + The component handle. + Thrown if no component was found + or if a component could not be resolved. + Thrown if is null. + + + + Provides information used to register a service. + + + + + Creates a service registration. + + The plugin to which the service will belong. + The service id. + The service type name. + Thrown if , + or is null. + + + + Gets or sets the default component type name, or null if none. + + + + + Gets or sets the plugin to which the service will belong. + + Thrown if is null. + + + + Gets or sets the service id. + + Thrown if is null. + + + + Gets or sets the service type name. + + Thrown if is null. + + + + Gets or sets the traits handler factory. + + Thrown if is null. + + + + A handler factory for singletons. + + + + Initializes a new instance of the class + + + + Creates a handler. + + The object dependency resolver, not null. + The contract type: the handler will ensure that the objects it produces are subclasses or implementations of the contract type. + The object type: the handler will produce objects that are (possibly decorated) instances of the object type. + The configuration properties for the objects produced by the handler. + The handler. + + + + The base class for plugin, service or component traits. + + + + Initializes a new instance of the class + + + + Specifies the traits class associated with a service contract. + + + + + Binds a traits interface to a service contract. + + The traits type, a subclass of . + Thrown if + is null. + Thrown if + is not a class or if it is not derived from . + + + + Gets the traits type, a subclass of . + + + + + Describes an assembly used by a plugin and how the loader should bind to it. + + + + + Creates an assembly reference. + + The assembly full name. + Thrown if is null. + + + + Gets or sets whether to apply the assembly publisher policy. Default is true. + + + + + Gets the mutable list of assembly binding redirects. + + + + + Gets or sets the assembly code base as a relative path to the plugin + base directory or to the 'bin' directory within, or null if none. + + + + + Gets or sets the assembly full name. + + Thrown if is null. + + + + Gets or sets whether the assembly full name should be used to qualify all partial + name references to the assembly. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Specifies an old version range for an assembly binding redirect. + + + + + Creates an assembly binding redirect. + + The old assembly version number or range. + Thrown if is null. + + + + Gets or sets the old assembly version number or range. + + Thrown if is null. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Describes a plugin cache file. + + + + + Creates an empty cache. + + + + + Gets or sets the installation id of the Gallio installation whose plugin information has been recorded in the cache, or null if not known. + + + + + Gets the mutable list of plugin information records in the cache. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Describes information about a plugin whose metadata has been cached. + + + + Initializes a new instance of the class + + + + Gets or sets the plugin base directory path. + + + + + Gets or sets the plugin metadata. + + + + + Gets or sets the plugin file path. + + + + + Gets or sets the plugin file modification time stamp. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Represents a component descriptor in Xml. + + + + + Creates a component descriptor. + + The component id. + The service id. + The assembly-qualified component type name. + Thrown if + or is null. + + + + Gets or sets the component id. + + Thrown if is null. + + + + Gets or sets the assembly-qualified component type name, or null to use the + default for the service. + + + + + Gets or sets the component parameters, or null if there are none. + + + + + Gets or sets the service id. + + Thrown if is null. + + + + Gets or sets the component traits, or null if there are none. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Describes a dependency on another plugin. + + + + + Creates an plugin dependency reference. + + The referenced plugin id. + Thrown if is null. + + + + Gets or sets the referenced plugin id. + + Thrown if is null. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Describes a file that belongs to a plugin. + + + + + Creates a file description. + + The path of the file relative to the plugin base directory. + Thrown if is null. + + + + Gets or sets the path of the file relative to the plugin base directory. + + Thrown if is null. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Represents a table of key and value pairs as a sequence of Xml elements whose local name + represents the key and whose text body contains the value. + + + + + Creates an empty key value table. + + + + + Gets or sets the Xml elements that describe the property entries + during serialization. + + Thrown if is null. + + + + Gets or sets a mutable view of the properties as a property set. + + Thrown if is null. + + + + Represents a plugin descriptor in Xml. + + + + + Creates a plugin descriptor with an id. + + The plugin id. + Thrown if is null. + + + + Gets the mutable list of plugin assembly bindings. + + + + + Gets the mutable list of components belonging to the plugin. + + + + + Gets the mutable list of plugin dependencies. + + + + + Gets or sets a condition governing the activation of the plugin, + or null if there is no condition. The plugin will be disabled if a + condition is provided but is not satisfied. + + + + + Gets the mutable list of files that belong to a plugin. + + + + + Gets or sets the plugin parameters, or null if there are none. + + + + + Gets or sets the plugin id. + + Thrown if is null. + + + + Gets or sets the assembly-qualified plugin type name, or null if the default + implementation may be used. + + + + + Gets the mutable list of additional probing paths in which to + attempt to locate referenced assemblies. + + + + + Gets or sets the recommended installation path for the plugin files relative to + the runtime installation directory, or null if there is no preference. + + + + + Gets the mutable list of services belonging to the plugin. + + + + + Gets or sets the plugin traits, or null if there are none. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Represents a service descriptor in Xml. + + + + + Creates a service descriptor. + + The service id. + The service type. + Thrown if or + is null. + + + + Gets or sets the assembly-qualified default component type name, or null if none. + + + + + Gets or sets the service id. + + Thrown if is null. + + + + Gets or sets the assembly-qualified service type name. + + Thrown if is null. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Recognizes .Net assemblies by looking for the CLR header within the file. + + + + Initializes a new instance of the class + + + + Returns true if the recognizer recognizes the file described by the file inspector. + + The file inspector, never null. + True if the file type was recognized. + + + + Describes a file type. + + + + + Creates a file type object. + + The file type id. + The file type description. + The super type of the file type, or null if none. + Thrown if + or is null. + Thrown if is empty. + + + + Gets the file type description. + + + + + Gets the id of the file type. + + + + + Returns true if this file type is equal to or is a subtype of some other type. + + The other type. + True if the condition is satisfied. + Thrown if is null. + + + + Returns true if this file type is equal to or is a subtype of any of the specified other types. + + The other types. + True if the condition is satisfied. + Thrown if is null + or contains a null. + + + + Gets the super type of this file type, or null if none. + + + + + Returns a that represents the current . + + + A that represents the current . + + + + + A built-in file type manager that identified file types based on a + set of registered components. + + + + + Creates a file type manager. + + The file type recognizer component handles. + Thrown if is null. + + + + Gets information about a registered file type by its id. + + The file type id. + The associated file type information, or null if not found. + Thrown if is null. + + + + Gets information about all registered file types. + + The list of all registered file types. + + + + Identifies the type of a file by consulting the set of all registered file types. + + The file inspector for the file to identify. + The file type of the file, or type if unidentified. + Thrown if is null. + Thrown if the file cannot be accessed. + + + + Identifies the type of a file by consulting only the specified list of file type candidates. + + The file inspector for the file to identify. + The collection of specific file type candidates to consider. + The file type of the file, or type if unidentified + among the candidates considered. + Thrown if or + is null. + Thrown if the file cannot be accessed. + + + + Identifies the type of a file by consulting the set of all registered file types. + + The file to identify. + The file type of the file, or type if unidentified. + Thrown if is null. + Thrown if the file cannot be accessed. + + + + Identifies the type of a file by consulting only the specified list of file type candidates. + + The file to identify. + The collection of specific file type candidates to consider. + The file type of the file, or type if unidentified + among the candidates considered. + Thrown if or + is null. + Thrown if the file cannot be accessed. + + + + Gets a file type used to identify a file of unknown type. + + + + + Provides metadata about a . + + + + + Creates traits for a file type recognizer. + + The file type id. + The file type description. + Thrown if or + is null. + Thrown if is empty. + + + + Specifies a regular expression used to identify the type of a file by its contents, + or null if none. The matching is performed case-insensitively. + + + + + Gets the file type description. + + + + + Specifies a regular expression used to identify the type of a file by its name, + or null if none. The matching is performed case-insensitively. + + + + + Gets the file type id. + + + + + Gets or sets the id of the file type, or null if none. + + + + + Provides a mechanism for inspecting the metadata and contents of a particular file. + + + + + Tries to get the contents of the file as a string. + + Returns the file contents when available, or null otherwise. + True if the file contents were available. + + + + Tries to get the file info associated with the original path of the file. + + Returns the file info when available, or null otherwise. + True if the file info was available. + + + + Tries to get the file stream opened for reading. + + Returns the file stream when available, or null otherwise. + True if the file stream was available. + + + + Provides services related to determining the type of a file. + + + + + Gets information about a registered file type by its id. + + The file type id. + The associated file type information, or null if not found. + Thrown if is null. + + + + Gets information about all registered file types. + + The list of all registered file types. + + + + Identifies the type of a file by consulting the set of all registered file types. + + The file inspector for the file to identify. + The file type of the file, or type if unidentified. + Thrown if is null. + Thrown if the file cannot be accessed. + + + + Identifies the type of a file by consulting only the specified list of file type candidates. + + The file inspector for the file to identify. + The collection of specific file type candidates to consider. + The file type of the file, or type if unidentified + among the candidates considered. + Thrown if or + is null. + Thrown if the file cannot be accessed. + + + + Identifies the type of a file by consulting the set of all registered file types. + + The file to identify. + The file type of the file, or type if unidentified. + Thrown if is null. + Thrown if the file cannot be accessed. + + + + Identifies the type of a file by consulting only the specified list of file type candidates. + + The file to identify. + The collection of specific file type candidates to consider. + The file type of the file, or type if unidentified + among the candidates considered. + Thrown if or + is null. + Thrown if the file cannot be accessed. + + + + Gets a file type used to identify a file of unknown type. + + + + + Recognizes the type of a file. + + + + + Returns true if the recognizer recognizes the file described by the file inspector. + + The file inspector, never null. + True if the file type was recognized. + + + + A file inspector that opens a file only on demand as needed. + + + + + Creates a file inspector for the file describe the specified file info object. + + The file to inspect. + Thrown if is null. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the inspector. + + True if was called directly. + + + + Tries to get the contents of the file as a string. + + Returns the file contents when available, or null otherwise. + True if the file contents were available. + + + + Tries to get the file info associated with the original path of the file. + + Returns the file info when available, or null otherwise. + True if the file info was available. + + + + Tries to get the file stream opened for reading. + + Returns the file stream when available, or null otherwise. + True if the file stream was available. + + + + A simple file type recognizer that does not perform any filtering + beyond that which is already specified by its associated traits. + + + + Initializes a new instance of the class + + + + Returns true if the recognizer recognizes the file described by the file inspector. + + The file inspector, never null. + True if the file type was recognized. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A default formatting rule for objects based on using the + to convert the value to a string. + + + + + Creates a conversion to string formatting rule. + + The converter to use. + Thrown if is null. + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + Service locator for . + + + + + Gets the global formatter singleton. + + + + + Typical priority values to use as guidelines. + + + + + The best possible formatting rule priority. + + + + + A better than typical rule. + + + + + The default formatting rule priority. + + + + + Fallback rule priority. + + + + + Generic rule priority. + + + + + Typical rule priority. + + + + + Provides services for formatting objects for display. + + + + + Formats an object to a string for display. + + The object to format, may be null. + The formatted string, never null and never an empty string. + + + + A formatting rule encapsulates an algorithm for formatting values of particular + types to strings for presentation. + + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for , , , + , , and . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A rule-based formatter uses a set of s to + format values appropriately. + + + + + Creates a rule-based formatter. + + The rules to use. + Thrown if is null. + + + + Formats an object to a string for display. + + The object to format, may be null. + The formatted string, never null and never an empty string. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule that describes the structure of objects in terms of their constituent + properties and fields. + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatter that is used when the runtime is not initialized. + + + + + Creates a stub formatter using only a few built-in formatting rules. + + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + Utilities for working with AppDomains. + + + + + Creates an AppDomain. + + The application name for the new AppDomain, or null if none. + The application base directory for the new AppDomain, or null to use the current one. + The configuration file for the new AppDomain, or null to use the current one. + If true, enables shadow copying within the AppDomain. + The new AppDomain. + + + + Creates a remote instance of a type within another AppDomain. + + The AppDomain in which to create the instance. + The type to instantiate. + The constructor arguments for the type. + The remote instance. + Thrown if or + is null. + + + + Base implementation of that performs argument validation. + + + + + Creates a host. + + The host setup. + The logger for host message output. + Thrown if + or is null. + + + + Gets the host service. + + The host service, or null if the host service was not available. + + + + Attaches the debugger to a process if the host settings require it. + + + + + Initializes the host and connects to the host service. + + Thrown if the host has already been initialized. + Thrown if the host has been disposed. + Thrown if an exception occurred while connecting to the host. + + + + Detaches the debugger from a process if the host settings require it. + + + + + Disconnects the host. + + Thrown if the host has been disposed. + + + + An event that is raised when the host is disconnected. + If the host has already been disconnected, the event is fired immediately. + + Thrown if the host has been disposed. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the host. + + True if disposing. + + + + Gets a host service that can be used to perform operations within the host's environment. + + Thrown if the host has been disconnected. + Thrown if the host has been disposed. + + + + Gets a deep copy of the host setup information. + + Thrown if the host has been disposed. + + + + Gets an reference to the host service, or null if not connected. + + + + + Gets the internal host setup information without copying it. + + + + + Returns true if the host is connected. + + Thrown if the host has been disposed. + + + + Returns true if the host is local to the creating AppDomain, false if it + must be accessed across a remote channel. + + + + + Gets the logger. + + + + + Sets the state of the host to disconnected and notifies clients. + + + + + Releases the host service. + + The host service that is being released, not null. + + + + Throws an exception if the host has been disposed. + + + + + An abstract base class for host factories. + + + + Initializes a new instance of the class + + + + Creates a host instance. + + The host setup. + The logger for host message output. + The newly created host. + Thrown if + or is null. + + + + Creates the host. + + The canonicalized host setup, non-null. + The logger, non-null. + The host. + + + + Base implementation of that performs argument validation. + + + + Initializes a new instance of the class + + + + Creates an instance of a remote object given an assembly name and type name. + + The name of assembly that contains the type. + The full name of the type. + The object handle of the instance. + Thrown if or + is null. + + + + Creates an instance of a remote object given an assembly path and type name. + + The path of assembly that contains the type. + The full name of the type. + The object handle of the instance. + Thrown if or + is null. + + + + Internal implementation of . + + The assembly path, not null. + The type name, not null. + The created object handle. + + + + Internal implementation of . + + The assembly name, not null. + The type name, not null. + The created object handle. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Disposes the host service. + + True if disposing. + + + + Asks the host to perform the specified action remotely. + + The action to perform. + The argument value, if any. + The argument type. + The result type. + The result value, if any. + Thrown if is null. + + + + Internal implementation of . + + The action to perform, not null. + The argument value, if any. + The argument type. + The result type. + The result value, if any. + + + + Pings the host to verify and maintain connectivity. + + Thrown if the remote host is unreachable. + + + + Internal implementation of . + + + + + Throws an exception if the host service has been disposed. + + + + + Specifies where a should store the temporary configuration file + it generates when it is being initialized. + + + + + Do not create a configuration file. + + + + + Stores the configuration file in the user's temporary directory. + + + + + Stores the configuration file in the application base directory of the hosted components. + + + + + Attaches to a to provide assembly resolution services. + + + + + Installs an assembly resolver that provides access to the installation path + using the . + + The host. + The Gallio runtime path. + Thrown if or + is null. + + + + Installs an assembly resolver that delegates to the creating 's + assembly resolver to locate assemblies whenever the host is unable to find them. + + The host. + Thrown if is null. + + + + Describes the runtime configuration of a . + + + + + Creates a default host configuration. + + + + + Adds a binding to the configuration for the specified assembly. + + The assembly binding. + Thrown if is null. + + + + Adds an assembly dependency if it is not already in the configuration. + + The assembly dependency to add. + Thrown if is null. + + + + Adds an assembly dependency element if a suitable one does not already exist. + + The assembly name. + The assembly public key token, or null if none. + The assembly culture. + The assembly processor architecture, or null if none. + The assembly dependency element. + + + + Adds an assembly qualification if it is not already in the configuration. + + The assembly qualification to add. + Thrown if is null. + + + + Adds an assembly qualification element if a suitable one does not already exist. + + The partial name to quality. + The full name. + The assembly qualification element. + Thrown if an assembly qualification already + exists for the same partial name but with a different full name. + + + + Adds a supported runtime version number if it is not already in the configuration. + + The version number, eg. "v2.0.50727". + Thrown if is null. + + + + Gets a read-only list of assembly dependencies. + + + + + Gets a read-only list of assembly qualifications. + + + + + Gets or sets whether the failure dialog is enabled. + + + + + Clears the list of assembly dependencies. + + + + + Clears the list of assembly qualifications. + + + + + Clears the list of supported runtime versions. + + + + + Gets or sets the primary Xml configuration data, or null if none. + + + + + Creates a copy of the host configuration information. + + The copy. + + + + Gets or sets whether the legacy unhandled exception policy is enabled. + + + + + Gets or sets whether remoting exceptions are substituted with custom errors instead + of being passed through to the remote client. + + + + + Removes an assembly dependency. + + The assembly dependency to remove. + Thrown if is null. + + + + Removes an assembly qualification. + + The assembly qualification to remove. + Thrown if is null. + + + + Removes a supported runtime version number. + + The version number, eg. "v2.0.50727". + Thrown if is null. + + + + Gets a read-only list of supported runtime versions in order of preference. + + + + + Overlays the with the additional configuration + entries necessary to enable the features described by this instance and returns + the combined Xml configuration. + + The combined Xml configuration. + + + + Overlays the with the additional configuration + entries necessary to enable the features described by this instance and writes + the combined Xml configuration to a . + + The TextWriter where the Xml configuration will be written to. + Thrown if is null. + Thrown if the configuration could not be written. + + + + Overlays the with the additional configuration + entries necessary to enable the features described by this instance and writes + the combined Xml configuration to a file with the given path. + + The file path. + Thrown if is null. + Thrown if the configuration could not be written. + + + + Describes an assembly binding redirection from an old version range to + a new version. + + + + + Creates an assembly binding redirect. + + The range of old versions to redirect, specified + either as a single version such as "1.2.3.4" or as a range such as "1.2.3.4-10.11.12.13". + The new version to which the binding should be redirected + such as "1.2.3.4". + Thrown if + or is null. + + + + Creates a copy of the assembly binding redirect information. + + The copy. + + + + Gets or sets the new version to which the binding should be redirected + such as "1.2.3.4" + + Thrown if is null. + + + + Gets or sets the range of old versions to redirect, specified + either as a single version such as "1.2.3.4" or as a range such as "1.2.3.4-10.11.12.13" + + Thrown if is null. + + + + Describes the location of the codebase of a particular assembly version. + + + + + Creates an assembly code base element. + + The assembly version to which this element applies + such as "1.2.3.4" + The Uri that specifies the location of the assembly. + Thrown if + or is null. + Thrown if is not an absolute Uri. + Thrown if is not a well-formed Uri. + + + + Creates a copy of the assembly binding redirect information. + + The copy. + + + + Gets or sets the Uri that specifies the location of the assembly. + + Thrown if is null. + Thrown if is not an absolute Uri. + Thrown if is not a well-formed Uri. + + + + Gets or sets the assembly version to which this element applies + such as "1.2.3.4". + + Thrown if is null. + + + + Describes a dependent assembly configuration entry that optionally + specifies the codebase, a publisher policy and binding redirects. + + + + + Creates an assembly dependency. + + The assembly name. + Thrown if is null. + + + + Adds an assembly binding redirect if it is not already in the configuration. + + The assembly binding redirect to add. + Thrown if is null. + + + + Adds an assembly binding redirect element if a suitable one is not already present. + + Th old version range. + The new version for redirection. + The binding redirect element. + + + + Adds an assembly codebase if it is not already in the configuration. + + The assembly codebase to add. + Thrown if is null. + + + + Adds an assembly code-base element if a suitable one is not already present. + + The assembly version. + The code base uri. + The code base element. + + + + Gets or sets whether to apply the publisher policy for this assembly. + + + + + Gets a read-only list of assembly binding redirect elements. + + + + + Gets a mutable list of assembly code base elements. + + + + + Gets or sets the assembly culture, or null if none. + + + + + Gets or sets assembly name. + + Thrown if is null. + + + + Gets or sets the assembly processor architecture, or null if none. + + + + + Gets or sets the assembly public key token, or null if none. + + + + + Clears the list of assembly binding redirects. + + + + + Clears the list of assembly codebases. + + + + + Creates a copy of the assembly dependency information. + + The copy. + + + + Removes an assembly binding redirect. + + The assembly binding redirect to remove. + Thrown if is null. + + + + Removes an assembly codebase. + + The assembly codebase to remove. + Thrown if is null. + + + + Describes an assembly name qualification configuration entry that + maps an assembly partial name to its full name. + + + + + Creates an assembly name qualification. + + The assembly partial name to qualify. + The assembly full name to use. + Thrown if + or is null. + + + + Creates a copy of the assembly qualification information. + + The copy. + + + + Gets or sets the assembly full name to use. + + Thrown if is null. + + + + Gets or sets the assembly partial name to qualify. + + Thrown if is null. + + + + The type of exception thrown when hosting operations fail. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Provides utilities to interact with a over a + or . + + + + + Gets a remote host service using the specified channel. + + The channel. + The remote host service. + + + + Registers the host service with a channel. + + The remote host service. + The channel. + Thrown if or + is null. + + + + Gets the name used to register the . + + + + + Specifies a collection of parameters for setting up a . + + + + + Creates a default host setup. + + + + + Adds the relative or absolute path of a hint directory if it is not already in the host setup. + + The directory to add. + Thrown if is null. + + + + Adds a property key/value pair. + + The property key. + The property value. + Thrown if or is null. + Thrown if is already in the property set. + + + + Gets or sets the relative or absolute path of the application base directory, + or null to use a default value selected by the consumer. + + + + + Makes all paths in this instance absolute. + + The base directory for resolving relative paths, + or null to use the current directory. + + + + Clears the list of hint directories. + + + + + Clears the collection of properties. + + + + + Gets or sets the host configuration information. + + Thrown if is null. + + + + Gets or sets where the host should write out the configuration file for the hosted components. + + + + + Creates a copy of the host setup information. + + The copy. + + + + Gets or sets the debugger setup options, or null if not debugging. + + + + + Gets or sets whether the host should run with elevated privileges. + + + + + Gets the read-only list of relative or absolute paths of + hint directories used to resolve assemblies. + + + + + Gets or sets the processor architecture that the host should target, when supported. + + + + + Gets a read-only collection of configuration properties for the host. + + + + + Removes a hint directory. + + The directory to remove. + Thrown if is null. + + + + Removes a property key/value pair. + + The property key. + Thrown if is null. + + + + Gets or sets the .Net runtime version of the host, or null to auto-detect. + + + + + Gets or sets whether assembly shadow copying is enabled. + + + + + Gets or sets the relative or absolute path of the working directory + or null to use a default value selected by the consumer. + + + + + Writes a temporary configuration file for the application to disk and returns its path + based on . + + The full path of the configuration file that was written, or null if no file was written. + Thrown if + is null but is . + Thrown if the configuration file could not be written. + + + + Provides utilities for working with hosts. + + + + + Creates an instance of an object within a host. + + The host in which to create the object. + The type of object to create. + The object instance. + Thrown if is null. + + + + Creates an instance of an object within a host. + + The host in which to create the object. + The type of object to create. + The object instance. + Thrown if + or is null. + + + + A host represents an environment that may be used to perform various + services in isolation. + + + + + Disconnects the host. + + Thrown if the host has been disposed. + + + + An event that is raised when the host is disconnected. + If the host has already been disconnected, the event is fired immediately. + + Thrown if the host has been disposed. + + + + Gets a host service that can be used to perform operations within the host's environment. + + Thrown if the host has been disconnected. + Thrown if the host has been disposed. + + + + Gets a deep copy of the host setup information. + + Thrown if the host has been disposed. + + + + Returns true if the host is connected. + + Thrown if the host has been disposed. + + + + Returns true if the host is local to the creating AppDomain, false if it + must be accessed across a remote channel. + + + + + A host factory encapsulates a policy for creating new instances. + + + + + Creates a host instance. + + The host setup. + The logger for host message output. + The newly created host. + Thrown if + or is null. + + + + A host service enables a local client to interact with a remotely + executing hosting environment. + + + + + Creates an instance of a remote object given an assembly name and type name. + + The name of assembly that contains the type. + The full name of the type. + The object handle of the instance. + Thrown if or + is null. + + + + Creates an instance of a remote object given an assembly path and type name. + + The path of assembly that contains the type. + The full name of the type. + The object handle of the instance. + Thrown if or + is null. + + + + Asks the host to perform the specified action remotely. + + The action to perform. + The argument value, if any. + The argument type. + The result type. + The result value, if any. + Thrown if is null. + + + + Pings the host to verify and maintain connectivity. + + Thrown if the remote host is unreachable. + + + + A specialization of host service designed for hosts that are remotely managed. + + + + + Remotely shuts down the host service. + + + + + An isolated app domain host is a the runs code within an + isolated of this process. Communication with the + occurs over an inter- .Net + remoting channel. + + + + + Creates an uninitialized host. + + The host setup. + The logger for host message output. + The debugger manager. + Thrown if , + or is null. + + + + Connects to the remote host service. + + The remote host service. + + + + Disposes the host. + + True if disposing. + + + + A factory for initialized hosts. + + + + + Creates a host factory. + + A reference to the debugger manager. + Thrown if is null. + + + + Gets the component Id of this factory. + + + + + Creates the host. + + The canonicalized host setup, non-null. + The logger, non-null. + The host. + + + + An isolated process host is a that runs code within a + new external process. + + + + + Creates an uninitialized host. + + The host setup. + The logger for host message output. + The runtime path where the hosting executable will be found. + Thrown if , or is null. + + + + Connects to the remote host service. + + The remote host service. + + + + Creates the process task to start the process. + + The executable path. + The command-line arguments. + The working directory. + The process task. + + + + Disposes the host. + + True if disposing. + + + + Prepares the parameters for the remote connection. + + The unique id of the host. + Set to the host application arguments used to configure its server channel. + Set to a factory used to create the local client channel. + Set to a factory used to create the local server channel to allow the remote host to call back to this one. + + + + A factory for initialized hosts. + + + + + Creates a host factory. + + The runtime. + Thrown if is null. + + + + Gets the component Id of this factory. + + + + + Creates the host. + + The canonicalized host setup, non-null. + The logger, non-null. + The host. + + + + Gets the path of the runtime components, in particular the folder where Gallio.Host.exe is located. + + + + + An implementation of that runs code + locally within the current AppDomain. + + + + + Creates a local host. + + The host setup. + The logger for host message output. + The debugger manager. + Thrown if , + or is null. + + + + Gets the host service. + + The host service, or null if the host service was not available. + + + + Disposes the host. + + True if disposing. + + + + Returns true if the host is local to the creating AppDomain, false if it + must be accessed across a remote channel. + + + + + Releases the host service. + + The host service that is being released, not null. + + + + A factory for initialized hosts. + + + + + Creates a host factory. + + A reference to the debugger manager. + Thrown if is null. + + + + Gets the component Id of this factory. + + + + + Creates the host. + + The canonicalized host setup, non-null. + The logger, non-null. + The host. + + + + An implementation of that communicates with a + that resides in a different context + using .Net remoting. + + + + + Creates an uninitialized host. + + The host setup. + The logger for host message output. + The automatic ping interval, or null if none. + Thrown if + or is null. + + + + Gets the host service. + + The host service, or null if the host service was not available. + + + + Connects to the remote host service. + + The remote host service. + + + + Disposes the host. + + True if disposing. + + + + Returns true if the host is local to the creating AppDomain, false if it + must be accessed across a remote channel. + + + + + Releases the host service. + + The host service that is being released, not null. + + + + A remotely accessible host service. + + + + + Creates a host service. + + The maximum amount of time to wait for a ping + before automatically disposing the host service, or null if there should be no timeout. + + + + Disposes the host service. + + True if disposing. + + + + Internal implementation of . + + + + + Remotely shuts down the host service. + + + + + Waits until the host service is shutdown or a ping timeout occurs. + + + + + Returns true if the watchdog timer expired. + + + + + Abstract base class for installers. + + + + Initializes a new instance of the class + + + + Installs components. + + The progress monitor, not null. + + + + Uninstalls components. + + The progress monitor, not null. + + + + The default installer manager implementation. + + + + + Creates the installer manager. + + The installer handles, not null. + The elevation manager, not null. + + + + Installs components. + + The ids of the specific installers to include, or null to include all. + A privilege elevation context, or null if the installer manager should obtain its own when needed. + The progress monitor. + True on success, false if the user canceled the operation. + Thrown if is null. + + + + Uninstalls components. + + The ids of the specific installers to include, or null to include all. + A privilege elevation context, or null if the installer manager should obtain its own when needed. + The progress monitor. + True on success, false if the user canceled the operation. + Thrown if is null. + + + + Installs or uninstalls components on the local machine. + + + + + Installs components. + + The progress monitor, not null. + + + + Uninstalls components. + + The progress monitor, not null. + + + + Performs installation tasks and manages the set of registered components. + + + + + Installs components. + + The ids of the specific installers to include, or null to include all. + A privilege elevation context, or null if the installer manager should obtain its own when needed. + The progress monitor. + True on success, false if the user canceled the operation. + Thrown if is null. + + + + Uninstalls components. + + The ids of the specific installers to include, or null to include all. + A privilege elevation context, or null if the installer manager should obtain its own when needed. + The progress monitor. + True on success, false if the user canceled the operation. + Thrown if is null. + + + + An elevated command used for installation. + + + + + Initializes the command. + + The installer manager, not null. + + + + The id of this elevated command. + + + + + Executes the command. + + The command arguments. + The progress monitor, non-null. + The command result, must be null or serializable. + + + + Arguments for the command. + + + + + Creates the arguments. + + The installer id. + The requested installer operation. + Thrown if is null. + + + + Gets the installer id. + + + + + Gets the requested installer operation. + + + + + Specifies the installer operation. + + + + + Runs the install. + + + + + Runs the uninstall. + + + + + Traits for components. + + + + Initializes a new instance of the class + + + + Gets or sets whether an installer requires privilege elevation (admin access) + to run. + + + + + Installs or uninstalls components using the . + + + + + Creates the command. + + The installer manager, not null. + + + + Executes the command. + + The command execution context, not null. + The typed command arguments, not null. + The command exit code, zero for success, non-zero for errors. + + + + Validates the command arguments. + + The arguments object, not null. + The error reporter, not null. + True if the arguments are valid. + + + + The arguments for the command. + + + + Initializes a new instance of the class + + + + When set to true, installs components. + + + + + The ids of installers to include. + + + + + When set to true, uninstalls components. + + + + + Bootstraps a globally reachable assembly loader within the Gallio installation path. + + + + + Gets the bootstrapped assembly loader. + + Thrown if the bootstrap assembly loader has not been initialized. + + + + Installs a global assembly resolver given the specified runtime path. + + The Gallio runtime path. + Thrown if is null. + + + + Resolves assemblies using hint paths and custom resolvers. + + + + + Initializes the assembly resolver manager. + + + + + Adds a custom assembly resolver to use when standard assembly resolution fails. + + The assembly resolver. + Thrown if is null. + + + + Adds an assembly load hint directory to search when standard assembly + resolution fails. + + The hint directory. + Thrown if is null. + + + + Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + + + + + Loads an assembly from the specified file. + + The assembly file. + The loaded assembly. + Thrown if the is null. + Thrown if the assembly could not be loaded. + + + + Locates Gallio.Loader.dll. + + + + + Gets the path of the Gallio.Loader assembly (unless it is in the GAC) so that it + can be loaded by external code using . + + The path of Gallio.Loader.dll, or null if Gallio.Loader.dll is + installed in the GAC. + Thrown if the Gallio.Loader assembly is not available. + + + + Provides support for resolving and loading assemblies using hint paths and custom resolvers. + + + + + Adds a custom assembly resolver to use when standard assembly resolution fails. + + The assembly resolver. + Thrown if is null. + + + + Adds an assembly load hint directory to search when standard assembly + resolution fails. + + The hint directory. + Thrown if is null. + + + + Loads an assembly from the specified file. + + The assembly file. + The loaded assembly. + Thrown if the is null. + Thrown if the assembly could not be loaded. + + + + A custom assembly resolver participates in assembly resolution when + standard assembly resolution fails to load the desired assembly + but before assembly load paths are considered. + + + + + Resolves the assembly with the specified name. + + The full name of the assembly as was provided + to . + True if the assembly is to be resolved in the + reflection-only context. + The assembly, or null if it could not be resolved. + + + + Base implementation of that performs argument validation + and supports convenience methods. + + + + Initializes a new instance of the class + + + + Logs a message. + + The log message severity. + The log message. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message. + The associated exception data, or null if none. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message. + The associated exception, or null if none. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + A buffered log writer is an adapter for that writes + long full lines to a . + + + + + Creates a buffered log writer that reports a encoding. + + The logger to which messages are written. + The log severity for messages. + Thrown if is null. + + + + Creates a buffered log writer that reports a particular encoding. + + The logger to which messages are written. + The log severity for messages. + The encoding to report. + Thrown if + or is null. + + + + Releases the unmanaged resources used by the and optionally releases the managed resources. + + true to release both managed and unmanaged resources; false to release only unmanaged resources. + + + + + When overridden in a derived class, returns the in which the output is written. + + + The Encoding in which the output is written. + + + + + Clears all buffers for the current writer and causes any buffered data to be written to the underlying device. + + + + + Gets or sets the line terminator string used by the current TextWriter. + + + The line terminator string for the current TextWriter. + + + + + Writes a subarray of characters to the text stream. + + + The character array to write data from. + + + Starting index in the buffer. + + + The number of characters to write. + + + The buffer length minus is less than . + + + The parameter is null. + + + or is negative. + + + The is closed. + + + An I/O error occurs. + + + + + Writes a string to the text stream. + + + The string to write. + + + The is closed. + + + An I/O error occurs. + + + + + Writes the text representation of an object by calling ToString on this object, followed by a line terminator to the text stream. + + + The object to write. If is null, only the line termination characters are written. + + + The is closed. + + + An I/O error occurs. + + + + + A logger that dispatches log messages via events and listeners. + + + + Initializes a new instance of the class + + + + Adds a log listener that will receive log messages dispatched to the runtime logger. + + The log listener to add. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + An event that is fired when a log message is received. + + + + + Removes a log listener so that it will no longer receive log messages dispatched to the runtime logger. + + The log listener to remove. + Thrown if is null. + + + + Filters another logger to exclude messages below a given level of severity. + + + + + Creates a filtered logger. + + The logger to which filtered log messages are sent. + The lowest severity message type to retain. + Thrown if is null. + + + + Creates a filtered logger. + + The logger to which filtered log messages are sent. + The verbosity to use. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + Gets the minimum severity of the messages that are included in the filtered log. + + + + + Provides support for logging messages from system components. + + + + + Logs a message. + + The log message severity. + The log message. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message. + The associated exception data, or null if none. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message. + The associated exception, or null if none. + Thrown if is null. + + + + Event arguments for the + + + + Creates a log event. + + The log severity. + The log message. + The exception data, or null if none. + Thrown if is null. + + + + Gets the exception, or null if none. + + + + + Gets the log message. + + + + + Gets the log severity. + + + + + Describes the severity of a log message. + + + + + The severity used for debug messages. + + + + + The severity used for informational messages. + + + + + The severity used for important messages. + + + + + The severity used for warning messages. + + + + + The severity used for error messages. + + + + + A implementation that logs messages to the specified . + + + + + Creates a logger for the markup stream writer. + + The markup stream writer. + Thrown if is null. + + + + A null implementation of that does nothing. + + + + Initializes a new instance of the class + + + + Gets a singleton instance of the null logger. + + + + + Wraps a logger so that it can be accessed remotely. + + + + + Creates a wrapper for the specified logger. + + The logger. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + The severity prefix logger wraps another loggers and encodes the severity of a + log entry into the log message itself in a standard form. + + + + + Creates a prefix logger. + + The inner logger. + Thrown if is null. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + Parses severity information from log messages encoded by . + + + + Initializes a new instance of the class + + + + Parses a line of log data. + + The line of log data to parse. + Set to the severity of the message extracted from the line. + The message extracted from the line. + True if the message included a severity, false otherwise. + Thrown if is null. + + + + A logger that writes output to a . + + + + + Creates a text logger. + + The text writer to which the log output should be written. + + + + Logs a message with an associated exception. + + The log message severity. + The log message, not null. + The associated exception data, or null if none. + + + + Specifies the verbosity of the output. + + + + + Will only display Error and Warning messages. + + + + + Will display Important, Warning and Error messages. + + + + + Will display all messages, except Debug. + + + + + Will display all messages. + + + + + An implementation of based on files. + + + + + Initializes the preference manager. + + + + + Gets a preference store common to all users of this system. + + + + + Gets a preference store for the current local user. + + + + + Gets a preference store for the current roaming user. + + + + + A preference set implementation based on storing preference settings within a file. + + + + + Creates a file preference set. + + The preference set file. + Thrown if is null. + + + + Gets the preference set file. + + + + + Obtains a reader for the preference set. + + The read action which is provided with the reader. + Thrown if is null. + + + + + Obtains a writer for the preference set. + + The write action which is provided with the reader. + Thrown if is null. + + + + + A preference store implementation based on storing preference sets as files within a directory. + + + + + Creates a file preference store. + + The preference store directory. + Thrown if is null. + + + + Gets the preference set with the specified name. + + The name of the preference set. + The preference set. + Thrown if is null. + Thrown if is empty. + + + + Gets the preference store directory. + + + + + Stores and retrieves user and machine preferences. + + + + + Gets a preference store common to all users of this system. + + + + + Gets a preference store for the current local user. + + + + + Gets a preference store for the current roaming user. + + + + + Represents a set of related preference settings. + + + + + Obtains a reader for the preference set. + + The read action which is provided with the reader. + Thrown if is null. + + + + Obtains a reader for the preference set. + + The read function which is provided with the reader. + The read function result type. + The result of the read function. + Thrown if is null. + + + + Obtains a writer for the preference set. + + The write action which is provided with the reader. + Thrown if is null. + + + + Obtains a writer for the preference set. + + The write function which is provided with the reader. + The write function result type. + The result of the write function. + Thrown if is null. + + + + Provides operations for reading preference settings within preference sets. + + + + + Gets a preference setting. + + The preference setting key. + The setting value type. + The setting value or default(T) if none. + + + + Gets a preference setting. + + The preference setting key. + The default value to return in case the setting does not exist. + The setting value type. + The setting value or if none. + + + + Returns true if the preference set contains a preference setting. + + The preference setting key. + True setting exists. + + + + Provides operations for writing preference settings. + + + + + Removes a preference setting. + + The preference setting key. + + + + Sets a preference setting. + + The preference setting key. + The value to set, or null to remove the value. + The setting value type. + + + + Stores and retrieves the contents of preference sets. + + + + + Gets the preference set with the specified name. + + The name of the preference set. + The preference set. + Thrown if is null. + Thrown if is empty. + + + + Represents a collection of preferences in Xml. + + + + + Creates a preference container. + + + + + Gets the mutable list of preference settings. + + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Represents a preference setting in Xml. + + + + + Creates a preference setting. + + The setting name. + The setting value. + Thrown if + or is null. + + + + Gets or sets the preference setting name. + + Thrown if is null. + + + + Validates the object. + + Thrown if the data is not well-formed. + + + + Gets or sets the preference setting value. + + Thrown if is null. + + + + Abstract base class for objects whose purpose is to present progress + information to the user. + + + + Initializes a new instance of the class + + + + Initializes the presenter after a progress monitor has been attached. + + + + + Presents an observable progress monitor. + + The progress monitor to present. + Thrown if is null. + Thrown if the presenter does not support being + reused to present multiple progress monitors. + + + + Gets the attached progress monitor. + + + + + An abstract base class to assist with the implementation of conformant + classes. + + + + Initializes a new instance of the class + + + + Gets a presenter for the progress monitor. + + The presenter. + + + + Runs a task with a progress monitor. + + The task to run, never null. + Thrown if the task is canceled. + + + + An abstract base class for progress monitors that implements the cancelation + semantics only. + + + + Initializes a new instance of the class + + + + Notifies that the main task is starting. + + The name of the task being monitored. + The total number of work units to perform. Must + be greater than 0, or if an indeterminate amount + of work is to be performed. + An object that calls when disposed. + Thrown if is null. + Thrown if is not valid. + Thrown if or have already been called. + + + + Notifies that the operation is to be canceled. + + + + + Adds or removes an event handler to be called when the operation is canceled. + + + + + Creates a sub-progress monitor that represents a given number of + work-units as a sub-task of this progress monitor. + + The total number of work units of the parent task + that are to be represented by the sub-task. When the sub-task completes, this much + work will have been performed on the parent. + Must be a finite value greater than or equal to 0. + Thrown if is not valid. + + + + Disposes the progress monitor, including cleaning up an marking as + the current task, if any. + + + + + Disposes the progress monitor, including cleaning up an marking as + the current task, if any. + + True if was called. + + + + Notifies that the work is done, either the main task is completed + was cancelled by the user. If already done, the method has no effect. + + + + + Returns true if the operation has been canceled. + + + + + Notifies that the task has actually been canceled. + + True if cancelation has just occurred, false if no + state change was performed. + + + + Called when performs its updates. + + + + + Sets detailed status information for the current task or subtask. + + The name of the current subtask. + Thrown if is null. + Thrown if the task is not running. + + + + Throws an if the operation + has been canceled. + + Thrown if is true. + + + + Notifies that a given number of work units of the main task + have been completed. + + The number of work units completed so far. Must be + a finite value greater than or equal to 0. + Thrown if is not valid. + Thrown if the task is not running. + + + + A progress monitor provides facilities for core functionality to report + progress of a long running operation. + + + + + Notifies that the main task is starting. + + The name of the task being monitored. + The total number of work units to perform. Must + be greater than 0, or if an indeterminate amount + of work is to be performed. + An object that calls when disposed. + Thrown if is null. + Thrown if is not valid. + Thrown if or have already been called. + + + + Notifies that the operation is to be canceled. + + + + + Adds or removes an event handler to be called when the operation is canceled. + + + + + Creates a sub-progress monitor that represents a given number of + work-units as a sub-task of this progress monitor. + + The total number of work units of the parent task + that are to be represented by the sub-task. When the sub-task completes, this much + work will have been performed on the parent. + Must be a finite value greater than or equal to 0. + Thrown if is not valid. + + + + Notifies that the work is done, either the main task is completed + was cancelled by the user. If already done, the method has no effect. + + + + + Returns true if the operation has been canceled. + + + + + Sets detailed status information for the current task or subtask. + + The name of the current subtask. + Thrown if is null. + Thrown if the task is not running. + + + + Throws an if the operation + has been canceled. + + Thrown if is true. + + + + Notifies that a given number of work units of the main task + have been completed. + + The number of work units completed so far. Must be + a finite value greater than or equal to 0. + Thrown if is not valid. + Thrown if the task is not running. + + + + A progress monitor presenter attaches a progress monitor to a view. + + + + + Presents an observable progress monitor. + + The progress monitor to present. + Thrown if is null. + Thrown if the presenter does not support being + reused to present multiple progress monitors. + + + + A progress monitor provider runs a task with progress monitoring + and provides clear notification of cancelation in the form of + an . + + + + + Runs a task with a progress monitor. + + The task to run, never null. + Thrown if the task is canceled. + + + + Displays progress by writing a series of messages to an as the name + of the current task changes. + + + + + Create a logged progress monitor presenter. + + A logger instance to which messages will be written. + Thrown if is null. + + + + Initializes the presenter after a progress monitor has been attached. + + + + + Displays progress by writing a series of messages to an as the name + of the current task changes. + + + + + Creates a log progress monitor provider. + + The logger to which messages should be written. + Thrown if is null. + + + + Gets a presenter for the progress monitor. + + The presenter. + + + + Creates instances of null progress monitors that do nothing. + + + + + Creates a null progress monitor. + + The null progress monitor. + + + + A null progress monitor presenter simply does nothing. + + + + + Gets the singleton instance of the presenter. + + + + + Presents an observable progress monitor. + + The progress monitor to present. + Thrown if is null. + Thrown if the presenter does not support being + reused to present multiple progress monitors. + + + + Runs tasks without reporting any progress. + + + + + Gets the singleton instance of the provider. + + + + + An observable progress monitor tracks validates arguments and tracks the state + of the progress monitor but it does not implement any of its own behavior in response + to the notifications received. + + + + Initializes a new instance of the class + + + + Begins a sub-task in a sub-progress monitor. + + The sub-progress monitor. + + + + Notifies that the main task is starting. + + The name of the task being monitored. + The total number of work units to perform. Must + be greater than 0, or if an indeterminate amount + of work is to be performed. + An object that calls when disposed. + Thrown if is null. + Thrown if is not valid. + Thrown if or have already been called. + + + + Adds or removes an event handler that is called whenever the state of the progress + monitor changes in any way. + + + + + Gets the active child sub-progress monitor, or null if none. + + + + + Gets the number of work units completed so far. + + + + + Creates a sub-progress monitor that represents a given number of + work-units as a sub-task of this progress monitor. + + The total number of work units of the parent task + that are to be represented by the sub-task. When the sub-task completes, this much + work will have been performed on the parent. + Must be a finite value greater than or equal to 0. + Thrown if is not valid. + + + + Notifies that the work is done, either the main task is completed + was cancelled by the user. If already done, the method has no effect. + + + + + Ends a sub-task in a sub-progress monitor. + + The sub-progress monitor. + + + + Returns true if has been called. + + + + + Returns true if has been called and + has not yet also been called. + + + + + Gets the currently active leaf sub-progress monitor, or this one if there are + no sub-progress monitors. + + + + + Gets the status of the most deeply nested sub-task, or the status of this + task if there are no sub-progress monitors. + + + + + Gets the name of the most deeply nested sub-task, or an empty string if + there are no sub-progress monitors. + + + + + Called when a subtask changes in any way, including one of its own subtasks changing. + + The sub-progress monitor. + + + + Called when the active sub-task performs its updates. + + The sub-task's progress monitor. + + + + Called after performs its updates. + + The task name. + The total number of work units. + + + + Called when performs its updates. + + + + + Called when a state change occurs. + + + + + Called when performs its updates. + + + + + Called when performs its updates. + + The sub-task's progress monitor. + + + + Called when performs its updates. + + The sub-task's progress monitor. + + + + Called when performs its updates. + + The status message. + + + + Called when a new progress monitor is created. + + + + + Called when performs its updates. + + + + + Gets the number of remaining work units to perform, or . + + + + + Sets detailed status information for the current task or subtask. + + The name of the current subtask. + Thrown if is null. + Thrown if the task is not running. + + + + Gets the current status message set by or an empty + string by default. + + + + + Adds or removes an event handler that is called whenever a new sub-progress monitor + is created so that the observer can attach its event handlers. + + + + + Adds or removes an event handler that is called when the task is finished. + + + + + Gets the name of the task or an empty string if has + not been called. + + + + + Adds or removes an event handler that is called when the task is starting. + + + + + Gets the total number of work units to perform, or + NaN to indicate that an indeterminate amount of work is + to be performed. + + + + + Notifies that a given number of work units of the main task + have been completed. + + The number of work units completed so far. Must be + a finite value greater than or equal to 0. + Thrown if is not valid. + Thrown if the task is not running. + + + + A standard sub-progress monitor implementation that notifies its parent as work is performed. + + + + + Creates a sub-progress monitor. + + The parent progress monitor. + The total number of work units of the parent task + that are to be represented by the sub-task. + + + + Called after performs its updates. + + The task name. + The total number of work units. + + + + Called when performs its updates. + + + + + Called when a state change occurs. + + + + + Called when performs its updates. + + + + + Called when performs its updates. + + + + + A progress monitor task cookie represents a task in progress. + + + + + Creates an object representing a task in progress. + + The progress monitor. + Thrown if is null. + + + + Marks the task as finished. + + + + + A remote progress monitor is a serializable wrapper for another progress monitor. + + + + + Creates a wrapper for the specified progress monitor. + + The progress monitor. + Thrown if is null. + + + + Notifies that the main task is starting. + + The name of the task being monitored. + The total number of work units to perform. Must + be greater than 0, or if an indeterminate amount + of work is to be performed. + An object that calls when disposed. + Thrown if is null. + Thrown if is not valid. + Thrown if or have already been called. + + + + Creates a sub-progress monitor that represents a given number of + work-units as a sub-task of this progress monitor. + + The total number of work units of the parent task + that are to be represented by the sub-task. When the sub-task completes, this much + work will have been performed on the parent. + Must be a finite value greater than or equal to 0. + Thrown if is not valid. + + + + Notifies that the work is done, either the main task is completed + was cancelled by the user. If already done, the method has no effect. + + + + + Sets detailed status information for the current task or subtask. + + The name of the current subtask. + Thrown if is null. + Thrown if the task is not running. + + + + Notifies that a given number of work units of the main task + have been completed. + + The number of work units completed so far. Must be + a finite value greater than or equal to 0. + Thrown if is not valid. + Thrown if the task is not running. + + + + A console progress monitor presenter displays a simple tally of the amount of work + to be done on the main task as a bar chart. + + + + + Creates a console presenter for a progress monitor. + + The console. + Thrown if is null. + + + + Initializes the presenter after a progress monitor has been attached. + + + + + A console progress monitor displays a simple tally of the amount of work + to be done on the main task as a bar chart. + + + + + Creates a rich console progress monitor provider. + + The console to which messages should be written. + Thrown if is null. + + + + Gets a presenter for the progress monitor. + + The presenter. + + + + Provides a reference to the newly created sub-progress monitor. + + + + + Creates an event object. + + The new sub-progress monitor. + Thrown if is null. + + + + Gets the newly created sub-progress monitor. + + + + + Represents a task to be executed with a progress monitor. + + The progress monitor, never null. + + + + Abstract base class for implementing elevated commands. + + The argument type for the command, must be serializable. + The result type for the command, must be serializable. + + + Initializes a new instance of the class + + + + Executes the command. + + The command arguments. + The progress monitor, non-null. + The command result, must be null or serializable. + + + + Executes the command. + + The command arguments. + The progress monitor, non-null. + The command result, must be null or serializable. + + + + Default implementation of . + + + + + Creates an elevation manager. + + The runtime, not null. + + + + Returns true if the user of the current process has elevated privileges. + + + + + Acquires a context for performing elevated commands. + + An action to be provided with an elevation context + within which elevated commands may be invoked. + Specifies the reason an elevation is required. The + reason may be displayed to the user to explain the purpose of the request. + True if the elevation context was acquired and the action completed + successfully, false if the action failed or elevation was forbidden by the user or by the + operating system. + Thrown if + or is null. + + + + Performs an action using an elevation context. + + The elevation context, not null. + True if the action completed successfully. + + + + Represents a command to be executed in an elevated context. + + + + + Executes the command. + + The command arguments. + The progress monitor, non-null. + The command result, must be null or serializable. + + + + Provides a context within which commands may be executed with elevated privileges. + + + + + Executes an elevated command. + + The command id. + The command arguments, must be null or serializable. + The progress monitor. + The command result. + Thrown if + or is null. + + + + Provides privilege elevation services to perform tasks that require administrative rights. + + + + + Returns true if the user of the current process has elevated privileges. + + + + + Acquires a context for performing elevated commands. + + An action to be provided with an elevation context + within which elevated commands may be invoked. + Specifies the reason an elevation is required. The + reason may be displayed to the user to explain the purpose of the request. + True if the elevation context was acquired and the action completed + successfully, false if the action failed or elevation was forbidden by the user or by the + operating system. + Thrown if + or is null. + + + + Abstract base class for a utility command. + + The arguments type, may be + for commands with no arguments. + + + Initializes a new instance of the class + + + + Executes the command. + + The command execution context, not null. + The typed command arguments, not null. + The command exit code, zero for success, non-zero for errors. + + + + Validates the command arguments. + + The arguments object, not null. + The error reporter, not null. + True if the arguments are valid. + + + + A utility command to clear the current user's plugin metadata cache. + + + + Initializes a new instance of the class + + + + Executes the command. + + The command execution context, not null. + The typed command arguments, not null. + The command exit code, zero for success, non-zero for errors. + + + + The default utility command manager implementation. + + + + + Creates a utility command manager. + + The command handles, not null. + + + + Gets handles for all registered utility commands. + + + + + Gets the utility command with the specified name ignoring case, or null if not registered. + + The command name. + The command. + Thrown if is null. + + + + A utility command is a small command-line tool that can be invoked + via the Gallio.Utility.exe program. + + + + + Executes the command. + + The command execution context, not null. + The command exit code, zero for success, non-zero for errors. + + + + Gets the type of a class used to provide arguments to the command. + + The argument class. + + + + Validates the command arguments. + + The arguments object, not null. + The error reporter, not null. + True if the arguments are valid. + + + + Provides services for managing utility commands. + + + + + Gets handles for all registered utility commands. + + + + + Gets the utility command with the specified name ignoring case, or null if not registered. + + The command name. + The command. + Thrown if is null. + + + + An elevated command used for resetting the installation id. + + + + + Initializes the command. + + + + + The id of this elevated command. + + + + + Executes the command. + + The command arguments. + The progress monitor, non-null. + The command result, must be null or serializable. + + + + Arguments for the command. + + + + Initializes a new instance of the class + + + + A utility command to reset the installation id. + + + + + Creates the command. + + The elevation manager, not null. + + + + Executes the command. + + The command execution context, not null. + The typed command arguments, not null. + The command exit code, zero for success, non-zero for errors. + + + + Describes the execution context of a utility command and allows it + to interact with the environment. + + + + + Creates a utility command context. + + The parsed command line arguments. + The console. + The logger. + The progress monitor provider. + The verbosity. + Thrown if , + , or is null. + + + + Gets the parsed command-line arguments. + + + + + Gets the console. + + + + + Get the logger for writing messages to the console colored and + filtered by severity. + + + + + Gets the progress monitor provider for obtaining console progress monitors, + or a null progress monitor provider if progress monitoring has been disabled. + + + + + Gets the verbosity requested by the user. + + + + + Provides traits for . + + + + + Creates utility command traits. + + The unique name of the utility command. + The description of the utility command. + + + + Gets the description of the utility command. + + + + + Gets the unique name of the utility command. + + + + + A utility command to verify that the plugin metadata and installation parameters are correct. + + + + + Creates the command. + + The runtime, not null. + + + + Executes the command. + + The command execution context, not null. + The typed command arguments, not null. + The command exit code, zero for success, non-zero for errors. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio.xsd b/lib/Gallio_3.1.397.0/bin/Gallio.xsd new file mode 100644 index 00000000..c92f50a0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio.xsd @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio35.dll b/lib/Gallio_3.1.397.0/bin/Gallio35.dll new file mode 100644 index 00000000..465708b4 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio35.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio35.pdb b/lib/Gallio_3.1.397.0/bin/Gallio35.pdb new file mode 100644 index 00000000..db55e91f Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio35.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio35.plugin b/lib/Gallio_3.1.397.0/bin/Gallio35.plugin new file mode 100644 index 00000000..c5af61c3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio35.plugin @@ -0,0 +1,35 @@ + + + + Gallio Extensions for .Net 3.5 + 3.1.0.0 + Provides additional Gallio features for use with .Net 3.5. + plugin://Gallio/Resources/Gallio.ico + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio35.xml b/lib/Gallio_3.1.397.0/bin/Gallio35.xml new file mode 100644 index 00000000..8779fd49 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio35.xml @@ -0,0 +1,292 @@ + + + + Gallio35 + + + + + Extension methods for delegates. + + + + + Wraps an action as a function that returns a dummy value. + + The function. + + + + Extension methods for . + + + + + Binds the arguments of a function expression. + + The expression. + The argument value. + The parameter type. + The result type. + The bound function. + + + + Binds the arguments of a function expression. + + The expression. + The first argument value. + The second argument value. + The first parameter type. + The second parameter type. + The result type. + The bound function. + + + + Returns true if the expression represents a captured variable within a closure. + + The expression. + True if the expression represents a captured variable. + + + + Returns true if the expression represents a captured variable within a closure. + + The expression. + True if the expression represents a captured variable. + + + + Returns true if the expression represents a captured variable or a parameter. + + The expression. + True if the expression represents a captured variable or a parameter. + + + + Instuments an to intercept intermediate results + from each sub-expression. + + + + Initializes a new instance of the class + + + + Compiles an expression to introduce trace points. + + The expression tree. + The expression type. + The compiled delegate representing expression. + Thrown if is null. + + + + Evaluates a sub-expression and collects trace information. + + The sub-expression to evaluate. + The continuation that evaluates the sub-expression. + The return type of the sub-expression. + The result of the evaluation. + + + + Rewrites an expression tree to introduce trace points. + + The expression tree. + The expression type. + The compiled delegate representing expression. + Thrown if is null. + + + + Performs different actions depending on the type of visited. + + The visitor result type. + + + Initializes a new instance of the class + + + + Visits the expression. + + The expression. + The result. + + + + + Visits an expression of any type that does not have other special behavior. + + + The default implementation throws . + + + The expression. + The result. + + + + Visits a binary expression. + + The expression. + The result. + + + + Visits a conditional expression. + + The expression. + The result. + + + + Visits a constant expression. + + The expression. + The result. + + + + Visits an invocation expression. + + The expression. + The result. + + + + Visits a lambda expression. + + The expression. + The result. + + + + Visits an list init expression. + + The expression. + The result. + + + + Visits a member access expression. + + The expression. + The result. + + + + Visits a member init expression. + + The expression. + The result. + + + + Visits a call expression. + + The expression. + The result. + + + + Visits a new expression. + + The expression. + The result. + + + + Visits a new array expression. + + The expression. + The result. + + + + Visits a parameter expression. + + The expression. + The result. + + + + Visits a type binary expression. + + The expression. + The result. + + + + Visits a unary expression. + + The expression. + The result. + + + + Evaluates a conditional expression. If the condition evaluates differently + than expected, returns a detailed that + describes the formatted values of relevant sub-expressions within the condtion. + + + + + Evaluates a conditional expression. + + The conditional expression. + The expected result. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The assertion failure if the conditional expression evaluated + to a different result than was expected or threw an exception, otherwise null. + Thrown if is null. + + + + A formatting rule for . + + + + Initializes a new instance of the class + + + + Formats the specified object. + + The object to format, never null. + The formatter to use for recursive formatting, never null. + The formatted string representation of the object or null if the object + could not be formatted to produce a non-empty string. + + + + Gets the formatting rule's priority for object of the specified type. + + The type of object, never null. + The priority of this rule, or null if the rule does not support formatting the specified object type. + + + + Extensions methods for formatting. + + + + + Formats an object using the default . + + The object to format. + The formatted object. + + + + Formats an object using the specified . + + The object to format. + The formatter to use, or null for the default. + The formatted object. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Gallio40.dll b/lib/Gallio_3.1.397.0/bin/Gallio40.dll new file mode 100644 index 00000000..cd0b0a2c Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio40.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio40.pdb b/lib/Gallio_3.1.397.0/bin/Gallio40.pdb new file mode 100644 index 00000000..d81dbd68 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Gallio40.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Gallio40.plugin b/lib/Gallio_3.1.397.0/bin/Gallio40.plugin new file mode 100644 index 00000000..0ead3b10 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio40.plugin @@ -0,0 +1,29 @@ + + + + Gallio Extensions for .Net 4.0 + 3.1.0.0 + Provides additional Gallio features for use with .Net 4.0. + plugin://Gallio/Resources/Gallio.ico + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Gallio40.xml b/lib/Gallio_3.1.397.0/bin/Gallio40.xml new file mode 100644 index 00000000..9cd44d01 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Gallio40.xml @@ -0,0 +1,8 @@ + + + + Gallio40 + + + + diff --git a/lib/Gallio_3.1.397.0/bin/ICSharpCode.TextEditor.dll b/lib/Gallio_3.1.397.0/bin/ICSharpCode.TextEditor.dll new file mode 100644 index 00000000..75accd53 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/ICSharpCode.TextEditor.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.dll b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.dll new file mode 100644 index 00000000..0f8810ae Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.pdb b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.pdb new file mode 100644 index 00000000..1808d0ac Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.plugin b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.plugin new file mode 100644 index 00000000..84544686 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.plugin @@ -0,0 +1,18 @@ + + + + Gallio.Loader + 3.1.0.0 + Enables external applications to load Gallio components. + plugin://Gallio/Resources/Gallio.ico + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.xml b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.xml new file mode 100644 index 00000000..129f4e4f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Loader/Gallio.Loader.xml @@ -0,0 +1,269 @@ + + + + Gallio.Loader + + + + + The Gallio loader provides access to installed Gallio assemblies so that we can reference + them even if they are not copied locally. + + + + + Adds a hint directory to the assembly resolver. + + The path of the hint directory to add. + Thrown if is null. + Thrown if the operation could not be performed. + + + + Creates a private AppDomain that Gallio can reside in. + + The remote environment. + Thrown if Gallio does not appear to be installed. + Thrown if the operation could not be performed. + + + + Gets the runtime path that will be used by default by the loader. + + The installed runtime path. + Thrown if Gallio does not appear to be installed. + + + + Initializes the Gallio loader (if not already initialized) and returns + its singleton reference. + + The loader. + Thrown if Gallio does not appear to be installed. + Thrown if the operation could not be performed. + + + + Initializes the Gallio loader (if not already initialized) and returns + its singleton reference. + + The runtime path from which to load Gallio, + or null to determine it automatically. + The loader. + Thrown if Gallio does not appear to be installed. + Thrown if the operation could not be performed. + + + + Obtains a lifetime service object to control the lifetime policy for this instance. + + + An object of type used to control the lifetime policy for this instance. This is the current lifetime service object for this instance if one exists; otherwise, a new lifetime service object initialized to the value of the property. + + + The immediate caller does not have infrastructure permission. + + + + + Remotely initializes the Gallio loader (if not already initialized) and returns + its singleton reference within a foreign AppDomain. + + The AppDomain in which to initialize the loader. + The loader. + Thrown if is null. + Thrown if Gallio does not appear to be installed. + Thrown if the operation could not be performed. + + + + Remotely initializes the Gallio loader (if not already initialized) and returns + its singleton reference within a foreign AppDomain. + + The AppDomain in which to initialize the loader. + The runtime path from which to load Gallio, + or null to determine it automatically. + The loader. + Thrown if is null. + Thrown if Gallio does not appear to be installed. + Thrown if the operation could not be performed. + + + + Gets the Gallio loader instance, or null if not initialized. + + + + + + Resolves a runtime service. + + The type of service to resolve. + The resolved service. + Thrown if the operation could not be performed. + + + + Gets the Gallio runtime path. + + Thrown if the operation could not be performed. + + + + + Sets up the runtime with a default runtime setup using the loader's + runtime path and a null logger. Does nothing if the runtime has + already been initialized. + + + If you need more control over this behavior, call RuntimeBootstrap + yourself. + + + Thrown if the operation could not be performed. + + + + + Provides an interface for interacting with the Gallio Loader. + + + + + + Adds a hint directory to the assembly resolver. + + The path of the hint directory to add. + Thrown if is null. + Thrown if the operation could not be performed. + + + + Resolves a runtime service. + + The type of service to resolve. + The resolved service. + Thrown if the operation could not be performed. + + + + Resolves a runtime service. + + The type of service to resolve. + The resolved service. + Thrown if the operation could not be performed. + + + + Gets the Gallio runtime path. + + Thrown if the operation could not be performed. + + + + + Sets up the runtime with a default runtime setup using the loader's + runtime path and a null logger. Does nothing if the runtime has + already been initialized. + + + If you need more control over this behavior, call RuntimeBootstrap + yourself. + + + Thrown if the operation could not be performed. + + + + Provides access to an instance of the Gallio runtime that is running in a foreign AppDomain. + + + + + Gets the remote AppDomain. + + Thrown if the remote environment has been disposed. + + + + Gets the remote loader. + + Thrown if the remote environment has been disposed. + + + + + An exception that expresses a problem in a manner that may be safely communicated + across a remote context to a client that may not be able to load the original exception type. + + + Using this type prevents spurious exceptions + from being thrown due to the server exposing an internal exception type that + is not accessible to the client. + + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Wraps an exception as a . + + The exception type. + The wrapped exception. + Thrown if is null. + + + + Gets version information for Gallio components. + + + + + Gets a version label of a Gallio component assembly for display purposes. + + The assembly. + The version label. + Thrown if is null. + + + + Generates a version label from a version number for display purposes. + + The version to transform into a label. + The version label. + Thrown if is null. + + + + Gets the version number of an assembly for display purposes. + + The assembly. + The version number. + Thrown if is null. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MSTest/Gallio.MSTestAdapter.dll b/lib/Gallio_3.1.397.0/bin/MSTest/Gallio.MSTestAdapter.dll new file mode 100644 index 00000000..33198904 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MSTest/Gallio.MSTestAdapter.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MSTest/Gallio.MSTestAdapter.plugin b/lib/Gallio_3.1.397.0/bin/MSTest/Gallio.MSTestAdapter.plugin new file mode 100644 index 00000000..1b6a7951 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MSTest/Gallio.MSTestAdapter.plugin @@ -0,0 +1,38 @@ + + + + MSTest Adapter Plugin + 3.1.0.0 + Provides support for running MSTest tests. Requires MSTest to be installed separately. + + + + + + + + + + + + + + + + + + + + MSTest + Microsoft.VisualStudio.QualityTools.UnitTestFramework + Assembly + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MSTest/Readme.txt b/lib/Gallio_3.1.397.0/bin/MSTest/Readme.txt new file mode 100644 index 00000000..74415689 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MSTest/Readme.txt @@ -0,0 +1,5 @@ +MSTest Adapter Plugin +==================== + +This plugin uses MSTest.exe to adapt MSTest tests so that +they can run within Gallio and be manipulated by Gallio-based tools. diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.dll b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.dll new file mode 100644 index 00000000..5e3935d5 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.pdb b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.pdb new file mode 100644 index 00000000..df0af03a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.plugin b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.plugin new file mode 100644 index 00000000..5ceefd66 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.plugin @@ -0,0 +1,28 @@ + + + + MbUnit v3 Extensions for Backwards Compatibility + 3.1.0.0 + Provides extensions for MbUnit v3 to assist with test migration from MbUnit v2. + plugin://MbUnit/Resources/MbUnit.ico + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.xml b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.xml new file mode 100644 index 00000000..60ffe518 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit.Compatibility.xml @@ -0,0 +1,3053 @@ + + + + MbUnit.Compatibility + + + + + Array Assertion class + + + + + Verifies that both array have the same dimension and elements. + + The expected values. + The actual values. + + + + + + + + + + + Assertion class + + + + + Verifies that two decimals are equal. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + + + + Verifies that two decimals are equal. If + they are not equals then an is + thrown. + + The message printed out upon failure. + The expected value. + The actual value. + + + + Verifies that two decimals are equal. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + + The format of the message to display if the assertion fails, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + The maximum acceptable difference between the + the expected and the actual. + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + The maximum acceptable difference between the + the expected and the actual. + The message printed out upon failure. + + + + Verifies that two ints are equal. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + + + + Verifies that two ints are equal. If + they are not equals then an is + thrown. + + The message printed out upon failure. + The expected value. + The actual value. + + + + Verifies that two ints are equal. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + + The format of the message to display if the assertion fails, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. All + non-numeric types are compared by using the Equals method. + If they are not equal an is thrown. + + The value that is expected. + The actual value. + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. All + non-numeric types are compared by using the Equals method. + If they are not equal an is thrown. + + The value that is expected. + The actual value. + The message to display if objects are not equal. + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. All + non-numeric types are compared by using the Equals method. + If they are not equal an is thrown. + + The value that is expected. + The actual value. + + The format of the message to display if the assertion fails, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Verifies that two floats are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equals then an is + thrown. + + The expected value. + The actual value. + The maximum acceptable difference between the + the expected and the actual. + + + + Verifies that two floats are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equals then an is + thrown. + + The message printed out upon failure. + The expected value. + The actual value. + The maximum acceptable difference between the + the expected and the actual. + + + + + Asserts that two decimals are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + + + + Asserts that two decimals are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the objects are the same. + + + + Asserts that two decimals are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the two objects are the same object. + Arguments to be used in formatting the message. + + + + Asserts that two doubles are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + + + + Asserts that two doubles are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the objects are the same. + + + + Asserts that two doubles are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the two objects are the same object. + Arguments to be used in formatting the message. + + + + Asserts that two ints are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + + + + Asserts that two ints are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the objects are the same. + + + + Asserts that two ints are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the two objects are the same object. + Arguments to be used in formatting the message. + + + + Asserts that two objects are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + + + + Asserts that two objects are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the objects are the same. + + + + Asserts that two objects are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the two objects are the same object. + Arguments to be used in formatting the message. + + + + Asserts that two floats are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + + + + Asserts that two floats are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the objects are the same. + + + + Asserts that two floats are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the two objects are the same object. + Arguments to be used in formatting the message. + + + + Asserts that two uints are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + + + + Asserts that two uints are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the objects are the same. + + + + Asserts that two uints are not equal. If they are equal + an is thrown. + + The expected object. + The actual object. + The message to be displayed when the two objects are the same object. + Arguments to be used in formatting the message. + + + + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object. + The actual object. + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The message to be printed when the two objects are not the same object. + The expected object. + The actual object. + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object. + The actual object. + + The format of the message to display if the assertion fails, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Verifies that the value of the property described by is the same + in both ojects. + + + Property describing the value to test + + + Reference object + + + Actual object + + + Index of the property. + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + Asserts that is between and + . + + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + The first object. + The second object. + + + + Throws an with the message that is + passed in. This is used by the other Assert functions. + + + + + Throws an with the message that is + passed in. This is used by the other Assert functions. + + The message to initialize the with. + + + + Throws an with the message that is + passed in. This is used by the other Assert functions. + + + The format of the message to initialize the with. + + + An array containing zero or more objects to format. + + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + + + + Verifies that the first value is greater than the second + value. If they are not, then an + is thrown. + + The first value, expected to be greater. + The second value, expected to be less. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Verifies that is strictly greater than + . + + + + + Asserts that is in the dic . + + + + + Asserts that is in the dic . + + + + + Asserts that is in the enumerable collection . + + + + + Asserts that is in the enumerable collection . + + + + + Asserts that is in the list . + + + + + Asserts that is in the list . + + + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination. + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination. + The messge to display in case of failure. + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination. + The message to display in case of failure. + Array of objects to be used in formatting the message. + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing ICollection. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + Arguments to be used in formatting the message. + + + + Assert that a string is empty - that is equal to string.Emtpy + + The string to be tested. + + + + Assert that a string is empty - that is equal to string.Emtpy + + The string to be tested. + The message to be displayed on failure. + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested. + The message to be displayed on failure. + Arguments to be used in formatting the message. + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition. + + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition. + + The format of the message to display if the condition is false, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Asserts that an object is an instance of a given type. + + The expected Type. + The object being examined. + + + + Asserts that an object is an instance of a given type. + + The expected Type. + The object being examined. + A message to display in case of failure. + + + + Asserts that an object is an instance of a given type. + + The expected Type. + The object being examined. + A message to display in case of failure. + An array of objects to be used in formatting the message. + + + + Verifies that the double is passed is an NaN value. + If the object is not NaN then an + is thrown. + + The object that is to be tested. + + + + Verifies that the double is passed is an NaN value. + If the object is not NaN then an + is thrown. + + The object that is to be tested. + The message to be displayed when the object is not null. + + + + Verifies that the double is passed is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested. + The message to be displayed when the object is not null. + Arguments to be used in formatting the message. + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination. + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination. + The messge to display in case of failure. + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination. + The message to display in case of failure. + Array of objects to be used in formatting the message. + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing ICollection. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + Arguments to be used in formatting the message. + + + + Assert that a string is empty - that is equal to string.Emtpy + + The string to be tested. + + + + Assert that a string is empty - that is equal to string.Emtpy + + The string to be tested. + The message to be displayed on failure. + + + + Assert that a string is empty - that is equal to string.Emtpy + + The string to be tested. + The message to be displayed on failure. + Arguments to be used in formatting the message. + + + + Asserts that an object is not an instance of a given type. + + The expected Type. + The object being examined. + + + + Asserts that an object is not an instance of a given type. + + The expected Type. + The object being examined. + A message to display in case of failure. + + + + Asserts that an object is not an instance of a given type. + + The expected Type. + The object being examined. + A message to display in case of failure. + An array of objects to be used in formatting the message. + + + + Verifies that the object that is passed in is not equal to null + If the object is not null then an + is thrown. + + The object that is to be tested. + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown with the message that is passed in. + + The object that is to be tested. + The message to initialize the with. + + + + Verifies that the object that is passed in is not equal to null + If the object is not null then an + is thrown. + + The object that is to be tested. + + The format of the message to display if the assertion fails, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Verifies that the object that is passed in is equal to null + If the object is null then an + is thrown. + + The object that is to be tested. + + + + Verifies that the object that is passed in is equal to null + If the object is null then an + is thrown with the message that is passed in. + + The object that is to be tested. + The message to initialize the with. + + + + Verifies that the object that is passed in is equal to null + If the object is null then an + is thrown. + + The object that is to be tested. + + The format of the message to display if the assertion fails, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition. + + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition. + + The format of the message to display if the condition is false, + containing zero or more format items. + + + An array containing zero or more objects to format. + + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less. + The second value, expected to be greater. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is lower equal than + . + + + + + Verifies that is lower equal than + . + + + + + Verifies that is lower equal than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Verifies that is strictly lower than + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not between and + . + + + + + Asserts that is not in the dic . + + + + + Asserts that is not in the dic . + + + + + Asserts that is not in the enumerable collection . + + + + + Asserts that is not in the enumerable collection . + + + + + Asserts that is not in the list . + + + + + Asserts that is not in the list . + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + The first object. + The second object. + + + + + + Assertion helper for the class. + + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + ICollection of objects to be considered. + System.Type that all objects in collection must be instances of. + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + ICollection of objects to be considered. + System.Type that all objects in collection must be instances of. + The message that will be displayed on failure. + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + ICollection of objects to be considered. + System.Type that all objects in collection must be instances of. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Asserts that all items contained in collection are not equal to null. + + ICollection of objects to be considered. + + + + Asserts that all items contained in collection are not equal to null. + + ICollection of objects to be considered. + The message that will be displayed on failure. + + + + Asserts that all items contained in collection are not equal to null. + + ICollection of objects to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + ICollection of objects to be considered. + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + ICollection of objects to be considered. + The message that will be displayed on failure. + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + ICollection of objects to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the property value + of and are equal. + + + Instance containing the expected value. + + + Instance containing the tested value. + + + + + Verifies that the property value + of is equal to . + + + Expected value. + + + Instance containing the tested value. + + + + + Verifies that and + are equal collections. Element count and element wize equality is verified. + + + Expected value. + + + Instance containing the tested value. + + + + + Verifies that and + are equal collections. Element count and element wize equality is verified. + + + Expected value. + + + Instance containing the tested value. + + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The message that will be displayed on failure. + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the property value + of is equal to . + + + Expected value. + + + Instance containing the tested value. + + + + + Verifies that the property value + of and are equal. + + + Instance containing the expected value. + + + Instance containing the tested value. + + + + + Asserts that expected and actual are not exactly equal. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The IComparer to use in comparing objects from each ICollection. + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The IComparer to use in comparing objects from each ICollection. + The message that will be displayed on failure. + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The IComparer to use in comparing objects from each ICollection. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Asserts that expected and actual are not exactly equal. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The message that will be displayed on failure. + + + + Asserts that expected and actual are not exactly equal. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Asserts that expected and actual are not equivalent. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + + + + Asserts that expected and actual are not equivalent. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The message that will be displayed on failure. + + + + Asserts that expected and actual are not equivalent. + + The first ICollection of objects to be considered. + The second ICollection of objects to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the property value + of and are equal. + + + Instance containing the expected value. + + + Instance containing the tested value. + + + + + Verifies that the property value + of is equal to . + + + Expected value. + + + Instance containing the tested value. + + + + + Asserts that collection contains actual as an item. + + ICollection of objects to be considered. + Object to be found within collection. + + + + Asserts that collection contains actual as an item. + + ICollection of objects to be considered. + Object to be found within collection. + The message that will be displayed on failure. + + + + Asserts that collection contains actual as an item. + + ICollection of objects to be considered. + Object to be found within collection. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Asserts that collection does not contain actual as an item. + + ICollection of objects to be considered. + Object that cannot exist within collection. + + + + Asserts that collection does not contain actual as an item. + + ICollection of objects to be considered. + Object that cannot exist within collection. + The message that will be displayed on failure. + + + + Asserts that collection does not contain actual as an item. + + ICollection of objects to be considered. + Object that cannot exist within collection. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the property + is synchronized with the number of iterated elements. + + + Collection to test. + + + is a null reference (Nothing in Visual Basic). + + + + + Asserts that subset is not a subset of superset. + + The ICollection subset to be considered. + The ICollection superset to be considered. + + + + Asserts that subset is not a subset of superset. + + The ICollection subset to be considered. + The ICollection superset to be considered. + The message that will be displayed on failure. + + + + Asserts that subset is not a subset of superset. + + The ICollection subset to be considered. + The ICollection superset to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the property value + is false. + + + Instance containing the expected value. + + + + + Asserts that subset is a subset of superset. + + The ICollection subset to be considered. + The ICollection superset to be considered. + + + + Asserts that subset is a subset of superset. + + The ICollection subset to be considered. + The ICollection superset to be considered. + The message that will be displayed on failure. + + + + Asserts that subset is a subset of superset. + + The ICollection subset to be considered. + The ICollection superset to be considered. + The message that will be displayed on failure. + Arguments to be used in formatting the message. + + + + Verifies that the property value + is true. + + + Instance containing the expected value. + + + + + + + + + + + + Assertion class + + + + Initializes a new instance of the class + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing ICollection. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + Arguments to be used in formatting the message. + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing ICollection. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection. + The message to be displayed on failure. + Arguments to be used in formatting the message. + + + + Reflection Assertion class + + + + + Asserts that the type has a constructor, with the specified bindind flags, with a signature defined by parameters. + + + + + Asserts that the type has a public instance constructor with a signature defined by parameters. + + + + + Asserts that the type has a default public constructor + + + + + Asserts that the type has a field, with the specified bindind flags, with a signature defined by parameters. + + + + + Asserts that the type has a public field method with a signature defined by parameters. + + + + + Asserts that the type has a method, with the specified bindind flags, with a signature defined by parameters. + + + + + Asserts that the type has a public instance method with a signature defined by parameters. + + + + + Asserts whether an instance of the + can be assigned from an instance of . + + + Parent instance. + + + Child instance. + + + + + Asserts whether is an instance of the + . + + + instance. + + + Child instance. + + + + + + + + + + + Security Assertion class + + + + + Asserts that is authenticated. + + + + + Asserts that is not authenticated. + + + + + Asserts that the current windows identity is authenticated. + + + + + Asserts that the current windows identity is not authenticated. + + + + + Asserts that the current windows identity is in + role. + + + + + Asserts that the current windows identity is in + role. + + + + + Asserts that the current windows identity is in + role. + + + + + Asserts that the current windows identity is in . + + + + + Asserts that the current windows identity is in + role. + + + + + String Assertion class + + + + + Asserts that two strings are equal, ignoring the case + + + Expected string. + + + Actual string. + + + + + + Asserts the string does not contain c + + + String to test. + + + Variable list of characeters. + + + + + + Asserts the regular expression reg makes a full match on s + + + String to test. + + + Regular expression. + + + + + Asserts the regular expression regex makes a full match on + . + + + String to test. + + + Regular expression. + + + + + Asserts that the string is non null and empty + + + String to test. + + + + + Asserts that the string is non null and non empty + + + String to test. + + + + + Asserts the regular expression reg makes a match on s + + + String to test. + + + Regular expression. + + + + + Asserts the regular expression regex makes a match on s + + + String to test. + + + A instance. + + + + + Asserts the regular expression reg makes a match on s + + + String to test. + + + Regular expression. + + + + + Asserts the regular expression regex makes a match on s + + + String to test. + + + A instance. + + + + + + Class containing generic assert methods for XML markup + + + + + Asserts that two pieces of XMl are similar given their diff + + The XML diff. + + + + Asserts that two pieces of XML are similar. + + The control input. + The test input. + + + + Asserts that two pieces of XML are similar. + + The control text reader. + The test text reader. + + + + Asserts that two pieces of XML are similar. + + The control text. + The test text. + + + + Asserts that two pieces of XML are identical given their diff + + The XML diff. + + + + Asserts that two pieces of XML are identical. + + The control input. + The test input. + + + + Asserts that two pieces of XML are identical. + + The control text reader. + The test text reader. + + + + Asserts that two pieces of XML are identical. + + The control text. + The test text. + + + + Asserts that two pieces of XMl are not similar given their diff + + The XML diff. + + + + Asserts that two pieces of XML are not identical given their diff + + The XML diff. + + + + Asserts that some XML is valid. + + A object containing the XML to validate. + + + + Asserts that some XML is valid. + + The XML input. + + + + Asserts that some XML is valid. + + A pointing to the XML to test. + + + + Asserts that some XML is valid given a + A pointing to the XML to test. + The base URI. + + + + Asserts that is valid XML. + + The XMl to test. + + + + Asserts that is valid XML given a + The XML to test. + The base URI. + + + + Asserts that the flattened String obtained by executing an Xpath on some XML is a particular value + + An X path expression. + The XML to test. + The expected value. + + + + Asserts that the flattened String obtained by executing an Xpath on some XML is a particular value + + An X path expression. + The XML to test. + The expected value. + + + + Asserts that the flattened String obtained by executing an Xpath on some XML is a particular value + + An X path expression. + The XML to test. + The expected value. + + + + Assert that an XPath expression matches at least one node in someXml + + An X path expression. + The XML to test. + + + + Assert that an XPath expression matches at least one node in someXml + + An X path expression. + A reader ontot eh XML being tested. + + + + Assert that an XPath expression matches at least one node in someXml + + An X path expression. + The XML being tested. + + + + Asserts that the results of an XSL transform on some XML are the expected result + + The XSL transform. + The XML to transform. + The expected result. + + + + Asserts that the results of an XSL transform on some XML are the expected result + + The XSL transform. + The XML to transform. + The expected result. + + + + Provides compatibility with MbUnit v2 row test feature. + + + + Initializes a new instance of the class + + + + Provides compatibility with MbUnit v2 test fixture set up. + + + + Initializes a new instance of the class + + + + Provides compatibility with MbUnit v2 test fixture tear down. + + + + Initializes a new instance of the class + + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + + + + + + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + + + + + + + Utilities for manipulating differences. + + + + + Returns true is a difference is considered significant. + + + + + Describes the type of difference found. + + + + + Comparing an implied attribute value against an explicit value + + + + + Comparing 2 elements and one has an attribute the other does not + + + + + Comparing 2 attributes with the same name but different values + + + + + Comparing 2 attribute lists with the same attributes in different sequence + + + + + Comparing 2 CDATA sections with different values + + + + + Comparing 2 comments with different values + + + + + Comparing 2 document types with different names + + + + + Comparing 2 document types with different public identifiers + + + + + Comparing 2 document types with different system identifiers + + + + + Comparing 2 elements with different tag names + + + + + Comparing 2 elements with different number of attributes + + + + + Comparing 2 processing instructions with different targets + + + + + Comparing 2 processing instructions with different instructions + + + + + Comparing 2 different text values + + + + + Comparing 2 nodes with different namespace prefixes + + + + + Comparing 2 nodes with different namespace URIs + + + + + Comparing 2 nodes with different node types + + + + + Comparing 2 nodes but only one has any children + + + + + Comparing 2 nodes with different numbers of children + + + + + Comparing 2 nodes with children whose nodes are in different sequence + + + + + Comparing 2 Documents only one of which has a doctype + + + + + Comparing 2 Documents only one of which has an XML Prefix Declaration + + + + + Initializes a new instance of the class + + + + + + + + + Initializes a new instance of the class + + + + + + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + + + + + + + + + + + Initializes a new instance of the class + + + + + + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + Initializes a new instance of the class + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.dll b/lib/Gallio_3.1.397.0/bin/MbUnit.dll new file mode 100644 index 00000000..f7a77fac Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.dll.tdnet b/lib/Gallio_3.1.397.0/bin/MbUnit.dll.tdnet new file mode 100644 index 00000000..367728e3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit.dll.tdnet @@ -0,0 +1,6 @@ + + MbUnit v{0}.{1} + TDNet\Gallio.TDNetRunner.dll + Gallio.TDNetRunner.GallioResidentTestRunner + Resident + diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.pdb b/lib/Gallio_3.1.397.0/bin/MbUnit.pdb new file mode 100644 index 00000000..b0228810 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.plugin b/lib/Gallio_3.1.397.0/bin/MbUnit.plugin new file mode 100644 index 00000000..9e337fa2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit.plugin @@ -0,0 +1,54 @@ + + + + MbUnit v3 + 3.1.0.0 + Provides support for running MbUnit v3 tests. + plugin://MbUnit/Resources/MbUnit.ico + + + + + + + + + + + + + + + + + + + + + + + + MbUnit v3 + MbUnit, Version=3.1.0.0 + plugin://MbUnit/Resources/MbUnit.ico + 3.1.0.0 + Assembly + + + + + + MbUnit v3 Assembly + MbUnit v3 Test Assembly + plugin://MbUnit/Resources/MbUnit.ico + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit.xml b/lib/Gallio_3.1.397.0/bin/MbUnit.xml new file mode 100644 index 00000000..db945192 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit.xml @@ -0,0 +1,5416 @@ + + + + MbUnit + + + + + The MbUnit test framework. + + + + Initializes a new instance of the class + + + + Gets information about a particular pattern test framework extension. + + The test assembly. + The pattern test framework extension information. + + + + Gets the MbUnit version label. + + + + + Associates an annotation message of the specified type with the code element. + + + + + Associates an annotation message of the specified type with the code element. + + The annotation type. + The annotation message. + Thrown if is null. + + + + Sets the apartment state to be used to run the decorated test and its children + unless subsequently overridden. + + + + + Sets the apartment state to be used to run the decorated test and its children + unless subsequently overridden. + + The apartment state to use. + + + + Gets the apartment state to be used to run the decorated test. + + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Declares that a class contains assembly-level setup and teardown methods. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Applies semantic actions to a test to estalish its runtime behavior. + + The test builder. + The test type. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The type. + Thrown if the attribute is being used incorrectly. + + + + Registers a custom assembly resolver. + + + + + Registers a custom assembly resolver. + + The assembly resolver type, must + implement . + + + + Gets the assembly resolver type. + + + + + Performs early initialization for the specified assembly. + + The root scope that will eventually contain the assembly-level test. + The assembly to process. + + + + Defines a set of assertions that enable a test to verify the expected + behavior of the subject under test. + + + + + Prevents instantiation. + Subclasses should likewise define their constructor to be protected. + + + + + Verifies that an actual value approximately equals some expected value + to within a specified delta. + + The expected value. + The actual value. + The inclusive delta between the values. + The type of values to be compared. + The type of the difference produced when the values are + subtracted, for numeric types this is the same as but it + may differ for other types. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value approximately equals some expected value + to within a specified delta. + + The expected value. + The actual value. + The inclusive delta between the values. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of values to be compared. + The type of the difference produced when the values are + subtracted, for numeric types this is the same as but it + may differ for other types. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal and in the same order. + + The expected sequence. + The actual sequence. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal and in the same order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal and in the same order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal and in the same order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal and in the same order. + + The expected sequence. + The actual sequence. + The comparer to use. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal and in the same order. + + The expected sequence. + The actual sequence. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal but perhaps in a different order. + + The expected sequence. + The actual sequence. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal but perhaps in a different order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal but perhaps in a different order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal but perhaps in a different order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal but perhaps in a different order. + + The expected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that expected and actual sequences have the same number of elements and + that the elements are equal but perhaps in a different order. + + The expected sequence. + The actual sequence. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that unexpected and actual sequences differ in at least one element. + + The unexpected sequence. + The actual sequence. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that unexpected and actual sequences differ in at least one element. + + The unexpected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that unexpected and actual sequences differ in at least one element. + + The unexpected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that unexpected and actual sequences differ in at least one element. + + The unexpected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that unexpected and actual sequences differ in at least one element. + + The unexpected sequence. + The actual sequence. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that unexpected and actual sequences differ in at least one element. + + The unexpected sequence. + The actual sequence. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Asserts that two strings are equal according to a particular string comparison mode. + + The expected value. + The actual value. + The string comparison type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Asserts that two strings are equal according to a particular string comparison mode. + + The expected value. + The actual value. + The string comparison type. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value equals some expected value. + + The expected value. + The actual value. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value equals some expected value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value equals some expected value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value equals some expected value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value equals some expected value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value equals some expected value. + + The expected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not approximately equal some unexpected value + to within a specified delta. + + The expected value. + The actual value. + The inclusive delta between the values. + The type of values to be compared. + The type of the difference produced when the values are + subtracted, for numeric types this is the same as but it + may differ for other types. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not approximately equal some unexpected value + to within a specified delta. + + The expected value. + The actual value. + The inclusive delta between the values. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of values to be compared. + The type of the difference produced when the values are + subtracted, for numeric types this is the same as but it + may differ for other types. + Thrown if the verification failed unless the current indicates otherwise. + + + + Asserts that two strings are not equal according to a particular string comparison mode. + + The unexpected value. + The actual value. + The string comparison type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Asserts that two strings are not equal according to a particular string comparison mode. + + The unexpected value. + The actual value. + The string comparison type. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not equal some unexpected value. + + The unexpected value. + The actual value. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not equal some unexpected value according to a particular comparer. + + The unexpected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not equal some unexpected value according to a particular comparer. + + The unexpected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not equal some unexpected value according to a particular comparer. + + The unexpected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not equal some unexpected value according to a particular comparer. + + The unexpected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value does not equal some unexpected value. + + The unexpected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is not referentially identical to some unexpected value. + + The unexpected value. + The actual value. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is not referentially identical to some unexpected value. + + The unexpected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is referentially identical to some expected value. + + The expected value. + The actual value. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is referentially identical to some expected value. + + The expected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The type of value. + + + + Verifies that a test value is between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be deserialized from a stream using a + and returns the resulting deserialized object. + + The stream to deserialize. + The deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be deserialized from a stream using a + and returns the resulting deserialized object. + + The stream to deserialize. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized to a stream using a + and returns the resulting stream. + + The value. + The serialized stream. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized to a stream using a + and returns the resulting stream. + + The value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The serialized stream. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized then deserialized to and from a stream using a + and returns the resulting deserialized object. + + The value. + The serialized then deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized and deserialized to and from a stream using a + and returns the resulting deserialized object. + + The value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The serialized then deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that is in the enumeration . + + The enumeration of items. + The expected value expected to be found in the collection. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that is in the enumeration . + + The enumeration of items. + The expected value expected to be found in the collection. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string contains some expected value. + + The actual value. + The expected substring. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string contains some expected value. + + The actual value. + The expected substring. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that is in the dictionary . + + The dictionary of items. + The key expected to be found in the dictionary. + The type of key. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that is in the dictionary . + + The dictionary of items. + The key expected to be found in the dictionary. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of key. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be deserialized from a stream using the + specified and returns the resulting deserialized object. + + The stream to deserialize. + The object serialization formatter. + The deserialized object. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be deserialized from a stream using the specified + and returns the resulting deserialized object. + + The stream to deserialize. + The object serialization formatter. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The deserialized object. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of objects contains distinct values. + + The sequence of values to be tested. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of objects contains distinct values. + + The sequence of values to be tested. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of objects contains distinct values. + + The sequence of values to be tested. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of objects contains distinct values. + + The sequence of values to be tested. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of objects contains distinct values. + + The sequence of values to be tested. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of objects contains distinct values. + + The sequence of values to be tested. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that is not in the enumeration . + + The enumeration of items. + The unexpected value. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that is not in the enumeration . + + The enumeration of items. + The unexpected value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string does not contain some unexpected substring. + + The actual value. + The unexpected substring. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string does not contain some unexpected substring. + + The actual value. + The unexpected substring. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that is not in the dictionary . + + The dictionary of items. + The key that should not be found in the dictionary. + The type of key. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that is not in the dictionary . + + The dictionary of items. + The key expected to be found in the dictionary. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of key. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code does not throw an exception of any type. + + The action delegate to evaluate. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code does not throw an exception of any type. + + The action delegate to evaluate. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string ends with the specified text. + + The actual value. + The expected pattern. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string ends with the specified text. + + The actual value. + The expected pattern. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Always throws an . + Use instead. + + + + + Verifies that at least one element of the sequence meets the specified condition. + + The sequence of values to evaluate. + The condition that must be fulfilled (returns true) by at least one element of the sequence. + The type of values in the sequence. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that at least one element of the sequence meets the specified condition. + + The sequence of values to evaluate. + The condition that must be fulfilled (returns true) by at least one element of the sequence. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of values in the sequence. + Thrown if the verification failed unless the current indicates otherwise. + + + + Signals an unconditional assertion failure. + + Thrown unless the current indicates otherwise. + + + + Signals an unconditional assertion failure with a particular message. + + The format of the assertion failure message. + The arguments for the assertion failure message format string. + Thrown unless the current indicates otherwise. + + + + Verifies that all the elements of the sequence meet the specified condition. + + The sequence of values to evaluate. + The condition that must be fulfilled (returns true) by all the elements of the sequence. + The type of values in the sequence. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that all the elements of the sequence meet the specified condition. + + The sequence of values to evaluate. + The condition that must be fulfilled (returns true) by all the elements of the sequence. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of values in the sequence. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string matches regular expression pattern exactly. + + The actual value. + The regular expression pattern. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string matches regular expression pattern exactly. + + The actual value. + The regular expression pattern. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string matches regular expression pattern exactly. + + The actual value. + The regular expression pattern. + The regular expression options. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string matches regular expression pattern exactly. + + The actual value. + The regular expression pattern. + The regular expression options. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string matches regular expression pattern exactly. + + The actual value. + The regular expression. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string matches regular expression pattern exactly. + + The actual value. + The regular expression. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that the left value is greater than the right value according to a particular comparer. + + The expected value. + The actual value. + The type of value. + + + + Verifies that the left value is greater than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than the right value according to a particular comparer. + + The expected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The type of value. + + + + Verifies that the left value is greater than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater or equal than right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is greater than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Terminates the test and reports an inconclusive test outcome. + + Thrown always. + + + + Terminates the test and reports an inconclusive test outcome. + + The custom message format string, or null if none. + The custom message arguments, or null if none. + Thrown always. + + + + Verifies that an object may be assigned to a variable of the specified type. + + The object under examination. + The Type to compare with the object's Type. + + + + Verifies that an object may be assigned to a variable of the specified type. + + The object under examination. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The Type to compare with the object's Type. + + + + Verifies that an object may be assigned to a variable of the specified type. + + The Type to compare with the object's Type. + The object under examination. + Thrown if is null. + + + + Verifies that an object may be assigned to a variable of the specified type. + + The Type to compare with the object's Type. + The object under examination. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if is null. + + + + Verifies that an actual value contains no elements. + + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value contains no elements. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Returns true if there is a pending unreported assertion failure. + + + + + Verifies that an actual value is false. + + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is false. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is an instance of some expected type. + + The actual value. + The expected type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is an instance of some expected type. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The expected type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is an instance of some expected type. + + The expected type. + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that an actual value is an instance of some expected type. + + The expected type. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that an object may not be assigned to a variable of the specified type. + + The object under examination. + The Type to compare with the object's Type. + + + + Verifies that an object may not be assigned to a variable of the specified type. + + The object under examination. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The Type to compare with the object's Type. + + + + Verifies that an object may not be assigned to a variable of the specified type. + + The Type to compare with the object's Type. + The object under examination. + Thrown if is null. + + + + Verifies that an object may not be assigned to a variable of the specified type. + + The Type to compare with the object's Type. + The object under examination. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if is null. + + + + Verifies that an actual value contains at least one element. + + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value contains at least one element. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is not an instance of some unexpected type. + + The actual value. + The unexpected type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is not an instance of some unexpected type. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The unexpected type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is not an instance of some unexpected type. + + The unexpected type. + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that an actual value is not an instance of some unexpected type. + + The unexpected type. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that an actual value is not null. + + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is not null. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is null. + + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is null. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a type supports the runtime serialization protocol. + + The type to verify. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a type supports the runtime serialization protocol. + + The type to verify. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that an actual value is true. + + The actual value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an actual value is true. + + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a type supports the Xml serialization protocol used by . + + The type to verify. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a type supports the Xml serialization protocol used by . + + The type to verify. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that the left value is less than the right value according to a particular comparer. + + The expected value. + The actual value. + The type of value. + + + + Verifies that the left value is less than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than the right value according to a particular comparer. + + The expected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The type of value. + + + + Verifies that the left value is less than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the left value is less than or equal to the right value according to a particular comparer. + + The expected value. + The actual value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string contains a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string contains a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string contains a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + The regular expression options. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string contains a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + The regular expression options. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string contains a full or partial match of a regular expression pattern. + + The actual value. + The regular expression. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string contains a full or partial match of a regular expression pattern. + + The actual value. + The regular expression. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Evaluates a block of code that contains multiple related assertions. + + The action to invoke. + Thrown if is null. + + + + Evaluates a block of code that contains multiple related assertions. + + The action to invoke. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if is null. + + + + Verifies that a test value is not between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The type of value. + + + + Verifies that a test value is not between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is not between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is not between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is not between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The comparer to use, or null to use the default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a test value is not between left and right values according to a particular comparer. + + The actual value. + Inclusive minimum value. + Inclusive maximum value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string does not contain a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string does not contain a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string does not contain a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + The regular expression options. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string does not contain a full or partial match of a regular expression pattern. + + The actual value. + The regular expression pattern. + The regular expression options. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string does not contain a full or partial match of a regular expression pattern. + + The actual value. + The regular expression. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string does not contain a full or partial match of a regular expression pattern. + + The actual value. + The regular expression. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Provides methods for composing assertions to map over complex data structures. + + + + + Always throws an . + Use instead. + + + + + Verifies that an object can be serialized to a stream using the specified + and returns the resulting stream. + + The value. + The object serialization formatter. + The serialized stream. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized to a stream using the specified + and returns the resulting stream. + + The value. + The object serialization formatter. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The serialized stream. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized then deserialized to and from a stream using the + specified and returns the resulting deserialized object. + + The value. + The object serialization formatter. + The serialized then deserialized object. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized and deserialized to and from a stream using the + specified and returns the resulting deserialized object. + + The value. + The object serialization formatter. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The serialized then deserialized object. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of values are sorted in the specified order. + + The sequence of values to be tested. + The expected sort order. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of values are sorted in the specified order. + + The sequence of values to be tested. + The expected sort order. + A comparer instance to be used to compare two elements of the sequence, or null to use a default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of values are sorted in the specified order. + + The sequence of values to be tested. + The expected sort order. + A comparer instance to be used to compare two elements of the sequence, or null to use a default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of values are sorted in the specified order. + + The sequence of values to be tested. + The expected sort order. + A comparison function to be used to compare two elements of the sequence, or null to use a default one. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of values are sorted in the specified order. + + The sequence of values to be tested. + The expected sort order. + A comparison function to be used to compare two elements of the sequence, or null to use a default one. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that the sequence of values are sorted in the specified order. + + The sequence of values to be tested. + The expected sort order. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The type of value. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a string starts with the specified text. + + The actual value. + The expected pattern. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Verifies that a string starts with the specified text. + + The actual value. + The expected pattern. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if the verification failed unless the current indicates otherwise. + Thrown if is null. + + + + Terminates the test and reports a specific test outcome. + + The desired test outcome. + Thrown always. + + + + Terminates the test and reports a specific test outcome. + + The desired test outcome. + The custom message format string, or null if none. + The custom message arguments, or null if none. + Thrown always. + + + + Terminates the test silently and reports a specific test outcome. + + The desired test outcome. + Thrown always. + + + + Terminates the test silently and reports a specific test outcome. + + The desired test outcome. + The custom message format string, or null if none. + The custom message arguments, or null if none. + Thrown always. + + + + Verifies that a block of code throws an exception of a particular type. + + The action delegate to evaluate. + The expected type of exception. + The exception that was thrown. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type; and that + the exception has an inner exception of a particular type. + + The action delegate to evaluate. + The expected type of exception. + The expected type of the inner exception. + The exception that was thrown. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type. + + The action delegate to evaluate. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The expected type of exception. + The exception that was thrown. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type; and that + the exception has an inner exception of a particular type. + + The action delegate to evaluate. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The expected type of the exception. + The expected type of the inner exception. + The exception that was thrown. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type. + + The expected exception type. + The action delegate to evaluate. + The exception that was thrown. + Thrown if + or is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type. + + The expected exception type. + The action delegate to evaluate. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The exception that was thrown. + Thrown if + or is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type; and that + the exception has an inner exception of a particular type. + + The expected exception type. + The expected inner exception type, or null to ignore the inner exception. + The action delegate to evaluate. + The exception that was thrown. + Thrown if + or is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a block of code throws an exception of a particular type; and that + the exception has an inner exception of a particular type. + + The expected exception type. + The expected inner exception type, or null to ignore the inner exception. + The action delegate to evaluate. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The exception that was thrown. + Thrown if + or is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be deserialized from Xml using + an and returns the resulting deserialized object. + + The Xml. + The deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be deserialized from Xml using + an and returns the resulting deserialized object. + + The Xml. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized to Xml using an + and returns the resulting Xml as a string. + + The value. + The serialized Xml. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized to Xml using + an and returns the resulting Xml as a string. + + The value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The serialized Xml. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized then deserialized to and from Xml using + an and returns the resulting deserialized object. + + The value. + The serialized then deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that an object can be serialized then deserialized to and from Xml using + an and returns the resulting deserialized object. + + The value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The serialized then deserialized object. + Thrown if the verification failed unless the current indicates otherwise. + + + + Defines methods used with the syntax for mapping + assertions over complex data structures. + + + + + Evaluates an assertion over key/value pairs with identical keys drawn from two dictionaries. + + The left dictionary, or null. + The right dictionary, or null. + The assertion to evaluate over all pairs, with the left value as first + argument, and right value as second. + The key type. + The expected value type. + The expected value type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Evaluates an assertion over key/value pairs with identical keys drawn from two dictionaries. + + The left dictionary, or null. + The right dictionary, or null. + The assertion to evaluate over all pairs, with the left value as first + argument, and right value as second. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The key type. + The expected value type. + The expected value type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Evaluates an assertion over key/value pairs with identical keys drawn from two dictionaries. + + The left dictionary, or null. + The right dictionary, or null. + The assertion to evaluate over all pairs, with the key as first + argument, left value as second, and right value as third. + The key type. + The expected value type. + The expected value type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Evaluates an assertion over key/value pairs with identical keys drawn from two dictionaries. + + The left dictionary, or null. + The right dictionary, or null. + The assertion to evaluate over all pairs, with the key as first + argument, left value as second, and right value as third. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The key type. + The expected value type. + The expected value type. + Thrown if the verification failed unless the current indicates otherwise. + + + + Evaluates an assertion over pairs of values taken from two sequences. + + The left sequence, or null. + The right sequence, or null. + The assertion to evaluate given a left value and a right value. + The left value type. + The right value type. + + + + Evaluates an assertion over pairs of values taken from two sequence. + + The left sequence, or null. + The right sequence, or null. + The assertion to evaluate given a left value and a right value. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + The left value type. + The right value type. + + + + Associates the author's name and email address with a test fixture, test method, + test parameter or other test component. + + + + + Associates the author's name with the test component annotated + by this attribute. + + The author's name. + Thrown if is null. + + + + Associates the author's name and email address with the test component annotated + by this attribute. + + The author's name. + The author's email address. + Thrown if or is null. + + + + Associates the author's name, email address and homepage with the test component annotated + by this attribute. + + The author's name. + The author's email address. + The author's home page. + Thrown if , + or is null. + + + + Gets or sets the author's email address or an empty string if none. + + + + + Gets or sets the author's homepage or an empty string if none. + + + + + Gets or sets the author's name. + + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + The bind attribute overrides the default binding rules for a test parameter + by specifying a different data source, a binding path or an index. + + + + + Sets the binding index for the associated test parameter. + + The binding index. + + + + Sets the binding path for the associated test parameter. + + The binding path. + Thrown if is null. + + + + Applies decorations to a . + + The slot scope. + The slot. + + + + Gets the binding index, or null if none. + + + + + Gets the binding path, or null if none. + + + + + Gets or sets the name of the data source to bind, or null to bind + the default data source for the test parameter. + + + + + Associates a category name with a test fixture, test method, test parameter + or other test component. + + + + + Associates a category with the test component annotated by this attribute. + + The name of the category to associate. + Thrown if is null. + + + + Gets the name of the category. + + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + Provides a column of literal values as a data source. + + + + + Adds a column of literal values. + + The array of values in the column. + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Gets the array of values in the column. + + + + + Sets the join strategy of a test to be combinatorial. + + + + Initializes a new instance of the class + + + + Gets the join strategy to use. + + The join strategy. + + + + An abstract base class for data source attributes that obtain contents from + a local file, manifest resource, or inline data. + + + + Initializes a new instance of the class + + + + Gets or sets the inline data contents as a string. + + + + + Gets or sets the path of a local file relative to the current working + directory from which the file contents should be read. + + + + + Gets the name of the location that is providing the data, or null if none. + + + + + Returns true if the contents are dynamic, or false if they are static. + + + + + Opens the contents as a stream. + + The code element to which the attribute was applied. + The stream. + + + + Opens the contents as a text reader. + + The code element to which the attribute was applied. + The text reader. + + + + Gets or sets the path of a manifest resource from which the contents should be read. + + + + + Gets or sets a that is used to locate the assembly and + namespace within which to resolve a manifest resource in combination + with the property. + + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + Validates the data source properties of the content attribute. + + The pattern scope. + The code element to which the attribute was applied. + Thrown if none of the source properties, such as , + or have been set. + + + + Provides data from Comma Separated Values (CSV) contents. + + + + Initializes a new instance of the class + + + + Gets or sets a character that indicates that a line in the source represents a comment. + + + + + Gets or sets the field delimiter character. + + + + + Gets or sets whether the CSV document has a header that should be used to provide + aliases for indexed columns. + + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + An abstract base class for MbUnit attributes that contribute values to data sources + along with metadata such a description or expected exception type. + + + + Initializes a new instance of the class + + + + Gets or sets a description of the values provided by the data source. + + + + + Gets or sets the type of exception that should be thrown when the + values provided by the data source are consumed by test. + + + + + Gets or sets the message of the exception that should be thrown when the + values provided by the data source are consumed by test. + May be a substring of the actual exception message. + + + + + Gets the metadata for the data source. + + The metadata keys and values. + + + + Specifies the default test case timeout for all tests in the test assembly. + + + + + Sets the default timeout in seconds, or zero if none. + + The timeout in seconds, or zero if none. + Thrown if is less than 0. + + + + Applies decorations to an assembly-level test. + + The assembly scope. + The assembly. + + + + Gets the timeout, or null if none. + + + + + Gets the default timeout in seconds, or zero if none. + + + + + Specifies the maximum number of concurrent threads to use when tests are run in parallel + for all tests in the test assembly. + + + + + Specifies the maximum number of concurrent threads to use when tests are run in parallel. + + The degree of parallelism. + Thrown if is less than 1. + + + + Applies decorations to an assembly-level test. + + The assembly scope. + The assembly. + + + + Gets the degree of parallelism. + + + + + Creates a dependency from this test assembly, test fixture or test method on some other test + fixture or test method. + + + + + Creates a dependency from this test on another test method within this test fixture. + + The dependent test method name. + Thrown if is null. + + + + Creates a dependency from this test on another test fixture. + + The dependent test fixture type. + Thrown if is null. + + + + Creates a dependency from this test on a particular test method within another test fixture. + + The dependent test fixture type. + The dependent test method name. + Thrown if or is null. + + + + Gets the code element that declares the tests on which this test should depend. + + The scope. + The code element. + The code element representing the dependency. + + + + Gets the dependent test fixture type, or null if the dependency is on another + test method of this test fixture. + + + + + Gets the dependent test method name, or null if the dependency + is on the whole test fixture. + + + + + Associates a description with a test fixture, test method, test parameter + or other test component. + + + + + Associates a description with the test component annotated by this attribute. + + The description to associate. + Thrown if is null. + + + + Gets or sets the description. + + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + Specifies a method that is used to generate tests dynamically at runtime. + + + + Initializes a new instance of the class + + + + Executes the test method. + + The test instance state, not null. + + + + Provides a column of enumeration values as a data source. + + + + + Adds a column of enumeration values. + + The type of the enumeration. + The specified type is null. + The specified type is not an enumeration type. + + + + Gets the type of the enumeration. + + + + + Sets or gets the single enumeration value that must be excluded from the column. + + + + + Sets or gets an array of values that must be excluded from the column. + + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Declares that the associated test is expected to throw an . + + + + + Declares that the associated test is expected to throw an . + + + + + Declares that the associated test is expected to throw an . + + The expected exception message, or null if not specified. + + + + Declares that the associated test is expected to throw an . + + + + + Declares that the associated test is expected to throw an . + + + + + Declares that the associated test is expected to throw an . + + The expected exception message, or null if not specified. + + + + Declares that the associated test is expected to throw an . + + + + + Declares that the associated test is expected to throw an . + + + + + Declares that the associated test is expected to throw an . + + The expected exception message, or null if not specified. + + + + Declares that the associated test is expected to throw an exception of + a particular type. + + + + + Declares that the associated test is expected to throw an exception of + a particular type. + + The expected exception type. + Thrown if is null. + + + + Declares that the associated test is expected to throw an exception of + a particular type. + + The expected exception type. + The expected exception message, or null if not specified. + May be a substring of the actual exception message. + Thrown if is null. + + + + Applies decorations to a method-level test. + + The method scope. + The method. + + + + Gets the expected exception type. + + + + + Gets or sets the expected exception message, or null if none specified. + May be a substring of the actual exception message. + + + + + Indicates that a test should only be run explicitly. + + + + + Indicates that this test should only run explicitly without providing a reason. + + + + + Indicates that this test should only run explicitly and provides a reason. + + The reason for which the test should be run explicitly. + Thrown if + is null. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Gets the reason that the test should only run explicitly. + + + + + Specifies a factory member that will provide values for a data-driven test. + + + + + Specifies the name of a method, property or field of the fixture + class that will provide values for a data-driven test. + + The factory member name. + Thrown if is null. + + + + Specifies the declaring type and name of a static method, property or field + that will provide values for a data-driven test. + + The declaring type of the factory. + The factory member name. + Thrown if + or is null. + + + + Gets or sets the number of columns produced by the factory, or 0 if unknown. + + Thrown if is + less than zero. + + + + Gets or sets the kind of the factory. + + + + + Gets the factory member name, never null. + + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Gets the declaring type of the factory, or null if it is assumed to be the fixture class. + + + + + Specifies a method that is to be invoked after a fixture instance has been + created to complete its initialization before test fixture setup runs. + + + + Initializes a new instance of the class + + + + + Applies decorations to the containing test. + + + The containing scope. + The method to process. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + Specifies a method that is to be invoked to set up the state of a fixture + before any of its tests are executed. + + + + Initializes a new instance of the class + + + + + Applies decorations to the containing test. + + + The containing scope. + The method to process. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + Specifies a method that is to be invoked to tear down the state of a fixture + after all of its tests have been executed. + + + + Initializes a new instance of the class + + + + + Applies decorations to the containing test. + + + The containing scope. + The method to process. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + Provides a column of sequential values as a data source. + + + + + Default constructor. + + + + + Returns a generator of random values. + + The containing scope. + A generator. + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Defines names as aliases for the columns in an indexed data source + such as those that have been populated by or . + + + + + Defines names as aliases for the columns in an indexed data source. + + The names of the columns in the data source in order by index. + Thrown if or + if one of the values it contains is null. + + + + Gets the array of column names. + + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Indicates that a test is to be ignored by the framework and will not be run. + + + + + Indicates that this test is to be ignored without providing a reason. + + + + + Indicates that this test is to be ignored and provides a reason. + + The reason for which the test is to be ignored. + Thrown if + is null. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Gets the reason that the test has been ignored, or an empty string if none. + + + + + Run a test or a test fixture under another user account. + + + + Initializes a new instance of the class + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Gets or sets the domain where the user is defined. + + + + + Gets or sets the password. + + + + + Gets or sets the user name. + + + + + Specifies the test's relative importance which can be used for classifying tests + to be executed. + + + + + Critical importance. + + + + + Severe importance. Less important than . + + + + + Serious importance. Less important than . + + + + + Default importance. + + + + + Not important. + + + + + Associates a with a test fixture, test method, + test parameter or other test component. + + + + + Associates a with the test component annotated by this attribute. + + The importance to associate. + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + Gets or sets the importance. + + + + + Specifies options for the operation. + + + + + Specifies a custom action to be executed between each consecutive attempt, but not before the first one. + + A custom action to be executed. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + Thrown if is null. + + + + Specifies the maximum number of evaluation attempts, before the , or + operation fails. + + The maximum number of evaluation cycles, or zero or a negative value to specify an unlimited number of attempts. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + + + + Specifies the condition to evaluate repeatedly, and starts the entire operation. + + The condition to evaluate. + Thrown when the condition is false, and a timeout occured, or the maximum + number of evaluation attempts was reached. + + + + Specifies a instance to wait for being terminated, and starts the entire operation. + + The thread to evaluate. + Thrown when the thread is still alive, and a timeout occured, or the maximum + number of evaluation attempts was reached. + + + + Specifies a instance to wait for being signaled, and starts the entire operation. + + The wait handle to evaluate. + Thrown when the wait handle is unsignaled, and a timeout occured, or the maximum + number of evaluation attempts was reached. + + + + Specifies a custom formatted message to be added to the text of the assertion raised when + the retry operation has failed. + + A user-supplied assertion failure message string, or null if none. + The format arguments, or null or empty if none. + + + + + + Specifies a polling time expressed in milliseconds between each consecutive evaluation of the condition. + + The polling time expressed in milliseconds. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + Thrown if is negative. + + + + Specifies a polling time between each consecutive evaluation of the condition. + + The polling time. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + Thrown if represents a negative duration. + + + + Specifies a timeout value expressed in milliseconds. + + The timeout value expressed in milliseconds, or a negative value to specify no timeout value. + A value of zero, will let the condition to be evaluated only once. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + + + + Specifies a timeout value. + + The timeout value, or a negative value to specify no timeout value. + A value of zero, will let the condition to be evaluated only once. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + + + + An abstract class for attributes that specify the join strategy of a test. + + + + Initializes a new instance of the class + + + + Gets the join strategy to use. + + The join strategy. + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + Associates custom metadata with a test fixture, test method, test parameter + or other test component. The metadata can be used for documentation, classification + or dynamic customization of tests. + + + + + Associates custom metadata with a test component. + + The metadata key. + The metadata value. + Thrown if + or is null. + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + Gets the metadata key. + + + + + Gets the metadata value. + + + + + Runs the test as if it were surrounded by so that + multiple assertion failures within the test are tolerated. + + + + Initializes a new instance of the class + + + + Applies decorations to a method-level test. + + The method scope. + The method. + + + + Run a test or a test fixture under different cultures. + + + + + Initializes a new instance of the class. + + An array of culture names to run the test under. + Thrown if is a null reference. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Overrides the name of a test or test parameter. + + + + + Overrides the name of a test or test parameter. + + The overridden name. + Thrown if is null. + + + + Gets the overridden name. + + + + + Processes a code element and applies its contributions to the scope of this pattern. + The scope will typically have been introduced by the method + of a primary pattern applied to this code element. + + The scope. + The code element to process. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The scope. + The code element. + Thrown if the attribute is being used incorrectly. + + + + Sets the join strategy of a test to be pairwise. + + + + Initializes a new instance of the class + + + + Gets the join strategy to use. + + The join strategy. + + + + Specifies that a test can be run in parallel with other parallelizable tests. + + + + + Specifies that this test is parallelizable. + + + + + Specifies that the tests in the specified scope are parallelizable. + + The test scope. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Gets the scope to which the parallelizable attribute applies. + + + + + Declares that a property, field, method parameter, constructor parameter, + generic type parameter or generic method parameter represents a test parameter. + + + + Initializes a new instance of the class + + + + Indicates that a test has pending prerequisites so it will not be run. + + + + + Indicates that this test has pending prerequisites without providing a reason. + + + + + Indicates that this test has pending prerequisites and provides a reason. + + The reason for which the test is pending. + Thrown if + is null. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Gets the reason that the test is pending. + + + + + Run a test or a test fixture under another user account. + + + + Initializes a new instance of the class + + + + Creates a principal object which represents the security context + of the user on whose behalf the test is running. + + A principal object. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Provides a column of random values as a data source. + + + + + Adds a column of random values. + + + + + Gets or sets the number of random values that are going to be generated. + + + + + Gets or sets the name of a method present in the test fixture + whose purpose is to prevent some specific values to be generated. + + + + + Returns a generator of random values. + + The containing scope. + A generator. + + + + Gets or sets the upper bound of the numeric range where random values are going to be generated. + + + + + Gets or sets the lower bound of the numeric range where random values are going to be generated. + + + + + Provides a column of random values as a data source. + + + + + Adds a column of random values. + + + + + Gets or sets the number of random values that are going to be generated. + + + + + Gets or sets the name of a method present in the test fixture + whose purpose is to prevent some specific values to be generated. + + + + + Returns a generator of random values. + + The containing scope. + A generator. + + + + Gets or sets a regular expression pattern to generate random string from. + + + + + Gets or sets the stock of predefined strings from which to draw random values. + + + + + Identifies a stock of predefined string values for the random strings generator. + + + + + A predefined collection of random US male names. + + + + + A predefined collection of random country names. + + + + + Decorates a test method and causes it to be invoked repeatedly. + + + + + Executes the test method repeatedly. + + The number of times to repeat the test. + Thrown if + is less than 1. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Evaluates repeatedly the specified condition until it becomes fulfilled, or throws + a if a timeout occured, or if the + evaluation was done unsuccessfully too many times. + + + + Initializes a new instance of the class + + + + Specifies a custom action to be executed between each consecutive attempt, but not before the first one. + + A custom action to be executed. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + Thrown if is null. + + + + Specifies the maximum number of evaluation attempts, before the , or + operation fails. + + The maximum number of evaluation cycles, or zero or a negative value to specify an unlimited number of attempts. + An instance to specify other options for the retry operation. + Thrown if the options was called more than once. + + + + Specifies the condition to evaluate repeatedly, and starts the entire operation. + + The condition to evaluate. + Thrown when the condition is still false, and a timeout occured, or the maximum + number of evaluation attempts was reached. + + + + Specifies a instance to wait for being terminated, and starts the entire operation. + + The thread to evaluate. + Thrown when the thread is still alive, and a timeout occured, or the maximum + number of evaluation attempts was reached. + + + + Specifies a instance to wait for being signaled, and starts the entire operation. + + The wait handle to evaluate. + Thrown when the wait handle is still unsignaled, and a timeout occured, or the maximum + number of evaluation attempts was reached. + + + + Specifies a custom formatted message to be added to the text of the assertion raised when + the retry operation has failed. + + A user-supplied assertion failure message string, or null if none. + The format arguments, or null or empty if none. + + + + + + Specifies a polling time expressed in milliseconds between each consecutive evaluation of the condition. + + The polling time expressed in milliseconds. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + Thrown if is negative. + + + + Specifies a polling time between each consecutive evaluation of the condition. + + The polling time. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + Thrown if represents a negative duration. + + + + Specifies a timeout value expressed in milliseconds. + + The timeout value expressed in milliseconds, or a negative value to specify no timeout value. + A value of zero, will let the condition to be evaluated only once. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + + + + Specifies a timeout value. + + The timeout value, or a negative value to specify no timeout value. + A value of zero, will let the condition to be evaluated only once. + An instance to specify other options for the retry operation. + Thrown if the option was called more than once. + + + + Decorates a test method whose database operation must be executed within a transaction and rolled + back when it has finished executing. + + + + + Tags a test method whose database operation must be executed within a transaction and rolled + back when it has finished executing. + + + + + Applies decorations to a test. + + The scope. + The code element. + + + + When set to true, includes setup and teardown in the rollback. Otherwise + only transactions performed during the test itself are affected. + + + + + Provides a row of literal values as a data source. + + + + + Adds a row of literal values. + + The array of values in the row. + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Gets the array of values in the row. + + + + + Sets the join strategy of a test to be sequential. + + + + Initializes a new instance of the class + + + + Gets the join strategy to use. + + The join strategy. + + + + Provides a column of sequential values as a data source. + + + + + Adds a column of sequential values. + + + + + Gets or sets the length of the sequence. + + + + + Gets or sets the ending value of the sequence. + + + + + Gets or sets the name of a method present in the test fixture + whose purpose is to prevent some specific values to be generated. + + + + + Returns a generator of random values. + + The containing scope. + A generator. + + + + Gets or sets the starting value of the sequence. + + + + + Gets or sets the increment between each value of the sequence. + + + + + Specifies a method that is to be invoked before each test in a fixture executes + to set up the state of the test. + + + + Initializes a new instance of the class + + + + Expected sorting order for the assertion. + + + + + Each value is expected to be greater than or equal to the previous value. + + + + + Each value is expected to be strictly greater than the previous value. + + + + + Each value is expected to be less than or equal to the previous value. + + + + + Each value is expected to be strictly less than the previous value. + + + + + Specifies a method that is used to generate tests statically at + test exploration time. + + + + Initializes a new instance of the class + + + + + Applies decorations to the containing test. + + + The containing scope. + The method to process. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The method. + Thrown if the attribute is being used incorrectly. + + + + A general-purpose structural equality comparer that defines a fully customizable equality operation without the + need to implement . + + The type of the objects. to compare. + + + Initializes a new instance of the class + + + + Adds a matching criterion to the structural equality comparer. + + An accessor that gets an enumeration of values from the tested object. + A comparer instance for the values returned by the accessor, or null to use the default one. + Some options indicating how to compare the enumeration of values returned by the accessor. + The type of the value returned by the accessor. + The specified accessor argument is a null reference. + + + + Adds a matching criterion to the structural equality comparer. + + An accessor that gets an enumeration of values from the tested object. + A comparer instance for the values returned by the accessor, or null to use the default one. + The type of the value returned by the accessor. + The specified accessor argument is a null reference. + + + + Adds a matching criterion to the structural equality comparer. + + An accessor that gets an enumeration of values from the tested object. + A comparer instance for the values returned by the accessor, or null to use the default one. + Some options indicating how to compare the enumeration of values returned by the accessor. + The type of the value returned by the accessor. + The specified accessor argument is a null reference. + + + + Adds a matching criterion to the structural equality comparer. + + An accessor that gets a value from the tested object. + The type of the value returned by the accessor. + The specified accessor argument is a null reference. + + + + Adds a matching criterion to the structural equality comparer. + + An accessor that gets a value from the tested object. + A equality comparison delegate to compare the values returned by the accessor, or null to use the default one. + The type of the value returned by the accessor. + The specified accessor argument is a null reference. + + + + Adds a matching criterion to the structural equality comparer. + + An accessor that gets a value from the tested object. + A comparer instance, or null to use the default one (). + The type of the value returned by the accessor. + The specified accessor argument is a null reference. + + + + Adds a matching criterion to the structural equality comparer. + + An equality comparison delegate to directly compare two instances, or null to use the default one. + + + + Adds a matching criterion to the structural equality comparer. + + An comparer object to directly compare two instances, or null to use the default one. + + + + Gets a default neutral structural equality comparer for the tested type. + + + + + Determines whether the specified objects are equal. + + The first object of type T to compare. + The second object of type T to compare. + true if the specified objects are equal; otherwise, false. + + + + Returns a strongly-typed enumerator that iterates through the collection. + + A strongly-typed enumerator that iterates through the collection. + + + + Returns a hash code for the specified object. + + The object for which a hash code is to be returned. + A hash code for the specified object. + The type of obj is a reference type and obj is null. + + + + Comparison options for the structural equality comparer. + + + + + Default options. + + + + + Compares the two child sequences by ignoring the order of the elements. + + + + + Specifies a method that is to be invoked after each test in a fixture executes + to tear down the state of the test. + + + + Initializes a new instance of the class + + + + Describes a test generated either at test exploration time or at test + execution time by a test factory. + + + + Initializes a new instance of the class + + + + Builds a static test during test exploration. + + The containing pattern evaluation scope. + The code element that represents the scope in which the test was defined. + + + + Builds a collection of static tests during test exploration. + + The enumeration of tests to build as children of the containing scope. + The containing pattern evaluation scope. + The code element that represents the scope in which the test was defined. + Thrown if , + or is null or contains a null. + + + + Runs a dynamic test during test execution. + + The code element that represents the scope in which the test was defined. + Optional set-up code to run before the test, or null if none. + Optional tear-down code to run after the test, or null if none. + + + + Runs a collection of dynamic tests during test execution. + + The enumeration of tests to run. + The code element that represents the scope in which the test was defined. + Optional set-up code to run before the test, or null if none. + Optional tear-down code to run after the test, or null if none. + Thrown if or + is null or contains a null. + + + + Specifies that a method represents a single test case within a fixture. + + + + Initializes a new instance of the class + + + + Executes the test method. + + The test instance state, not null. + + + + Describes a test case generated either at test exploration time or at test + execution time by a test factory. + + + + + Creates a test case with a delegate to execute as its main body. + + The test case name. + The main body of the test case. + Thrown if or + is null. + + + + Gets the delegate to run as the main body of the test case. + + + + + Returns true if the test represents an individual test case. + + + + + Gets the test kind. + + + + + Executes the main body of the test, excluding its children (which will + run afterwards). + + + + + Gets or sets a set-up action to be executed before the test case. + + + + + Gets or sets a tear-down action to be executed after the test case. + + + + + An abstract base class for implementing new test decorator behaviors. + + + + Initializes a new instance of the class + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Disposes the test. + + The test instance state, not null. + + + + Executes the test. + + The test instance state, not null. + + + + Initializes the test. + + The test instance state, not null. + + + + Sets up the test. + + The test instance state, not null. + + + + Tears down the test. + + The test instance state, not null. + + + + Abstract class for custom test definitions such as generated test cases + and test suites. + + + + + Creates a test. + + The test name. + Thrown if is null. + + + + Builds a static test during test exploration. + + The containing pattern evaluation scope. + The code element that represents the scope in which the test was defined. + + + + Gets or sets the code element associated with the test, or null if none. + + + + + Gets or sets the description metadata of the test, or null if none. + + + + + Gets the children of this test. + + + + + Returns true if the test represents an individual test case. + + + + + Gets the test kind. + + + + + Gets a mutable table of metadata entries associated with the test. + + + + + Gets the test name. + + + + + Executes the main body of the test, excluding its children (which will + run afterwards). + + + + + Runs set-up code before each child. + + + + + Runs set-up code before execute and before all children. + + + + + Runs tear-down code after each child. + + + + + Runs tear-down code after execute and after all children. + + + + + Runs a dynamic test during test execution. + + The code element that represents the scope in which the test was defined. + Optional set-up code to run before the test, or null if none. + Optional tear-down code to run after the test, or null if none. + + + + Gets or sets the maximum amount of time the whole test including + its setup, teardown and body should be permitted to run. + + Thrown if + represents a negative time span. + + + + Specifies that a class represents a test fixture. This attribute is optional. + + + + Initializes a new instance of the class + + + + Describes a reference to another test fixture. + + + + + Creates a reference to a test fixture. + + The test fixture type. + Thrown if is null. + + + + Builds a static test during test exploration. + + The containing pattern evaluation scope. + The code element that represents the scope in which the test was defined. + + + + Runs a dynamic test during test execution. + + The code element that represents the scope in which the test was defined. + Optional set-up code to run before the test, or null if none. + Optional tear-down code to run after the test, or null if none. + + + + Gets the referenced test fixture type, or null if the reference is on a + test method of the containing test fixture. + + + + + Specifies the scope to which certain attributes apply. + + + + + Applies to this test only. + + + + + Applies to the descendants of this test only. + + + + + Applies to this test and its descendants. + + + + + Associates the name of the type under test with a test fixture, test method, + test parameter or other test component. + + + + + Associates the full name or assembly qualified name of the type under test + with the test component annotated by this attribute. + + The name of the type under test as obtained by + or . + Thrown if is null. + + + + Associates the type under test with the test component annotated by this attribute. + + The type under test. + Thrown if is null. + + + + Gets the metadata key / value pairs to be added to the test component. + + The metadata entries. + + + + Gets the full name or assembly qualified name of the type under test. + + + + + Describes a test suite generated either at test exploration time or at test + execution time by a test factory. + + + + + Creates a test suite. + + The test suite name. + Thrown if is null. + + + + Gets a mutable list of the children of this test. + + + + + Gets the children of this test. + + + + + Returns true if the test represents an individual test case. + + + + + Gets the test kind. + + + + + Runs set-up code before each child. + + + + + Runs set-up code before execute and before all children. + + + + + Runs tear-down code after each child. + + + + + Runs tear-down code after execute and after all children. + + + + + Gets or sets a delegate to run before each test case in the suite, or null if none. + + + + + Gets or sets a delegate to run before all test cases in the suite, or null if none. + + + + + Gets or sets a delegate to run after all test cases in the suite, or null if none. + + + + + Gets or sets a delegate to run after each test case in the suite, or null if none. + + + + + Decorates a test method and causes it to be invoked repeatedly + on multiple concurrent threads. + + + + + Executes the test method on the specified number of concurrent threads. + + The number of threads to execute the test on. + Thrown if + is less than 1. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Sets the maximum amount of time in seconds that a test or fixture is permitted to run. + + + + + Sets the test timeout in seconds, or zero if none. + + The timeout in seconds, or zero if none. + Thrown if is less than 0. + + + + Applies decorations to a test. + + The scope. + The code element. + + + + Gets the timeout, or null if none. + + + + + Gets the test timeout in seconds, or zero if none. + + + + + Provides data from XML contents. + + + + + Specifies a XML-based data source. + + The XPath expression used to select items within the document. + Thrown if is null. + + + + Populates the data source with the contributions of this attribute. + + The scope. + The data source. + The code element. + + + + Abstract base class for contracts. + + + + Initializes a new instance of the class + + + + Verifies that the specified method info object is not null, indicating that the + method exists, otherwise raises an assertion failure and describes the expected method signature. + + The method, or null if missing. + The expected method signature for diagnostic output. + + + + Gets the execution context. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + The context of execution. + An enumeration of tests. + + + + Gets the interface of a particular type if it is implemented by another type, + otherwise returns null. + + The implementation type. + The interface type. + The interface type or null if it is not implemented by the implementation type. + + + + Contract for verifying the implementation of public type accessors, usually the getter and the setter of a particular property. + + The type of the tested object which contain the accessors. + The type of the value handled by the accessors. + + + + Default constructor. + + + + + Determines whether the tested accessors are expected to accept a null reference as a valid input. + + + + + Provides a default instance of the tested type. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Specifies an explicit way to get a value from the tested accessors. + + + + + Defines a collection of incompetence classes which identify object instances that are expected to be not accepted + by the tested setter. Each incompetence class contains a collection of distinct object instance associated + with an expected exception type. + + + + + Specifies the name of tested property. + + + + + Specifies an explicit way to set a value to the tested accessors. + + + + + Defines a collection of distinct object instances that are expected to be inconditionally accepted as + valid input by the tested setter. Feeding that contract property with at least one value is mandatory. + + + + + Contract for verifying the implementation of the generic . + + The type of the collection implementing . + The type of items contained in the collection. + + + + Default constructor. + + + + + Determines whether the collection is expected to accept several identical items (object equality). + The default value is true. + + + + + Determines whether the collection is expected to accept null references as valid items. + + + + + Asserts that the collection of distinct instances specified by the user is not empty. + + + + + Creates a test that invokes an action over the collection, which + is supposed to not be supported. The test expects that an exception be thrown. + + The name of the tested method. + The action to evaluate. + + + + + + Creates a test which runs an action over the collection with + a null argument. The test expects that an exception be thrown. + + The name of the tested method. + The action to evaluate. + + + + + + Provides a default instance of the collection to test. + + + + + Gets a collection of distinct object instances that feeds the different tests. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Returns safely a default instance of the tested type. + + A new instance of the tested type as specified in the contract. + Thrown if the instance cannot be generated. + + + + Determines whether the tested collection is expected to be read-only. + + + + + Contract for verifying the implementation of the generic interface. + + The type of the object to evaluate. + + + + Default constructor. + + + + + Gets or sets the collection of equivalence classes of instances + to feed the contract verifier. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Determines whether the verifier will evaluate the presence and the + behavior of the 4 operator overloads "Greater Than", "Greater Than + Or Equal", "Less Than", and "Less Than Or Equal". + + + + + A collection of distinct object instances. Every element represents a valid instance + which is different from all the other elements in the collection (object equality). + + The type of the object instances in the collection. + + + + Constructs an empty collection of distinct object instances. + + + + + Constructs acollection of distinct object instances from the specified + enumeration of elements. + + An enumeration of distinct object instances. + + + + Adds the specified instance to the collection. + + A valid and non-null object instance. + + + + Returns a strongly-typed enumerator that iterates through the collection. + + A strongly-typed enumerator. + + + + Gets all the instances. + + + + + Contract for verifying the implementation of the generic interface. + + The target tested type which implements the generic interface. + + + + Default constructor. + + + + + Gets or sets the collection of equivalence classes of instances + to feed the contract verifier. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Determines whether the verifier will evaluate the presence and the + behavior of the equality and the inequality operator overloads. + + + + + Contains a collection of equivalent object instances. + + The type of equivalent object instances. + + + + Constructs a class of equivalent instances. + + The type of equivalent object instances. + + + + Gets the collection of equivalent instances. + + + + + Returns a strongly-typed enumerator that iterates through the collection. + + A strongly-typed enumerator. + + + + A collection of equivalence classes. + + The type of equivalent object instances. + + + + Constructs an empty collection of equivalence classes. + + + + + Constructs a collection of equivalence classes from the specified distinct object instances. + + An enumeration of distinct instances. + + + + Adds to the collection a new equivalence class which contains the specified objects. + + An array of equivalent instances. + + + + Gets the equivalence classes. + + + + + Returns a strongly-typed enumerator that iterates through the collection. + + A strongly-typed enumerator. + + + + Contract for verifying the implementation of a custom exception type. + + The target custom exception type. + + + + Default constructor. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Determines whether the verifier will check for the serialization support. + + + + + Determines whether the verifier will check for the presence of + the recommended standard constructors. + + + + + Performs round-trip serialization of the exception and returns the result. + + The exception instance. + The instance produced after serialization and deserialization. + + + + Describes a contract that can be verified. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + The context of execution. + An enumeration of tests. + + + + Contract for verifying the implementation of an immutable type. + + The target immutable type. + + + + Default constructor. + + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + A collection of distinct object instances associated with a particular exception type. + + The type of the object instances in the collection. + + + + Constructs an empty collection of distinct object instances associated with an exception type. + + The type of the expected exception. + + + + Constructs a collection of distinct object instances associated with an exception type. + + The type of the exception associated with the object instances in the collection. + An array of distinct object instances. + + + + The type of the exception associated with the object instances in the collection. + + + + + A collection of classes of distinct object instances gathered by the type + of the exception which is expected to be raised when the subject instances are passed + to a tested method or property. + + The type of the object instances in the inner class collections. + + + + Constructs an empty collection of classes of distinct object instances. + + + + + Adds the specified class of distinct object instance to the collection. + + The class to add to the collection. + + + + Adds a new class of distinct object instances to the collection. + + The exception type to associate with the new class. + an array of distinct object instances to populate the new class. + + + + Gets the number of invalid classes in the collection. + + + + + Returns a strongly-typed enumerator that iterates through the collection. + + A strongly-typed enumerator. + + + + Contract for verifying the implementation of the generic interface. + + The type of the collection implementing . + The type of items contained by the list. + + + Initializes a new instance of the class + + + + Gets an enumeration of test cases whose purpose is to verify the contract. + + An enumeration of tests. + + + + Verifies that a contract has been satisfied. + + + + Initializes a new instance of the class + + + + Consumes a code element and applies its contributions to the scope + provided by a containing pattern. + + The containing scope. + The code element to process. + If true, skips generating child test components. + Instead the children may be populated on demand using + . The implementation + may safely ignore the value of this flag so long as subsequent attempts to populate children on + demand are idempotent (do nothing or have no adverse side-effects). + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Generates static or dynamic tests from the contract. + + The field scope. + The field. + The containing scope. + + + + Initializes a test for a contract verifier field after it has been added to the test model. + + The field scope. + The field. + + + + Returns true if this is a primary pattern. + + + + + Returns true if the code element represents a test. + + The evaluator. + The code element. + True if the code element represents a test. + May be thrown to halt processing of the pattern + and report an error message to the user as an annotation that describes how the + pattern was misapplied. + + + + Verifies that the attribute is being used correctly. + + The containing scope. + The field. + Thrown if the attribute is being used incorrectly. + + + + Execution context of a contract verification test. + + + + + Constructs an execution context for the verification tests of a contract verifier. + + The code element for the contract read-only field. + Thrown if is null. + + + + Gets the code element for the contract read-only field. + + + + + Gets an artificial stack trace data that points to + the contract read-only field. + + An artificial stack trace data that points to the contract read-only field. + + + + Access modifier of a class or class member. + + + + + Public. + + + + + Protected, internal, private. + + + + + Static. + + + + + Default that includes public, protected, internal, private, and static. + + + + + Member types of a class. + + + + + Method. + + + + + Field or variable. + + + + + Property. + + + + + Indicates that a reflection operation performed by failed. + + + + + Creates an exception. + + + + + Creates an exception from serialization info. + + The serialization info. + The streaming context. + + + + Creates an exception. + + The message. + + + + Creates an exception. + + The message. + The inner exception. + + + + Helper class to test non-public classes and class members. + + + + + Constructor for object. + + Object to be referred to in methods. + + + + Use this constructor if you plan to test default constructor of a non-public class. + + Assembly name. + Type name. + + + + Use this constructor if you plan to test constructor with arguments of a non-public class. + + Assembly name. + Type name. + Parameters for a constructor. + + + + Creates an instance + + Full assembly path. + Type Name such as (System.String). + Newly created object. + + + + Creates an instance + + Full assembly path. + Type Name such as (System.String) + Constructor parameters. + Newly created object. + + + + Gets the field value. + + Specify field access modifier. + Object where field is defined. + Field name. + Field value. + + + + Gets the field value. + + Specify field access modifier. + Object where field is defined. + Field name. + Specify if need to look in Base classes. + Field value. + + + + Gets the public, non-public, or static field value. + + Object where field is defined. + Field name. + Field value. + + + + Gets the public, non-public, or static field value. + + Field name. + Field value. + + + + Gets the field value. + + Field name. + Specify field access modifier. + Field value. + + + + Gets the field value. + + Field name. + Specify field access modifier. + Specify if need to look in Base classes. + Field value. + + + + Gets the property value. + + Specify property access modifier. + Object that has the property. + Property Name. + Property Value. + + + + Gets the property value. + + Specify property access modifier. + Object that has the property. + Property Name. + Set to true if need look for the property in base classes. + Property Value. + + + + Get the property value + + Specify property access modifier. + Property Name. + Property Value. + + + + Get the property value. + + Specify property access modifier. + Property Name. + Specify if need to look in Base classes. + Property Value. + + + + Gets the property value. + + Object where property is defined. + Property Name. + Property Value. + + + + Gets the property value + + Property Name. + Property Value. + + + + Executes a non-public method with arguments on a object + + Specify method access modifier. + Object where method is defined. + Method to call. + Speicifies if to search for the method in the base classes or not. + Method's parameters. + The object the method should return. + + + + Executes a non-public method with arguments on a object + + Specify method access modifier. + Object where method is defined. + Method to call. + Method's parameters. + The object the method should return. + + + + Executes a non-public method with arguments on a object + + Method to call. + Specify method access modifier. + Method's parameters. + The object the method should return. + + + + Executes a non-public method with arguments on a object + + Object where method is defined. + Method to call. + The object the method should return. + + + + Executes a non-public method with arguments on a object + + Object where method is defined. + Method to call. + Method's parameters. + The object the method should return. + + + + Executes a non-public method with arguments on a object + + Method to call. + The object the method should return. + + + + Executes a non-public method with arguments on a object + + Method to call. + Method's parameters. + The object the method should return. + + + + Sets the field value. + + Specify field access modifier. + Object where field is defined. + Field Name. + Field Value. + + + + Sets the field value. + + Specify field access modifier. + Object where field is defined. + Field Name. + Field Value. + Specify if need to look in Base classes. + + + + Sets the field value. + + Field Name. + Field Value. + Specify field access modifier. + + + + Sets the field value. + + Object where field is defined. + Field Name. + Field Value. + + + + Sets the field value. + + Field Name. + Field Value. + + + + Sets the property value. + + Specify property access modifier. + Object where property is defined. + Property Name. + Property Value. + + + + Sets the property value. + + Specify property access modifier. + Object where property is defined. + Property Name. + Property Value. + Set to true if need look for the property in base classes. + + + + Sets the property value. + + Specify property access modifier. + Property Name. + Property Value. + + + + Sets the property value. + + Object where property is defined. + Property Name. + Property Value. + + + + Sets the property value. + + Property Name. + Property Value. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/Gallio.MbUnit2Adapter.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/Gallio.MbUnit2Adapter.dll new file mode 100644 index 00000000..03eb4737 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/Gallio.MbUnit2Adapter.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/Gallio.MbUnit2Adapter.plugin b/lib/Gallio_3.1.397.0/bin/MbUnit2/Gallio.MbUnit2Adapter.plugin new file mode 100644 index 00000000..681f7626 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/Gallio.MbUnit2Adapter.plugin @@ -0,0 +1,106 @@ + + + + MbUnit v2 Adapter Plugin + 3.1.0.0 + Provides support for running MbUnit v2 tests. + plugin://Gallio.MbUnit2Adapter/Resources/MbUnit.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MbUnit v2 + MbUnit.Framework + 2.4.2.175 + plugin://Gallio.MbUnit2Adapter/Resources/MbUnit.ico + Assembly + + + + + + MbUnit v2 Assembly + MbUnit v2 Test Assembly + plugin://Gallio.MbUnit2Adapter/Resources/MbUnit.ico + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.2.0.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.2.0.dll new file mode 100644 index 00000000..9150d063 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.2.0.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.2.0.xml b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.2.0.xml new file mode 100644 index 00000000..abe249c2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.2.0.xml @@ -0,0 +1,278 @@ + + + + MbUnit.Framework.2.0 + + + + Assertion class This class cannot be inherited. + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + Arguments to be used in formatting the message + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + + + Assert that an array,list or other collection is empty + An array, list or other collection implementing ICollection + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + Arguments to be used in formatting the message + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + + + Assert that an array,list or other collection is empty + An array, list or other collection implementing ICollection + + + Create Instance + Full assembly path. + Type Name such as (System.String) + Newly created object. + + + Create Instance + Full assembly path. + Type Name such as (System.String) + Constructor parameters. + Newly created object. + + + Get public, non-public, or static field value. + Object where field is defined. + Field name. + Field value + + + Get field value. + Specify field access modifier. + Object where field is defined. + Field name. + Field value + + + Get field value. + Specify field access modifier. + Object where field is defined. + Field name. + Specify if need to look in Base classes. + Field value + + + Get public, non-public, or static field value. + Field name. + Field value + + + Get field value. + Field name. + Specify field access modifier. + Field value + + + Get field value. + Field name. + Specify field access modifier. + Specify if need to look in Base classes. + Field value + + + Gets value of NonPublic field. + NonPublic field name + Field value + + + Gets value of NonPublic property + Property name + Property value + + + Get the value from a NonPublic variable or field. + Object which contains field + Field Name + + + Get the value from a NonPublic variable or field. + Object which contains field + Field Name + + + Get Property Value + Object where property is defined. + Property Name. + Property Value. + + + Get Property Value + Specify property access modifier. + Property Name. + Property Value. + + + Get Property Value + Specify property access modifier. + Property Name. + Set to true if need look for the property in base classes. + Property Value. + + + Get Property Value + Property Name. + Property Value. + + + Get Property Value + Specify property access modifier. + Property Name. + Property Value. + + + Get Property Value + Specify property access modifier. + Property Name. + Specify if need to look in Base classes. + Property Value. + + + Execute a NonPublic method with arguments on a object + Object where method is defined. + Method to call + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Object where method is defined. + Method to call + Method's parameters. + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Specify method access modifier. + Object where method is defined. + Method to call + Method's parameters. + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Specify method access modifier. + Object where method is defined. + Method to call + Method's parameters. + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Method to call + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Method to call + Method's parameters. + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Method to call + Specify method access modifier. + Method's parameters. + The object the method should return. + + + Execute a NonPublic method on a object + Object to call method on + Method to call + + + Execute a NonPublic method without arguments on a object + Object to call method on + Method to call + The object the method should return. + + + Execute a NonPublic method with arguments on a object + Object to call method on + Method to call + The object the method should return. + + + Set field value. + Object where field is defined. + Field Name. + Field Value. + + + Set field value. + Specify field access modifier. + Object where field is defined. + Field Name. + Field Value. + + + Set field value. + Specify field access modifier. + Object where field is defined. + Field Name. + Field Value. + Specify if need to look in Base classes. + + + Set field value. + Field Name. + Field Value. + + + Set field value. + Field Name. + Field Value. + Specify field access modifier. + + + Set Property value. + Object where property is defined. + Property Name. + Property Value. + + + Set Property value. + Specify property access modifier. + Object where property is defined. + Property Name. + Property Value. + + + Set Property value. + Specify property access modifier. + Object where property is defined. + Property Name. + Property Value. + Set to true if need look for the property in base classes. + + + Set Property value. + Property Name. + Property Value. + + + Set Property value. + Specify property access modifier. + Property Name. + Property Value. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.dll new file mode 100644 index 00000000..172cc979 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.dll.tdnet b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.dll.tdnet new file mode 100644 index 00000000..54d021d2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.dll.tdnet @@ -0,0 +1,6 @@ + + MbUnit v{0}.{1}.{2} + ..\TDNet\Gallio.TDNetRunner.dll + Gallio.TDNetRunner.GallioResidentTestRunner + Resident + diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.xml b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.xml new file mode 100644 index 00000000..c039b458 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/MbUnit.Framework.xml @@ -0,0 +1,4748 @@ + + + + MbUnit.Framework + + + + Event argument that contains an assembly. + + + Returns true if the entire test fixture is ignored. + + + TODO - Add class summary + + + Static helper functions for retreiving resources This is a and so cannot be inherited or instantiated. + + + Creates and saves the images in the directory with the specified path. + The directory path in which to save the images + + + This class represents the execution pipe of a test. It contains a sequence of . + + + TODO - Add class summary + + + Event argument that carries a instance. + + + Helper static class for Type related tasks This class cannot be inherited. + + + Creates an instance of the type using the default Method. + type to instanciate + type instance + + + Creates an instance of the type using the Method that matches the signature defined by + type to instanciate + argument of the Method + type instance initialized using + + + Gets the first method of the type that is tagged by a instance. + type to test + custom attribute type to search + First method of that that is tagged by a instance, null if no method is tagged by the specified attribute type. + + or is a null reference + + + Gets all methods of the type that are tagged by a instance. + type to test + custom attribute type to search + + collection of type that that are tagged by a instance. + + or is a null reference + + + Retreives the that matches the signature. + type to test + Method parameter types + The instance of matching the signature. + + is a null reference + No Method of type match the signature defined by . + + + Retreives the that matches the signature, given the list of arguments. + type to test + Method arguments from which the signature is deduced + The instance of matching the signature defined by the list of arguments. + + is a null reference + One of the args item is a null reference + No Method of type match the signature defined by . + + + Gets the first instance of from the method custom attributes. + Method to test + custom attribute type to search + First instance of from the method custom attributes. + + or is a null reference + + is not tagged by an attribute of type + + + Retreives the indexer that matches the signature + type that holds the indexer + indexer arguments + + + Gets the value of the property . + property + object instnace + property arguments (in case of an indexer + property value + + + Gets a value indicating if the type contains a Method with the signature defined by . + type to test + arguments of the Method + true if contains a Method matching types + t is a null reference + + + Gets a value indicating if the is tagged by a instance. + method to test + custom attribute type to search + true if is tagged by a attribute, false otherwise. + + or is a null reference + + + Gets a value indicating if the method info is tagged by a instance. + method to test + custom attribute type to search + true if is tagged by a attribute, false otherwise. + + or is a null reference + + + Gets a value indicating if the type has an indexer that takes arguments. + type that holds the indexer + indexer arguments + true if an indexer that matched the signature was found, false otherwise + + + Gets a value indicating the class type has a method that is tagged by a instance. + type to test + custom attribute type to search + true if class type has a method tagged by a attribute, false otherwise. + + or is a null reference + + + Gets a value indicating if the match the + property or method paramter info + tested signature + + + Output the methods and their custom attributes to the console. (Debugging method) + type to visit + + is a null reference + + is anot a class type. + + + Gets the first instance of from the method custom attributes. + Method to test + custom attribute type to search + First instance of from the method custom attributes; otherwize a null reference + + or is a null reference + + + Assembly event delegate + + + Type event delegate + + + A collection of elements of type Assembly This class cannot be inherited. + + + Gets or sets the Assembly at the given index in this AssemblyCollection. + + + Adds an instance of type Assembly to the end of this AssemblyCollection. + The Assembly to be added to the end of this AssemblyCollection. + + + Determines whether a specfic Assembly value is in this AssemblyCollection. + The Assembly value to locate in this AssemblyCollection. + true if value is found in this AssemblyCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this AssemblyCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific Assembly from this AssemblyCollection. + The Assembly value to remove from this AssemblyCollection. + + + Type-specific enumeration class, used by AssemblyCollection.GetEnumerator. This class cannot be inherited. + + + A dictionary with keys of type Assembly and values of type TypeCollection This class cannot be inherited. + + + Gets or sets the TypeCollection associated with the given Assembly + The Assembly whose value to get or set. + + + Gets a collection containing the keys in this AssemblyTypeCollectionDictionary. + + + Gets a collection containing the values in this AssemblyTypeCollectionDictionary. + + + Adds an element with the specified key and value to this AssemblyTypeCollectionDictionary. + The Assembly key of the element to add. + + + Determines whether this AssemblyTypeCollectionDictionary contains a specific key. + The Assembly key to locate in this AssemblyTypeCollectionDictionary. + true if this AssemblyTypeCollectionDictionary contains an element with the specified key; otherwise, false. + + + Removes the element with the specified key from this AssemblyTypeCollectionDictionary. + The Assembly key of the element to remove. + + + Adds an instance of type Fixture to the end of this FixtureCollection. + The Fixture to be added to the end of this FixtureCollection. + + + Determines whether a specfic Fixture value is in this FixtureCollection. + The Fixture value to locate in this FixtureCollection. + true if value is found in this FixtureCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this FixtureCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific Fixture from this FixtureCollection. + The Fixture value to remove from this FixtureCollection. + + + Type-specific enumeration class, used by FixtureCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type IFixtureFactory This class cannot be inherited. + + + Adds an instance of type IFixtureFactory to the end of this FixtureFactoryCollection. + The IFixtureFactory to be added to the end of this FixtureFactoryCollection. + + + Determines whether a specfic IFixtureFactory value is in this FixtureFactoryCollection. + The IFixtureFactory value to locate in this FixtureFactoryCollection. + true if value is found in this FixtureFactoryCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this FixtureFactoryCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific IFixtureFactory from this FixtureFactoryCollection. + The IFixtureFactory value to remove from this FixtureFactoryCollection. + + + Type-specific enumeration class, used by FixtureFactoryCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type IRun This class cannot be inherited. + + + Gets or sets the IRun at the given index in this RunCollection. + + + Adds an instance of type IRun to the end of this RunCollection. + The IRun to be added to the end of this RunCollection. + + + Determines whether a specfic IRun value is in this RunCollection. + The IRun value to locate in this RunCollection. + true if value is found in this RunCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RunCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific IRun from this RunCollection. + The IRun value to remove from this RunCollection. + + + Type-specific enumeration class, used by RunCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type IRunInvoker This class cannot be inherited. + + + Gets or sets the IRunInvoker at the given index in this IRunInvokerCollection. + + + Adds an instance of type IRunInvoker to the end of this IRunInvokerCollection. + The IRunInvoker to be added to the end of this IRunInvokerCollection. + + + Determines whether a specfic IRunInvoker value is in this IRunInvokerCollection. + The IRunInvoker value to locate in this IRunInvokerCollection. + true if value is found in this IRunInvokerCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this IRunInvokerCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific IRunInvoker from this IRunInvokerCollection. + The IRunInvoker value to remove from this IRunInvokerCollection. + + + Type-specific enumeration class, used by IRunInvokerCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type RunInvokerVertex This class cannot be inherited. + + + Gets or sets the RunInvokerVertex at the given index in this RunInvokerVertexCollection. + + + Adds an instance of type RunInvokerVertex to the end of this RunInvokerVertexCollection. + The RunInvokerVertex to be added to the end of this RunInvokerVertexCollection. + + + Determines whether a specfic RunInvokerVertex value is in this RunInvokerVertexCollection. + The RunInvokerVertex value to locate in this RunInvokerVertexCollection. + true if value is found in this RunInvokerVertexCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RunInvokerVertexCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific RunInvokerVertex from this RunInvokerVertexCollection. + The RunInvokerVertex value to remove from this RunInvokerVertexCollection. + + + Type-specific enumeration class, used by RunInvokerVertexCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type RunInvokerVertexCollection This class cannot be inherited. + + + Gets or sets the RunInvokerVertexCollection at the given index in this RunInvokerVertexCollectionCollection. + + + Adds an instance of type RunInvokerVertexCollection to the end of this RunInvokerVertexCollectionCollection. + The RunInvokerVertexCollection to be added to the end of this RunInvokerVertexCollectionCollection. + + + Determines whether a specfic RunInvokerVertexCollection value is in this RunInvokerVertexCollectionCollection. + The RunInvokerVertexCollection value to locate in this RunInvokerVertexCollectionCollection. + true if value is found in this RunInvokerVertexCollectionCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RunInvokerVertexCollectionCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific RunInvokerVertexCollection from this RunInvokerVertexCollectionCollection. + The RunInvokerVertexCollection value to remove from this RunInvokerVertexCollectionCollection. + + + Type-specific enumeration class, used by RunInvokerVertexCollectionCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type RunPipe This class cannot be inherited. + + + Gets or sets the RunPipe at the given index in this RunPipeCollection. + + + Adds an instance of type RunPipe to the end of this RunPipeCollection. + The RunPipe to be added to the end of this RunPipeCollection. + + + Determines whether a specfic RunPipe value is in this RunPipeCollection. + The RunPipe value to locate in this RunPipeCollection. + true if value is found in this RunPipeCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RunPipeCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific RunPipe from this RunPipeCollection. + The RunPipe value to remove from this RunPipeCollection. + + + Type-specific enumeration class, used by RunPipeCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type IRunPipeListener This class cannot be inherited. + + + Adds an instance of type IRunPipeListener to the end of this RunPipeListenerCollection. + The IRunPipeListener to be added to the end of this RunPipeListenerCollection. + + + Determines whether a specfic IRunPipeListener value is in this RunPipeListenerCollection. + The IRunPipeListener value to locate in this RunPipeListenerCollection. + true if value is found in this RunPipeListenerCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RunPipeListenerCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific IRunPipeListener from this RunPipeListenerCollection. + The IRunPipeListener value to remove from this RunPipeListenerCollection. + + + Type-specific enumeration class, used by RunPipeListenerCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type RunPipeStarter This class cannot be inherited. + + + Adds an instance of type RunPipeStarter to the end of this RunPipeStarterCollection. + The RunPipeStarter to be added to the end of this RunPipeStarterCollection. + + + Determines whether a specfic RunPipeStarter value is in this RunPipeStarterCollection. + The RunPipeStarter value to locate in this RunPipeStarterCollection. + true if value is found in this RunPipeStarterCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RunPipeStarterCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific RunPipeStarter from this RunPipeStarterCollection. + The RunPipeStarter value to remove from this RunPipeStarterCollection. + + + Type-specific enumeration class, used by RunPipeStarterCollection.GetEnumerator. This class cannot be inherited. + + + A dictionary with keys of type IRun and values of type RunVertex This class cannot be inherited. + + + Gets or sets the RunVertex associated with the given IRun + The IRun whose value to get or set. + + + Gets a collection containing the keys in this RunVertexDictionary. + + + Gets a collection containing the values in this RunVertexDictionary. + + + Adds an element with the specified key and value to this RunVertexDictionary. + The IRun key of the element to add. + The RunVertex value of the element to add. + + + Determines whether this RunVertexDictionary contains a specific key. + The IRun key to locate in this RunVertexDictionary. + true if this RunVertexDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this RunVertexDictionary contains a specific value. + The RunVertex value to locate in this RunVertexDictionary. + true if this RunVertexDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this RunVertexDictionary. + The IRun key of the element to remove. + + + A collection of elements of type Thread This class cannot be inherited. + + + Gets or sets the Thread at the given index in this ThreadCollection. + + + Adds an instance of type Thread to the end of this ThreadCollection. + The Thread to be added to the end of this ThreadCollection. + + + Determines whether a specfic Thread value is in this ThreadCollection. + The Thread value to locate in this ThreadCollection. + true if value is found in this ThreadCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this ThreadCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific Thread from this ThreadCollection. + The Thread value to remove from this ThreadCollection. + + + Type-specific enumeration class, used by ThreadCollection.GetEnumerator. This class cannot be inherited. + + + A collection of elements of type Type This class cannot be inherited. + + + Gets or sets the Type at the given index in this TypeCollection. + + + Adds an instance of type Type to the end of this TypeCollection. + The Type to be added to the end of this TypeCollection. + + + Determines whether a specfic Type value is in this TypeCollection. + The Type value to locate in this TypeCollection. + true if value is found in this TypeCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this TypeCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific Type from this TypeCollection. + The Type value to remove from this TypeCollection. + + + Type-specific enumeration class, used by TypeCollection.GetEnumerator. This class cannot be inherited. + + + Allows control of command line parsing. Attach this attribute to instance fields of types used as the destination of command line argument parsing. + + + Returns true if the argument did not have an explicit long name specified. + + + Returns true if the argument did not have an explicit short name specified. + + + The long name of the argument. + + + The short name of the argument. + + + The error checking to be done on the argument. + + + Parser for command line arguments. + + + A user friendly usage string describing the command line argument syntax. + + + Parses an argument list. + The arguments to parse. + The destination of the parsed arguments. + true if no parse errors were encountered. + + + Useful Stuff. This is a and so cannot be inherited or instantiated. + + + The System Defined new line string. This field is constant and read-only. + + + Returns a Usage string for command line argument parsing. Use CommandLineArgumentAttributes to control parsing behaviour. + The type of the arguments to display usage for. + Printable string containing a user friendly description of command line arguments. + + + Parses Command Line Arguments. Errors are output on Console.Error. Use CommandLineArgumentAttributes to control parsing behaviour. + The actual arguments. + The resulting parsed arguments. + + + Parses Command Line Arguments. Use CommandLineArgumentAttributes to control parsing behaviour. + The actual arguments. + The resulting parsed arguments. + The destination for parse errors. + + + Indicates that this argument is the default argument. '/' or '-' prefix only the argument value is specified. + + + Used to control parsing of command line arguments. + + + Indicates that this field is required. An error will be displayed if it is not present when parsing arguments. + + + Only valid in conjunction with Multiple. Duplicate values will result in an error. + + + Inidicates that the argument may be specified more than once. Only valid if the argument is a collection + + + The default type for non-collection arguments. The argument is not required, but an error will be reported if it is specified more than once. + + + For non-collection arguments, when the argument is specified more than once no error is reported and the value of the argument is the last value which occurs in the argument list. + + + The default type for collection arguments. The argument is permitted to occur multiple times, but duplicate values will cause an error to be reported. + + + A delegate used in error reporting. + + + Base class for MbUnit exceptions + + + Exception thrown when not finding a vertex. + + + The exception message + + + Exception thrown when a specified resource cannot be found. + + + Exception throwed when not finding a vertex. + + + Filter class for FixtureCategory attribute. This class cannot be inherited. + + + Tests if a fixture has a category attribute matching a pattern. + The fixture to test. + true if the fixture has a matching category attribute, otherwise false. + + + This is the base class for attributes that can decorate tests. This class is and so cannot be instantiated. + + + This is the base class for attributes that can decorate fixtures. This class is and so cannot be instantiated. + + + Base class for attributes that tag method that are usualy used to set up, provide data, tear down tests, etc... + + + Base class for all attributes that are part of the MbUnit framework. + + + Base class for attributes that define test fixtures. This class is and so cannot be instantiated. + + + Gets or sets the fixture timeout in minutes. + Time out minutes. + + + Base class for attributes that define unit test. + + + Decorator invorkers are used to modify the way a fixute method is executed. Popular examples of such is the or the . This class is and so cannot be instantiated. + + + Invoker for tests decorated with the ExplicitAttribute. + + + Execute method for the invoker. + + + + + TODO - Add class summary + + + An invoker that wraps up the call to a fixture method. + + + A implementation, containing a . + + + Gets a value indicating if the vertex has a instance attached to it. + true if the vertex has a instance attached. + + + Gets the attached to the vertex. + The instance attached to the vertex + the is a null reference + + + Not implemented. + always thrown + + + Converts the object to string + String representation of the vertex + + + Serializes informations to the instance. + serialization device + info is a null reference + + + Internal use This class cannot be inherited. + + + This interface defines a method invoker object. + + + Gets a reference to the instance that generated the invoker. + Reference to the instance that generated the invoker. + + + Gets a descriptive name of the + A descriptive name of the . + + + Gets a value indicating if the instance is related to + A instance + true if the instance is related to the member info; otherwize false + + + Executes the wrapped method + Test fixture instance + Method arguments + Return value of the invoked method. If the method returns void, null is returned. + + + Describes the status of the memory. This class cannot be inherited. + + + A high performance timer This class cannot be inherited. + + + Gets the timed duration value in seconds + Timer duration + + + Gets the current duration value without stopping the timer + Current duration value + + + Starts the timer + + + Stops the timer + + + AssemblyWatcher keeps track of one or more assemblies to see if they have changed. It incorporates a delayed notification and uses a standard event to notify any interested parties about the change. The path to the assembly is provided as an argument to the event handler so that one routine can be used to handle events from multiple watchers. + + + Helper method to delete the cache dir. This method deals with a bug that occurs when pdb files are marked read-only. + + + + Merge a 'dependentAssembly' directive into a given config document. If any entries exist for the same assembly they will be deleted before the new entry is merged. + The config document to merge + The Assembly that should be used + The range of compatable versions (eg. "1.0.0.0-3.0.0.0") + The codebase to use. + + + A dictionary with keys of type Guid and values of type TestTreeNode + + + Gets or sets the TestTreeNode associated with the given Guid + The Guid whose value to get or set. + + + Gets a collection containing the keys in this GuidTestTreeNodeDictionary. + + + Gets a collection containing the values in this GuidTestTreeNodeDictionary. + + + Adds an element with the specified key and value to this GuidTestTreeNodeDictionary. + The TestTreeNode value of the element to add. + + + Determines whether this GuidTestTreeNodeDictionary contains a specific key. + The Guid key to locate in this GuidTestTreeNodeDictionary. + true if this GuidTestTreeNodeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this GuidTestTreeNodeDictionary contains a specific key. + The Guid key to locate in this GuidTestTreeNodeDictionary. + true if this GuidTestTreeNodeDictionary contains an element with the specified key; otherwise, false. + + + Removes the element with the specified key from this GuidTestTreeNodeDictionary. + The Guid key of the element to remove. + + + A dictionary with keys of type Guid and values of type TreeNode + + + Gets or sets the TreeNode associated with the given Guid + The Guid whose value to get or set. + + + Gets a collection containing the keys in this GuidTreeNodeDictionary. + + + Gets a collection containing the values in this GuidTreeNodeDictionary. + + + Adds an element with the specified key and value to this GuidTreeNodeDictionary. + The TreeNode value of the element to add. + + + Determines whether this GuidTreeNodeDictionary contains a specific key. + The Guid key to locate in this GuidTreeNodeDictionary. + true if this GuidTreeNodeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this GuidTreeNodeDictionary contains a specific key. + The Guid key to locate in this GuidTreeNodeDictionary. + true if this GuidTreeNodeDictionary contains an element with the specified key; otherwise, false. + + + Removes the element with the specified key from this GuidTreeNodeDictionary. + The Guid key of the element to remove. + + + Long living object. (Extracted from NUnit source) + + + Clears the internal representation of the tree + + + Populates the node using the instance contained in . + + + Supports verbose output option of console app. Added as part of fix to issue MBUNIT-28. + + + Gets or sets a value indicating the assemblies have to be shadow copied + + + Set the location for caching and delete any old cache info + Our domain + + + Creates an AppDomain for the Test Assembly + + + + + + + A dictionary with keys of type String and values of type TestTreeNode + + + Gets or sets the TestTreeNode associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringTestTreeNodeDictionary. + + + Gets a collection containing the values in this StringTestTreeNodeDictionary. + + + Adds an element with the specified key and value to this StringTestTreeNodeDictionary. + The String key of the element to add. + The TestTreeNode value of the element to add. + + + Determines whether this StringTestTreeNodeDictionary contains a specific key. + The String key to locate in this StringTestTreeNodeDictionary. + true if this StringTestTreeNodeDictionary contains an element with the specified key; otherwise, false. + + + Removes the element with the specified key from this StringTestTreeNodeDictionary. + The String key of the element to remove. + + + Gets the testFilePath + + + Gets a identifying the + + + Loads domain and test assembly + + + Raises the event. + + + Raises the event. + + + Raises the event. + + + Unload and reload test domain + + + Unload domain + + + A collection of elements of type TestTreeNode + + + Adds an instance of type TestTreeNode to the end of this TestTreeNodeCollection. + The TestTreeNode to be added to the end of this TestTreeNodeCollection. + + + Determines whether a specfic TestTreeNode value is in this TestTreeNodeCollection. + The TestTreeNode value to locate in this TestTreeNodeCollection. + true if value is found in this TestTreeNodeCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this TestTreeNodeCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific TestTreeNode from this TestTreeNodeCollection. + The TestTreeNode value to remove from this TestTreeNodeCollection. + + + Type-specific enumeration class, used by TestTreeNodeCollection.GetEnumerator. + + + Defines a class that can populate a tree of tests This class is and so cannot be instantiated. + + + Clears the internal representation of the tree + + + Populates the node using the instance contained in . + Node dictionary. + The root node. + Collection of s + + or is a null reference (Nothing in Visual Basic) + + + A collection of elements of type TestTreePopulator + + + Adds an instance of type TestTreePopulator to the end of this TestTreePopulatorCollection. + The TestTreePopulator to be added to the end of this TestTreePopulatorCollection. + + + Adds the elements of an array to the end of this TestTreePopulatorCollection. + The array whose elements are to be added to the end of this TestTreePopulatorCollection. + + + Adds the elements of another TestTreePopulatorCollection to the end of this TestTreePopulatorCollection. + The TestTreePopulatorCollection whose elements are to be added to the end of this TestTreePopulatorCollection. + + + Determines whether a specfic TestTreePopulator value is in this TestTreePopulatorCollection. + The TestTreePopulator value to locate in this TestTreePopulatorCollection. + true if value is found in this TestTreePopulatorCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this TestTreePopulatorCollection. + An object that implements System.Collections.IEnumerator. + + + Removes the first occurrence of a specific TestTreePopulator from this TestTreePopulatorCollection. + The TestTreePopulator value to remove from this TestTreePopulatorCollection. + + + Type-specific enumeration class, used by TestTreePopulatorCollection.GetEnumerator. + + + Gets the assembly watcher + + + Defines a class that can populate a tree of tests + + + Clears the internal representation of the tree + + + Populates the node using the instance contained in . + A node dictionary. + The root node. + A collection of pipes. + + or is a null reference (Nothing in Visual Basic) + + + Render the report result to the specified writer + Result from the test + Writer to write result output to + + + Render the report result to a file + Result from the test + Report output file name + + + Render the report result to a file + Result from the test + Output directory + Default format name + Extension of the file + File name of the report + + + Render the report result to a file + Result from the test + Output directory + Default format name. If null, the default name will be used + File name of the report + + + Reports MbUnit result in text format. This class cannot be inherited. + + + XML Report. This class cannot be inherited. + + + TODO - Add class summary + + + Gets a value indicating the run is considered as a test or not. + true if the instance is a test + + + Gets a descriptive name of the + A descriptive name of the + + + Populates the invoker graph with generated by the run. + Invoker tree + parent vertex + class type that is marked by the run + + + TODO - Add class summary This class cannot be inherited. + + + Gets a value indicating the run is considered as a test or not. + true if the instance is a test + + + Gets a descriptive name of the + A descriptive name of the + + + Populates the invoker graph with generated by the run. + Invoker tree + parent vertex + class type that is marked by the run + + + A sequence of IRuns This class cannot be inherited. + + + Populates the invoker graph with generated by the run. + Invoker tree. + Parent vertex. + The to search for. + + + Test fixture run with support for decoration by . This class cannot be inherited. + + + Builds the test run invoker tree. + + + + + + This interface defines a type of test/non test run that is used to define the logic. + + + Gets a value indicating the run is considered as a test or not. + true if the instance is a test + + + Gets a descriptive name of the + A descriptive name of the + + + Populates the invoker graph with generated by the run. + Invoker tree + parent vertex + class type that is marked by the run + + + Array Assertion class This is a and so cannot be inherited or instantiated. + + + Verifies that both array have the same dimension and elements. + + + + + Class containing generic assert methods for the comparison of values and object references, the existence of objects within a collection type and basic object properties - for example, whether or not it is assignable to. Also contains a set of Fail asserts which will automatically fail a test straight away. This is a and so cannot be inherited or instantiated. + + + Number of Asserts made so far this test run + + + Verifies that two doubles, and , are equal given a . If the expected value is infinity then the delta value is ignored. If they are not equal then a is thrown with the given . + The expected value + The actual value + The maximum acceptable difference between and + The message printed out upon failure + Thrown if has been given a negative value. + Thrown if and are not values within the given . + + + Verifies that two doubles, and , are equal considering a . If the expected value is infinity then the delta value is ignored. If they are not equals then an is thrown with no explanation for the failure. Use if you want to provide an explanation. + The expected value + The actual value + The maximum acceptable difference between and + Thrown if has been given a negative value. + Thrown if and are not values within the given . + + + Verifies that two doubles, and , are equal considering a . If the expected value is infinity then the delta value is ignored. If they are not equal then a is thrown with a message defined via and through . + The expected value + The actual value + The maximum acceptable difference between and + A composite format string + An array containing zero or more objects to format. + Thrown if has been given a negative value. + Thrown if and are not values within the given . Exception message is generated through and . + + + Verifies that two floats, and , are equal considering a . If the value is infinity then the value is ignored. If they are not equal then an is thrown with the given . + The expected value + The actual value + The maximum acceptable difference between and + The message printed out upon failure + Thrown if has been given a negative value. + Thrown if and are not values within the given . + + + Verifies that two floats, and , are equal considering a . If the value is infinity then the value is ignored. If they are not equals then an is thrown with a message defined via and through . + The expected value + The actual value + The maximum acceptable difference between and + A composite format string + An array containing zero or more objects to format. + Thrown if has been given a negative value. + Thrown if and are not values within the given . Exception message is generated through and . + + + Verifies that two floats, and , are equal considering a . If the value is infinity then the value is ignored. If they are not equals then an is thrown. + The expected value + The actual value + The maximum acceptable difference between and + Thrown if has been given a negative value. + Thrown if and are not values within the given . + + + Verifies that two decimals, and , are equal. If they are not equal then an is thrown with the given . + The expected value + The actual value + The message printed out upon failure + + and are not equal. + + + Verifies that two decimals, and , are equal. If they are not equal then a is thrown with a message defined via and through . + The expected value + The actual value + A composite format string + An array containing zero or more objects to format. + Thrown if and are not equal. + + + Verifies that two decimals, and , are equal. If they are not equal then a is thrown. + The expected value + The actual value + Thrown if and are not equal. + + + Verifies that two integers, and , are equal. If they are not equal then a is thrown with the given . + The expected value + The actual value + The message printed out upon failure + Thrown if and are not equal. + + + Verifies that two integers, and , are equal. If they are not equal then an is thrown with a message defined via and through . + The expected value + The actual value + A composite format string + An array containing zero or more objects to format. + Thrown if and are not equal. + + + Verifies that two integers, and , are equal. If they are not equal then a is thrown. + The expected value + The actual value + Thrown if and are not equal. + + + Verifies that two objects, and , are equal. If they are not equal then a is thrown with a message defined via and through . + The expected value + The actual value + A composite format string + An array containing zero or more objects to format. + Thrown if and are not equal. + + + Verifies that two objects, and , are equal. If they are not equal then an is thrown with a given . + The expected value + The actual value + The message printed out upon failure + Thrown if and are not equal. + + + Verifies that two objects, and , are equal. If they are not equal then an is thrown. + The expected value + The actual value + + and are not equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with a message defined via and through . + The to compare + The being compared + A composite format string + An array containing zero or more objects to format. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with the given + The to compare + The being compared + The message to include if the test fails + Thrown if and are equal. + Thrown if and are both null + + + Verifies that two s, and , are not equal. If the s are equal an is thrown. + The to compare + The being compared + Thrown if and are equal. + Thrown if and are both null + + + Verifies that two integers, and , are not equal. If the integers are equal an is thrown with a message defined via and through . + The integer to compare + The integer being compared + A composite format string + An array containing zero or more objects to format. + Thrown if and are equal. + + + Verifies that two integers, and , are not equal. If the integers are equal an is thrown with a given . + The integer to compare + The integer being compared + The message to include if the test fails + Thrown if and are equal. + + + Verifies that two integers, and , are not equal. If the integers are equal an is thrown + The integer to compare + The integer being compared + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with a message defined via and through . + The to compare + The being compared + A composite format string + An array containing zero or more objects to format. + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with the given + The to compare + The being compared + The message to include if the test fails + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown. + The to compare + The being compared + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with a message defined via and through . + The to compare + The being compared + A composite format string + An array containing zero or more objects to format. + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with the given + The to compare + The being compared + The message to include if the test fails + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown + The to compare + The being compared + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with a message defined via and through . + The to compare + The being compared + A composite format string + An array containing zero or more objects to format. + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with the given + The to compare + The being compared + The message to include if the test fails + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown + The to compare + The being compared + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with a message defined via and through . + The to compare + The being compared + A composite format string + An array containing zero or more objects to format. + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown with the given + The to compare + The being compared + The message to include if the test fails + Thrown if and are equal. + + + Verifies that two s, and , are not equal. If the s are equal an is thrown + The to compare + The being compared + Thrown if and are equal. + + + Asserts that two objects refer to the same object. If they are not the same an is thrown. + The message to be printed when the two objects are not the same object. + The expected object + The actual object + + + Asserts that two objects refer to the same object. If they are not the same an is thrown. + The expected object + The actual object + The format of the message to display if the assertion fails, containing zero or more format items. + An array containing zero or more objects to format. + + + Asserts that two objects refer to the same object. If they are not the same an is thrown. + The expected object + The actual object + + + Verifies that given two objects, and , the property described by the object is present in both objects, is not null, and that the value of the property in both objects is equal. + The object indicating the property to be tested + The object containing the expected value of the property + The object containing the actual value of the property + The index of the value in the property if it is an indexed property + One or both of and are null + The property that describes is not present in either or + The property values in and are not equal + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + Asserts that is between and . + + + The Equals method throws an . This is done to make sure there is no mistake by calling this function. Use AreEqual instead or one of its overloads. + The first to compare + The second to compare + True if the values are equal, false otherwise + Always thrown as this method should not be used. + + + Throws an with the message that is passed in. This is used by the other Assert functions. + The format of the message to initialize the with. + An array containing zero or more objects to format. + + + Throws an with the message that is passed in. This is used by the other Assert functions. + The message to initialize the with. + + + Throws an with the message that is passed in. This is used by the other Assert functions. + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + The message that will be displayed on failure + + + Verifies that the first value is greater than the second value. If they are not, then an is thrown. + The first value, expected to be greater + The second value, expected to be less + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Verifies that is strictly greater than . + + + Makes the current test ignored using like formatting + + + + + Makes the current test ignored using like formatting + + + + Asserts that is in the dic . + + + Asserts that is in the dic . + + + Asserts that is in the list . + + + Asserts that is in the list . + + + Asserts that is in the enumerable collection . + + + Asserts that is in the enumerable collection . + + + Increments by 1 + + + Asserts that an object may be assigned a value of a given Type. + The expected Type. + The object under examination + + + Asserts that an object may be assigned a value of a given Type. + The expected Type. + The object under examination + The messge to display in case of failure + + + Asserts that an object may be assigned a value of a given Type. + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + Assert that a string is empty - that is equal to string.Empty + The string to be tested + The message to be displayed on failure + Arguments to be used in formatting the message + + + Assert that a string is empty - that is equal to string.Emtpy + The string to be tested + The message to be displayed on failure + + + Assert that a string is empty - that is equal to string.Emtpy + The string to be tested + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + Arguments to be used in formatting the message + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + + + Assert that an array,list or other collection is empty + An array, list or other collection implementing ICollection + + + Asserts that a is false. If true, the method throws an with a message defined via and through . + The evaluated condition + A composite format string + An array containing zero or more objects to format. + Thrown when is not false. + + + Asserts that a is false. If true, the method throws an with the given . + The evaluated condition + The message printed out upon failure + Thrown when is not false. + + + Asserts that a is false. If true, the method throws an with no explanatory message. + The evaluated condition + Thrown when is not false. + + + Asserts that an object is an instance of a given type. + The expected Type + The object being examined + + + Asserts that an object is an instance of a given type. + The expected Type + The object being examined + A message to display in case of failure + + + Asserts that an object is an instance of a given type. + The expected Type + The object being examined + A message to display in case of failure + An array of objects to be used in formatting the message + + + Verifies that the double is passed is an NaN value. If the object is not NaN then an is thrown. + The value that is to be tested + The message to be displayed when the object is not null + Arguments to be used in formatting the message + + + Verifies that the double is passed is an NaN value. If the object is not NaN then an is thrown. + The object that is to be tested + The message to be displayed when the object is not null + + + Verifies that the double is passed is an NaN value. If the object is not NaN then an is thrown. + The object that is to be tested + + + Asserts that an object may not be assigned a value of a given Type. + The expected Type. + The object under examination + + + Asserts that an object may not be assigned a value of a given Type. + The expected Type. + The object under examination + The messge to display in case of failure + + + Asserts that an object may not be assigned a value of a given Type. + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + Assert that a string is empty - that is equal to string.Emtpy + The string to be tested + The message to be displayed on failure + Arguments to be used in formatting the message + + + Assert that a string is empty - that is equal to string.Emtpy + The string to be tested + The message to be displayed on failure + + + Assert that a string is empty - that is equal to string.Emtpy + The string to be tested + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + Arguments to be used in formatting the message + + + Assert that an array, list or other collection is empty + An array, list or other collection implementing ICollection + The message to be displayed on failure + + + Assert that an array,list or other collection is empty + An array, list or other collection implementing ICollection + + + Asserts that an object is not an instance of a given type. + The expected Type + The object being examined + A message to display in case of failure + An array of objects to be used in formatting the message + + + Asserts that an object is not an instance of a given type. + The expected Type + The object being examined + + + Asserts that an object is not an instance of a given type. + The expected Type + The object being examined + A message to display in case of failure + + + Verifies that the given is not null. If it is null, an is thrown with a message defined via and through + The to test + A composite format string + An array containing zero or more objects to format. + Thrown if is null + + + Verifies that the given is not null. If it is null, an is thrown with the given + The to test + The message to include if the test fails + Thrown if is null + + + Verifies that the given is not null. If it is null, an is thrown + The to test + Thrown if is null + + + Verifies that the given is null. If it is not null, an is thrown with a message defined via and through + The to test + A composite format string + An array containing zero or more objects to format. + Thrown if is not null + + + Verifies that the given is null. If it is not null, an is thrown with the given + The to test + The message to include if the test fails + Thrown if is not null + + + Verifies that the given is null. If it is not null, an is thrown + The to test + Thrown if is not null + + + Asserts that a is true. If false, the method throws an with a message defined via and through String.Format. + The evaluated condition + A composite format string + An array containing zero or more objects to format. + Thrown when is not true. + + + Asserts that a is true. If false, the method throws an with the given . + The evaluated condition + The message printed out upon failure + Thrown when is not true. + + + Asserts that a is true. If false, the method throws an with no explanatory message. + The evaluated condition + Thrown if is not true. + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + The message that will be displayed on failure + + + Verifies that the first value is less than the second value. If it is not, then an is thrown. + The first value, expected to be less + The second value, expected to be greater + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is lower equal than . + + + Verifies that is lower equal than . + + + Verifies that is lower equal than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Verifies that is strictly lower than . + + + Asserts that is not between and . + + + Asserts that is not between and . + + + Asserts that is not between and . + + + Asserts that is not between and . + + + Asserts that is not between and . + + + Asserts that is not between and . + + + Asserts that is not between and . + + + Asserts that is not in the dic . + + + Asserts that is not in the dic . + + + Asserts that is not in the list . + + + Asserts that is not in the list . + + + Asserts that is not in the enumerable collection . + + + Asserts that is not in the enumerable collection . + + + Overrides the default method inherited from to throw an instead. This is to ensure that there is no mistake in calling this function as part of an Assert in your tests. Use AreSame() instead or one of its overloads. + The first to compare + The second to compare + Always thrown as this method should not be used. + + + Resets to 0 + + + This attribute identifies the author of a test fixture. + + + Assertion helper for the class. This is a and so cannot be inherited or instantiated. + + + Asserts that all items contained in collection are of the type specified by expectedType. + ICollection of objects to be considered + System.Type that all objects in collection must be instances of + + + Asserts that all items contained in collection are of the type specified by expectedType. + ICollection of objects to be considered + System.Type that all objects in collection must be instances of + The message that will be displayed on failure + + + Asserts that all items contained in collection are of the type specified by expectedType. + ICollection of objects to be considered + System.Type that all objects in collection must be instances of + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Asserts that all items contained in collection are not equal to null. + ICollection of objects to be considered + + + Asserts that all items contained in collection are not equal to null. + ICollection of objects to be considered + The message that will be displayed on failure + + + Asserts that all items contained in collection are not equal to null. + ICollection of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Ensures that every object contained in collection exists within the collection once and only once. + ICollection of objects to be considered + + + Ensures that every object contained in collection exists within the collection once and only once. + ICollection of objects to be considered + The message that will be displayed on failure + + + Ensures that every object contained in collection exists within the collection once and only once. + ICollection of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that and are equal collections. Element count and element wize equality is verified. + Expected value. + Instance containing the tested value. + + + Verifies that and are equal collections. Element count and element wize equality is verified. + Expected value. + Instance containing the tested value. + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The message that will be displayed on failure + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Asserts that expected and actual are not exactly equal. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + + + Asserts that expected and actual are not exactly equal. If comparer is not null then it will be used to compare the objects. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The IComparer to use in comparing objects from each ICollection + + + Asserts that expected and actual are not exactly equal. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The message that will be displayed on failure + + + Asserts that expected and actual are not exactly equal. If comparer is not null then it will be used to compare the objects. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The IComparer to use in comparing objects from each ICollection + The message that will be displayed on failure + + + Asserts that expected and actual are not exactly equal. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Asserts that expected and actual are not exactly equal. If comparer is not null then it will be used to compare the objects. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The IComparer to use in comparing objects from each ICollection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Asserts that expected and actual are not equivalent. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + + + Asserts that expected and actual are not equivalent. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The message that will be displayed on failure + + + Asserts that expected and actual are not equivalent. + The first ICollection of objects to be considered + The second ICollection of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Asserts that collection contains actual as an item. + ICollection of objects to be considered + Object to be found within collection + + + Asserts that collection contains actual as an item. + ICollection of objects to be considered + Object to be found within collection + The message that will be displayed on failure + + + Asserts that collection contains actual as an item. + ICollection of objects to be considered + Object to be found within collection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Asserts that collection does not contain actual as an item. + ICollection of objects to be considered + Object that cannot exist within collection + + + Asserts that collection does not contain actual as an item. + ICollection of objects to be considered + Object that cannot exist within collection + The message that will be displayed on failure + + + Asserts that collection does not contain actual as an item. + ICollection of objects to be considered + Object that cannot exist within collection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the property is synchronized with the number of iterated elements. + Collection to test + + is a null reference (Nothing in Visual Basic) + + + Asserts that subset is not a subset of superset. + The ICollection subset to be considered + The ICollection superset to be considered + + + Asserts that subset is not a subset of superset. + The ICollection subset to be considered + The ICollection superset to be considered + The message that will be displayed on failure + + + Asserts that subset is not a subset of superset. + The ICollection subset to be considered + The ICollection superset to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the property value is false. + Instance containing the expected value. + + + Asserts that subset is a subset of superset. + The ICollection subset to be considered + The ICollection superset to be considered + + + Asserts that subset is a subset of superset. + The ICollection subset to be considered + The ICollection superset to be considered + The message that will be displayed on failure + + + Asserts that subset is a subset of superset. + The ICollection subset to be considered + The ICollection superset to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + Verifies that the property value is true. + Instance containing the expected value. + + + Collection indexing pattern. This class cannot be inherited. + + + Creates the execution logic + A instance that represent the type test logic. + + + Collection Order Pattern implementations. This class cannot be inherited. + + + Tag use to mark a mark a unit test method. This class cannot be inherited. + + + Assertion helper for compilation. This is a and so cannot be inherited or instantiated. + + + Gets the C# compiler from . + C# compiler. + + + Gets the VB.NET compiler from . + VB.NET compiler. + + + Verifies that compiles using the provided compiler. + Compiler instance + Source code to compile + + + Verifies that compiles using the provided compiler. + Compiler instance + Source code to compile + + + Verifies that compiles using the provided compiler. + Compiler instance + Referenced assemblies + Source code to compile + + + Verifies that compiles using the provided compiler. + + instance. + Compilation options + source to compile + + + Verifies that compiles using the provided compiler. + + instance. + Compilation options + Source to compile + true if assertion should throw if any warning. + + + Verifies that compiles using the provided compiler. + + instance. + Compilation options + Stream containing the source to compile + + + Verifies that compiles using the provided compiler. + + instance. + Compilation options + Stream containing the source to compile + true if assertion should throw if any warning. + + + Verifies that does not compile using the provided compiler. + + instance. + Source to compile + + + Verifies that does not compile using the provided compiler. + + instance. + Source to compile + + + Verifies that does not compile using the provided compiler. + + instance. + Collection of referenced assemblies + Source to compile + + + Verifies that does not compile using the provided compiler. + + instance. + Compilation options + Source to compile + + + Verifies that does not compile using the provided compiler. + + instance. + Compilation options + Source to compile + + + Composite fixture pattern implementation. This class cannot be inherited. + + + Gets or sets the fixture type. + Fixture instance type. + + + Creates the execution logic + A instance that represent the type test logic. + + + Tags method that should throw an exception if a predicate is true. + + + Assertion helper for the class. This is a and so cannot be inherited or instantiated. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value of and are equal. + Instance containing the expected value. + Instance containing the tested value. + + + Verifies that the property value of is equal to . + Expected value. + Instance containing the tested value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is false. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Verifies that the property value is true. + Instance containing the expected value. + + + Tags method that provider a new object and copy the content of the arguments into the object + + + Assertion class for Database related object. This is a and so cannot be inherited or instantiated. + + + Assert that data are equal. + + + Asserts that two are equal. + Expected instance. + Actual instance. + + + Asserts that two are equal. + Expected instance. + Actual instance. + + + Assert that schemas and data are equal. + + + Assert that schemas are equal. + + + Data Test fixture. This class cannot be inherited. + + + Creates the execution logic + A instance that represent the type test logic. + + + Tags method that provide data for the tests. + + + Tag method that should return in a given time interval. + + + Enumeration Pattern implementations. This class cannot be inherited. + + + Tags method that should throw an exception. + + + The expected exception. + + + The expected message text. + + + The expected inner exception. + + + Tags test methods that are only to be run when explicitly selected. This class cannot be inherited. + + + Test methods annotated with this attribute will have the specified embedded resource extracted. + + + The destination file to write the resource to. Should be a path. + + + Whether or not to cleanup the resource. + + + The full name of the resource. Use Reflector to find this out if you don't know. + + + The current resource stream if using the attribute without specifying a destination. + + + The type within the assembly that contains the embedded resource. + + + Tags method that fill collections with data. + + + Tags test methods that are ignored. This class cannot be inherited. + + + This attribute collects the test importance information. + + + Tag method that provider a collection, an inde + + + Tag method that gives a list of culture that the test should run on. + + + Tags method that should throw an exception. + + + Performance Assertion class This is a and so cannot be inherited or instantiated. + + + Creates a countdown timer that will assert if execution time exceeds maximum duration. + + + .Net CLR Data This is a and so cannot be inherited or instantiated. + + + Current number of pools associated with the process. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + Current number of connections, pooled or not. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + Current number of connections in all pools associated with the process. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The highest number of connections in all pools since the process started. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The total number of command executes that have failed for any reason. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The total number of connection open attempts that have failed for any reason. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + Runtime statistics on CLR exception handling. This is a and so cannot be inherited or instantiated. + + + This counter displays the total number of exceptions thrown since the start of the application. These include both .NET exceptions and unmanaged exceptions that get converted into .NET exceptions e.g. null pointer reference exception in unmanaged code would get re-thrown in managed code as a .NET System.NullReferenceException; this counter includes both handled and unhandled exceptions. Exceptions that are re-thrown would get counted again. Exceptions should only occur in rare situations and not in the normal control flow of the program. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of exceptions thrown per second. These include both .NET exceptions and unmanaged exceptions that get converted into .NET exceptions e.g. null pointer reference exception in unmanaged code would get re-thrown in managed code as a .NET System.NullReferenceException; this counter includes both handled and unhandled exceptions. Exceptions should only occur in rare situations and not in the normal control flow of the program; this counter was designed as an indicator of potential performance problems due to large (>100s) rate of exceptions thrown. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of .NET exception filters executed per second. An exception filter evaluates whether an exception should be handled or not. This counter tracks the rate of exception filters evaluated; irrespective of whether the exception was handled or not. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of finally blocks executed per second. A finally block is guaranteed to be executed regardless of how the try block was exited. Only the finally blocks that are executed for an exception are counted; finally blocks on normal code paths are not counted by this counter. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of stack frames traversed from the frame that threw the .NET exception to the frame that handled the exception per second. This counter resets to 0 when an exception handler is entered; so nested exceptions would show the handler to handler stack depth. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Stats for CLR interop. This is a and so cannot be inherited or instantiated. + + + This counter displays the current number of Com-Callable-Wrappers (CCWs). A CCW is a proxy for the .NET managed object being referenced from unmanaged COM client(s). This counter was designed to indicate the number of managed objects being referenced by unmanaged COM code. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of times arguments and return values have been marshaled from managed to unmanaged code and vice versa since the start of the application. This counter is not incremented if the stubs are inlined. (Stubs are responsible for marshalling arguments and return values). Stubs usually get inlined if the marshalling overhead is small. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of stubs created by the CLR. Stubs are responsible for marshalling arguments and return values from managed to unmanaged code and vice versa; during a COM Interop call or PInvoke call. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Reserved for future use. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Reserved for future use. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Stats for CLR Jit. This is a and so cannot be inherited or instantiated. + + + This counter displays the rate at which IL bytes are jitted per second. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total IL bytes jitted since the start of the application. This counter is exactly equivalent to the "Total # of IL Bytes Jitted" counter. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of methods compiled Just-In-Time (JIT) by the CLR JIT compiler since the start of the application. This counter does not include the pre-jitted methods. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Not Displayed. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the peak number of methods the JIT compiler has failed to JIT since the start of the application. This failure can occur if the IL cannot be verified or if there was an internal error in the JIT compiler. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the percentage of elapsed time spent in JIT compilation since the last JIT compilation phase. This counter is updated at the end of every JIT compilation phase. A JIT compilation phase is the phase when a method and its dependencies are being compiled. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total IL bytes jitted since the start of the application. This counter is exactly equivalent to the "# of IL Bytes Jitted" counter. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Statistics for CLR Class Loader. This is a and so cannot be inherited or instantiated. + + + Reserved for future use. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current size (in bytes) of the memory committed by the class loader across all AppDomains. (Committed memory is the physical memory for which space has been reserved on the disk paging file.) This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of AppDomains loaded in this application. AppDomains (application domains) provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications running in the same process. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of Assemblies loaded across all AppDomains in this application. If the Assembly is loaded as domain-neutral from multiple AppDomains then this counter is incremented once only. Assemblies can be loaded as domain-neutral when their code can be shared by all AppDomains or they can be loaded as domain-specific when their code is private to the AppDomain. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of classes loaded in all Assemblies. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of AppDomains loaded per second. AppDomains (application domains) provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications running in the same process. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of AppDomains unloaded per second. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of Assemblies loaded across all AppDomains per second. If the Assembly is loaded as domain-neutral from multiple AppDomains then this counter is incremented once only. Assemblies can be loaded as domain-neutral when their code can be shared by all AppDomains or they can be loaded as domain-specific when their code is private to the AppDomain. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of classes loaded per second in all Assemblies. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of classes that failed to load per second. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. These load failures could be due to many reasons like inadequate security or illegal format. Full details can be found in the profiling services help. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Reserved for future use. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the peak number of AppDomains loaded since the start of this application. AppDomains (application domains) provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications running in the same process. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of AppDomains unloaded since the start of the application. If an AppDomain is loaded and unloaded multiple times this counter would count each of those unloads as separate. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of Assemblies loaded since the start of this application. If the Assembly is loaded as domain-neutral from multiple AppDomains then this counter is incremented once only. Assemblies can be loaded as domain-neutral when their code can be shared by all AppDomains or they can be loaded as domain-specific when their code is private to the AppDomain. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the cumulative number of classes loaded in all Assemblies since the start of this application. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the peak number of classes that have failed to load since the start of the application. These load failures could be due to many reasons like inadequate security or illegal format. Full details can be found in the profiling services help. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Stats for CLR Locks and Threads. This is a and so cannot be inherited or instantiated. + + + Rate at which threads in the runtime attempt to acquire a managed lock unsuccessfully. Managed locks can be acquired in many ways; by the "lock" statement in C# or by calling System.Monitor.Enter or by using MethodImplOptions.Synchronized custom attribute. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of threads currently waiting to acquire some managed lock in the application. This counter is not an average over time; it displays the last observed value. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of current .NET thread objects in the application. A .NET thread object is created either by new System.Threading.Thread or when an unmanaged thread enters the managed environment. This counters maintains the count of both running and stopped threads. This counter is not an average over time; it just displays the last observed value. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of native OS threads created and owned by the CLR to act as underlying threads for .NET thread objects. This counters value does not include the threads used by the CLR in its internal operations; it is a subset of the threads in the OS process. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of threads that are currently recognized by the CLR; they have a corresponding .NET thread object associated with them. These threads are not created by the CLR; they are created outside the CLR but have since run inside the CLR at least once. Only unique threads are tracked; threads with same thread ID re-entering the CLR or recreated after thread exit are not counted twice. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of threads that have been recognized by the CLR since the start of this application; these threads have a corresponding .NET thread object associated with them. These threads are not created by the CLR; they are created outside the CLR but have since run inside the CLR at least once. Only unique threads are tracked; threads with same thread ID re-entering the CLR or recreated after thread exit are not counted twice. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of threads that waited to acquire some managed lock since the start of the application. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of threads per second waiting to acquire some lock in the application. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of threads per second that have been recognized by the CLR; these threads have a corresponding .NET thread object associated with them. These threads are not created by the CLR; they are created outside the CLR but have since run inside the CLR at least once. Only unique threads are tracked; threads with same thread ID re-entering the CLR or recreated after thread exit are not counted twice. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of times threads in the CLR have attempted to acquire a managed lock unsuccessfully. Managed locks can be acquired in many ways; by the "lock" statement in C# or by calling System.Monitor.Enter or by using MethodImplOptions.Synchronized custom attribute. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Counters for CLR Garbage Collected heap. This is a and so cannot be inherited or instantiated. + + + This counter displays the rate of bytes per second allocated on the GC Heap. This counter is updated at the end of every GC; not at each allocation. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of garbage collected objects that survive a collection because they are waiting to be finalized. If these objects hold references to other objects then those objects also survive but are not counted by this counter; the "Promoted Finalization-Memory from Gen 0" and "Promoted Finalization-Memory from Gen 1" counters represent all the memory that survived due to finalization. This counter is not a cumulative counter; its updated at the end of every GC with count of the survivors during that particular GC only. This counter was designed to indicate the extra overhead that the application might incur because of finalization. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the maximum bytes that can be allocated in generation 0 (Gen 0); its does not indicate the current number of bytes allocated in Gen 0. A Gen 0 GC is triggered when the allocations since the last GC exceed this size. The Gen 0 size is tuned by the Garbage Collector and can change during the execution of the application. At the end of a Gen 0 collection the size of the Gen 0 heap is infact 0 bytes; this counter displays the size (in bytes) of allocations that would trigger the next Gen 0 GC. This counter is updated at the end of a GC; its not updated on every allocation. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the bytes per second that are promoted from generation 0 (youngest) to generation 1; objects that are promoted just because they are waiting to be finalized are not included in this counter. Memory is promoted when it survives a garbage collection. This counter was designed as an indicator of relatively long-lived objects being created per sec. This counter displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of bytes in generation 1 (Gen 1); this counter does not display the maximum size of Gen 1. Objects are not directly allocated in this generation; they are promoted from previous Gen 0 GCs. This counter is updated at the end of a GC; its not updated on every allocation. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the bytes per second that are promoted from generation 1 to generation 2 (oldest); objects that are promoted just because they are waiting to be finalized are not included in this counter. Memory is promoted when it survives a garbage collection. Nothing is promoted from generation 2 since it is the oldest. This counter was designed as an indicator of very long-lived objects being created per sec. This counter displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of bytes in generation 2 (Gen 2). Objects are not directly allocated in this generation; they are promoted from Gen 1 during previous Gen 1 GCs. This counter is updated at the end of a GC; its not updated on every allocation. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current size of the Large Object Heap in bytes. Objects greater than 20 KBytes are treated as large objects by the Garbage Collector and are directly allocated in a special heap; they are not promoted through the generations. This counter is updated at the end of a GC; its not updated on every allocation. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter is the sum of four other counters; Gen 0 Heap Size; Gen 1 Heap Size; Gen 2 Heap Size and the Large Object Heap Size. This counter indicates the current memory allocated in bytes on the GC Heaps. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of GC Handles in use. GCHandles are handles to resources external to the CLR and the managed environment. Handles occupy small amounts of memory in the GCHeap but potentially expensive unmanaged resources. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of times the generation 0 objects (youngest; most recently allocated) are garbage collected (Gen 0 GC) since the start of the application. Gen 0 GC occurs when the available memory in generation 0 is not sufficient to satisfy an allocation request. This counter is incremented at the end of a Gen 0 GC. Higher generation GCs include all lower generation GCs. This counter is explicitly incremented when a higher generation (Gen 1 or Gen 2) GC occurs. _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of times the generation 1 objects are garbage collected since the start of the application. The counter is incremented at the end of a Gen 1 GC. Higher generation GCs include all lower generation GCs. This counter is explicitly incremented when a higher generation (Gen 2) GC occurs. _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of times the generation 2 objects (older) are garbage collected since the start of the application. The counter is incremented at the end of a Gen 2 GC (also called full GC). _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the peak number of times a garbage collection was performed because of an explicit call to GC.Collect. Its a good practice to let the GC tune the frequency of its collections. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of pinned objects encountered in the last GC. This counter tracks the pinned objects only in the heaps that were garbage collected e.g. a Gen 0 GC would cause enumeration of pinned objects in the generation 0 heap only. A pinned object is one that the Garbage Collector cannot move in memory. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of sync blocks in use. Sync blocks are per-object data structures allocated for storing synchronization information. Sync blocks hold weak references to managed objects and need to be scanned by the Garbage Collector. Sync blocks are not limited to storing synchronization information and can also store COM interop metadata. This counter was designed to indicate performance problems with heavy use of synchronization primitives. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the amount of virtual memory (in bytes) currently committed by the Garbage Collector. (Committed memory is the physical memory for which space has been reserved on the disk paging file). This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the amount of virtual memory (in bytes) currently reserved by the Garbage Collector. (Reserved memory is the virtual memory space reserved for the application but no disk or main memory pages have been used.) This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Not Displayed. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the bytes of memory that are promoted from generation 0 to generation 1 just because they are waiting to be finalized. This counter displays the value observed at the end of the last GC; its not a cumulative counter. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the bytes of memory that are promoted from generation 1 to generation 2 just because they are waiting to be finalized. This counter displays the value observed at the end of the last GC; its not a cumulative counter. This counter is reset to 0 if the last GC was a Gen 0 GC only. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the bytes of memory that survive garbage collection (GC) and are promoted from generation 0 to generation 1; objects that are promoted just because they are waiting to be finalized are not included in this counter. This counter displays the value observed at the end of the last GC; its not a cumulative counter. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the bytes of memory that survive garbage collection (GC) and are promoted from generation 1 to generation 2; objects that are promoted just because they are waiting to be finalized are not included in this counter. This counter displays the value observed at the end of the last GC; its not a cumulative counter. This counter is reset to 0 if the last GC was a Gen 0 GC only. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + % Time in GC is the percentage of elapsed time that was spent in performing a garbage collection (GC) since the last GC cycle. This counter is usually an indicator of the work done by the Garbage Collector on behalf of the application to collect and compact memory. This counter is updated only at the end of every GC and the counter value reflects the last observed value; its not an average. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Help not available. This is a and so cannot be inherited or instantiated. + + + The cumulative total number of bytes received over all open socket connections since the process was started. This number includes data and any protocol information that is not defined by the TCP/IP protocol. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + The cumulative total number of bytes sent over all open socket connections since the process was started. This number includes data and any protocol information that is not defined by the TCP/IP protocol. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + The cumulative total number of socket connections established for this process since the process was started. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + The cumulative total number of datagram packets received since the process was started. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + The cumulative total number of datagram packets sent since the process was started. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Stats for CLR Remoting. This is a and so cannot be inherited or instantiated. + + + This counter displays the total number of remoting channels registered across all AppDomains since the start of the application. Channels are used to transport messages to and from remote objects. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of context-bound classes loaded. Classes that can be bound to a context are called context-bound classes; context-bound classes are marked with Context Attributes which provide usage rules for synchronization; thread affinity; transactions etc. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of context-bound objects allocated per second. Instances of classes that can be bound to a context are called context-bound objects; context-bound classes are marked with Context Attributes which provide usage rules for synchronization; thread affinity; transactions etc. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of remoting proxy objects created in this process since the start of the process. Proxy object acts as a representative of the remote objects and ensures that all calls made on the proxy are forwarded to the correct remote object instance. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the current number of remoting contexts in the application. A context is a boundary containing a collection of objects with the same usage rules like synchronization; thread affinity; transactions etc. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the number of remote procedure calls invoked per second. A remote procedure call is a call on any object outside the caller;s AppDomain. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of remote procedure calls invoked since the start of this application. A remote procedure call is a call on any object outside the caller;s AppDomain. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Stats for CLR Security. This is a and so cannot be inherited or instantiated. + + + This counter displays the total number of linktime Code Access Security (CAS) checks since the start of the application. Linktime CAS checks are performed when a caller makes a call to a callee demanding a particular permission at JIT compile time; linktime check is performed once per caller. This count is not indicative of serious performance issues; its indicative of the security system activity. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Not Displayed. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the depth of the stack during that last runtime Code Access Security check. Runtime Code Access Security check is performed by crawling the stack. This counter is not an average; it just displays the last observed value. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the percentage of elapsed time spent in performing runtime Code Access Security (CAS) checks since the last such check. CAS allows code to be trusted to varying degrees and enforces these varying levels of trust depending on code identity. This counter is updated at the end of a runtime security check; it represents the last observed value; its not an average. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Reserved for future use. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + This counter displays the total number of runtime Code Access Security (CAS) checks performed since the start of the application. Runtime CAS checks are performed when a caller makes a call to a callee demanding a particular permission; the runtime check is made on every call by the caller; the check is done by examining the current thread stack of the caller. This counter used together with "Stack Walk Depth" is indicative of performance penalty for security checks. This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by for the current instance. + + + Counters for System.Data.OracleClient This is a and so cannot be inherited or instantiated. + + + The number of actual connections per second that are being made to servers This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of actual disconnects per second that are being made to servers This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of unique connection strings This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connection pools This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections currently in-use This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections currently available for use This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of unique connection strings waiting for pruning This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connection pools This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections that are not using connection pooling This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections that are managed by the connection pooler This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections we reclaim from GCed from external connections This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections currently waiting to be made ready for use This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections we get from the pool per second This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections we return to the pool per second This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + Counters for System.Data.SqlClient This is a and so cannot be inherited or instantiated. + + + The number of actual connections per second that are being made to servers This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of actual disconnects per second that are being made to servers This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of unique connection strings This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connection pools This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections currently in-use This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections currently available for use This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of unique connection strings waiting for pruning This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connection pools This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections that are not using connection pooling This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections that are managed by the connection pooler This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections we reclaim from GCed from external connections This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections currently waiting to be made ready for use This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections we get from the pool per second This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + The number of connections we return to the pool per second This is a and so cannot be inherited or instantiated. + + + Gets the value of the . + Value returned by . + + + Process Test Pattern fixture. This class cannot be inherited. + + + Creates the execution logic + A instance that represent the type test logic. + + + Tags method that provide new object to be used in the following tests. + + + Gets or sets the provided type + Provided type. + + + Tag use to mark a method that writes data to a device. + + + Reflection Assertion class This is a and so cannot be inherited or instantiated. + + + Asserts that the type has a public instance constructor with a signature defined by parameters. + + + Asserts that the type has a constructor, with the specified bindind flags, with a signature defined by parameters. + + + Asserts that the type has a default public constructor + + + Asserts that the type has a public field method with a signature defined by parameters. + + + Asserts that the type has a field, with the specified bindind flags, with a signature defined by parameters. + + + Asserts that the type has a public instance method with a signature defined by parameters. + + + Asserts that the type has a method, with the specified bindind flags, with a signature defined by parameters. + + + Asserts whether an instance of the can be assigned from an instance of . + Parent instance. + Child instance. + + + Asserts whether is an instance of the . + + instance. + Child instance. + + + This tag defines test method that will be repeated the specified number of times. This class cannot be inherited. + + + This tag defines test method that will be repeated the specified number of times. This class cannot be inherited. + + + A resource-based data provider This class cannot be inherited. + + + Tags methods to execute database operation in its own database transaction. This class cannot be inherited. + + + Provides a row of values using in conjunction with to bind values to the parameters of a row test method. This class cannot be inherited. + + + Gets or sets the type of exception that is expected to be thrown when this row is tested, or null if none. + + + Gets the row of values. + The row of values + + + Gets the row of values. Each one will be converted (if posible) to the type of the corresponding argument in the test method. + List of parameters. + The row of values. + + + Declares a row test when applied to a test method along with one or more attributes. This class cannot be inherited. + + + Security Assertion class This is a and so cannot be inherited or instantiated. + + + Asserts that is authenticated. + + + Asserts that is not authenticated. + + + Asserts that the current windows identity is authenticated. + + + Asserts that the current windows identity is not authenticated. + + + Asserts that the current windows identity is in role. + + + Asserts that the current windows identity is in role. + + + Asserts that the current windows identity is in role. + + + Asserts that the current windows identity is in . + + + Asserts that the current windows identity is in role. + + + Verifies that the type is serializable with the XmlSerializer object. + type to test. + + + Serializes and deserialies to/from XML and checks that the results are the same. + Object to test + + + Tag use to mark a method that initiliazes the fixture instance. + + + String Assertion class This is a and so cannot be inherited or instantiated. + + + Asserts that two strings are equal, ignoring the case + Expected string + Actual string + + + Asserts the string does not contain c + String to test. + Variable list of characeters. + + + Asserts the regular expression reg makes a full match on s + String to test. + Regular expression + + + Asserts the regular expression regex makes a full match on . + String to test. + Regular expression + + + Asserts that the string is non null and empty + String to test. + + + Asserts that the string is non null and non empty + String to test. + + + Asserts the regular expression reg makes a match on s + String to test. + Regular expression + + + Asserts the regular expression regex makes a match on s + String to test. + A instance. + + + Asserts the regular expression reg makes a match on s + String to test. + Regular expression + + + Asserts the regular expression regex makes a match on s + String to test. + A instance. + + + Tag use to mark a method that cleans up the resource of the fixture instance. + + + Tag use to mark a mark a unit test method. This class cannot be inherited. + + + A single test case of a . + + + Gets the name of the test case + The name of the test case + + + Invokes test using the parameters returned by . + + + Simple Test Pattern fixture. This class cannot be inherited. + + + Creates the execution logic + A instance that represent the type test logic. + + + Contributes additional tests and setup or teardown steps to the lifecycle defined by . This class is and so cannot be instantiated. + + + Called to add runs to perform after teardown. + The collection to update + + + Called to add runs to perform before setup. + The collection to update + + + Called to add runs to perform during the test execution cycle. + The collection to update + + + Creates an order of execution in the fixture. This class cannot be inherited. + + + Gets or sets the order execution + The order of execution + + + Returns a string that represents the instance. + String representing the object. + + + A named collection of uniquely named . + + + Gets the name. + The name. + + + Gets a collection of . + A collection of . + + + Adds the test case to the suite + + instance to add. + The suite already contains a test case named . + + + Adds a new to the suite. + Name of the new test case + + invoked by the test case + parameters sent to when invoked + + is a null reference (Nothing in Visual Basic) + + is empty. + The suite already contains a test case named . + + + Removes the test case from the suite + Test case to remove + + is a null reference (Nothing in Visual Basic) + + + Test Suite fixture. This class cannot be inherited. + + + Creates the execution logic + A instance that represent the type test logic. + + + Tag used to mark a method that needs to be run before TestSuite generation. + + + This tag defines test method that will invoke the method in the specified number of concurrent threads. This class cannot be inherited. + + + Type fixture pattern implementation. This class cannot be inherited. + + + Creates the execution logic + A instance that represent the type test logic. + + + Gets a list of member names separated by ; + + + Gets a list of values separated by ; + + + A with verified result. + + + Web related assertions. This is a and so cannot be inherited or instantiated. + + + Verifies that the property of is equal to . + + + Verifies that the property of is equal to . + + + Verifies that the property of and are equal. + + + Verifies that the property of is equal to are equal. + + + Verifies that has child controls. + + + Verifies that has no child controls. + + + Verifies that is a child control of + + + Verifies that is the ID of a child control of + + + Verifies that has ViewState enabled. + + + Verifies that ID is equal to . + + + Verifies that is a not child control of + + + Verifies that is the not ID of a child control of + + + Verifies that has not ViewState enabled. + + + Verifies that the property of is false. + + + Verifies that the property of is false. + + + Verifies that the property of is false. + + + Verifies that is not visible. + + + Verifies that the property of is true. + + + Verifies that the property of is true. + + + Verifies that the property of is true. + + + Verifies that is visible. + + + Tag use to mark a method that writes data to a device. + + + A file-based data provider + + + Different collection order + + + Tests ascending order collection + + + Tests ascending order collection + + + Used to specify whether or not the test should delete the extracted resource when the test is complete. + + + Do not delete the extracted resource + + + Delete the extracted resource after the test. + + + When used as parameter in a row test, it will be replaced by null (Nothing in VB). + + + Could not find . + + + Collection indexing test class + + + Collection order tester class. + + + Tests for the and . + + + + + Comparing 2 attributes with the same name but different values + + + Comparing 2 attribute lists with the same attributes in different sequence + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.Algorithms.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.Algorithms.dll new file mode 100644 index 00000000..20413e65 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.Algorithms.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.Algorithms.xml b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.Algorithms.xml new file mode 100644 index 00000000..d5e036bb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.Algorithms.xml @@ -0,0 +1,2818 @@ + + + + QuickGraph.Algorithms + + + + A static class with some helper methods This is a and so cannot be inherited or instantiated. + + + Checks that the graph does not have cyclies + graph to test + g is a null reference + graph contains a cycle + + + Checks that the sub graph rooted at does not have cyclies + graph to test + g is a null reference + graph contains a cycle + + + Computes the connected components. + graph to explore + component map where results are recorded + number of components + + + Checks if the child vertex is a child of the parent vertex using the predecessor map. + + + + + + Checks wheter an edge belongs to the edge set + graph containing the edge set + edge to test + true if e is in the graph edge set + + + Checks wheter an edge that goes from source to target belongs to the edge set + graph containing the edge set + edge source + edge target + true if e is in the graph edge set + + + Checks wheter a vertex belongs to the vertex set + graph containing the vertex set + vertex to test + true if v is in the graph vertex set + + + Checks if there exists a path between source and target + source vertex + target vertex + graph + true if target is reachable from source + + + Returns true if edge is a self edge + edge to test + true if self edge + e is null + + + Create a collection of odd vertices + graph to visit + colleciton of odd vertices + g is a null reference + + + Returns the vertex opposite to v on the edge e. + + + e or v is null + v is not incident to e + + + Returns an enumerable collection of the leaf vertices of the graph + graph to visit + enumerable of leaf vertices + + + Computes the leaves from the vertex. + graph containing the vertex + root of the tree + leaf vertices + + + Returns an enumerable collection of the root vertices of the graph + graph to visit + enumerable of root vertices + + + Computes the strong components. + graph to explore + component map where results are recorded + number of strong components + + + Applies a topological sort to the graph + graph to sort + sorted vertices + + + Creates a condensation graph transformation + + + Read only map of vertices within each strongly connected component + map with StronglyConnectedComponent ID as key and IList of vertices as value + + + Maps a graph vertex to a strongly connected component + Map of IVertex to strongly connected component ID + + + Visited graph + + + Clear the extracted strongly connected components + + + Compute the condensation graph and store it in the supplied graph 'cg' + Instance of mutable graph in which the condensation graph transformation is stored + + + Raise the CondensationGraphVertex evt + Pack the CG vertex and a VertexCollection of it's constituent vertices + + + Raised when a new vertex is added in the condensation graph + + + Encapsulates a vertex in the original graph and it's corresponding vertex in a transformation of the graph + + + Condensation graph vertex + + + Strongly connected vertices from original graph represented by the condensation graph node + + + Connected component computation + + + Gets the component map + Component map + + + Gets the connected components count + Connected component count + + + Visited graph + + + Executes the algorithm + The total number of components is the return value of the function + + + Computes the graph strong components. + + + Component map + + + Gets the number of strongly connected components in the graph + Number of strongly connected components + + + Vertex discory times + + + Root map + + + Visited graph + + + Executes the algorithm + The number of components is the return value of the function. + + + Topological sort of the graph. + + + Sorted vertices list + + + Visited vertex list + + + Delegate event that detects cycle. . + DepthFirstSearch algorithm + Edge that produced the error + Will always throw an exception. + + + Computes the topological sort and stores it in the list. + + + Computes the topological sort and stores it in the list. + Vertex list that will contain the results + + + Delegate that adds the vertex to the vertex list. . + + + + + Creates a transitive closure of the input graph + + + Map of vertex in Original graph to corresponding vertex in Transitive Closure + + + Visited Graph + + + Compute the transitive closure and store it in the supplied graph 'tc' + Mutable Graph instance to store the transitive closure + + is a . + + + Raises the event. + New edge that was added to the transitive closure graph + + + Raises the event. + + + + Invoked when a new edge is added to the transitive closure graph. + + + Invoked when a new vertex is added to the Transitive Closure graph + + + Encapsulates a vertex in the original graph and it's corresponding vertex in a transformation of the graph + + + Vertex in original graph + + + Equivalent Vertex in the transformation graph + + + Delegate to handle the CondensationGraphVertexEvent + + + Delegate to handle the TransformVertexEvent + + + Floyd Warshall All Shortest Path Algorithm + + + Gets the instance + + + Gets the visited graph + Visited Graph + + + Checks the graph for connectivity and negative cycles + cost distionary + graph has negatice cycle. + graph is not strongly connected + + + Compute the All shortest path problem. + + + Raises the event. + source vertex + target vertex + + + Raises the event. + + + + + + Raises the event. + source vertex + target vertex + + + + Raises the event. + + + + + + Raised when initializing a new path + + + Raised when a path is not reduced + + + Raised when a path is reduced + + + Distance reducer interface + + + + + + + + + Edge cloning event argument + + + Clone vertex + + + Original vertex + + + Vertex cloning event argument + + + Gets the clone vertex + Clone vertex instance + + + Gets the original vertex + Original vertex instance + + + A graph cloner algorithm + + + Makes a copy of the source graph to the clone graph. + source graph + clone graph + + + Triggers the CloneEdge event + + + + + Triggers the CloneVertex event + + + + + Clones the to and reverses the edges. + + + Event called on each edge cloning + + + Event called on each vertex cloning + + + Edge cloning event handler + + + Vertex cloning event handler + + + The grid variant of the Fruchterman-Reingold graph layout algorithm. + + + This algorithm is based on the following paper: T. Fruchterman and E. Reingold. "Graph drawing by force-directed placement." Software Practice and Experience, 21(11):1129--1164, 1991. Implemented by Arun Bhalla. + + + Useful point algebra function. This is a and so cannot be inherited or instantiated. + + + Computes the Euclidian distance between two points + first point + second point + + |p1-p2|_2 + + + + Computes the square of the Euclidian distance between two points + first point + second point + + (p1.x-p2.x)^2+(p1.y-p2.y)^2 + + + + Edmonds-Karp Maximum Flow Algorithm + + + Computes the maximum flow between and + + + + + Abstract base class for maximum flow algorithms. This class is and so cannot be instantiated. + + + + + + + Push-Relabel Maximum Flow Algorithm + + + Computes the maximum flow between and . + The source node of the graph. + The sink node of the graph. + The maximum flow of the graph. + + + A implementation that augments a such that for all edge (u,v) there exists the edge (v,u) in the graph. + + + Gets a value indicating wheter the has been augmented. + + + Gets a instance containing the augmented edges. + + + Gets a associating each edge to it's corresponding reversed edge. + + + Augments the with reversed edges. + The graph has already been augmented. + + + Removes the reversed edges. + The graph is not yet augmented. + + + + + Wilson-Propp Cycle-Popping Algorithm for Random Tree Generation. + + + Get the color dictionary + Vertex color dictionary + + + Gets or sets the Markov chain. + Markov chain. + set property, value is a null reference. + + + Gets or sets the random number generator used in RandomTree. + + number generator + + + Gets the dictionary of vertex edges successors in the generated random tree. + Vertex - Edge successor dictionary. + + + Gets the visited instance + Visited instance + + + Attemps to create a new random tree with probability transition . + probability transition + true if random tree generated, false otherwise + + + Clears from the tree and raises the event. + vertex to clear + + + Initializes the tree. + + + Gets the next vertex in the tree. + source vertex + next vertex in tree if any, null otherwise + + + Gets a value indicating if is not in the tree. + vertex to test + true if not in the tree, false otherwise. + + + Raises the event. + vertex being removed + + + Raises the event. + vertex being terminated + + + Raises the event. + vertex being initialized + + + Raises the event. + edge being added to the tree + + + Gets the next out-edge according to the Markov Chain generator. + Source vertex + next edge in the chain, null if u has no out-edges + + + Generates a random tree with no specified root. + + + Generates a random tree rooted at . + root vertex + root is a null reference + + + Adds to the tree and raises the event. + vertex to add + + + Sets as the next edge of in the tree, and raises the event. + source vertex + next edge in tree + + + Occurs when a vertex is removed from the tree. + + + Occurs when a vertex is added to the tree. + + + Occurs when a vertex is initialized + + + Occurs when an edge is added to the tree. + + + Markov chain generator with the propability vector equally distributed over the out-edges. + + + Gets or sets the random generator + Random number generator + + + Selects the next out- in the Markov Chain. + visted graph + source vertex + Random next out-edge + + or is a null reference + + + Stochastic Random Walk Generation. + + + Gets or sets the Markov chain. + Markov chain. + set property, value is a null reference. + + + Gets or sets an end of traversal predicate. + End of traversal predicate. + + + Gets or sets the random number generator used in RandomTree. + + number generator + + + Gets the visited instance + Visited instance + + + Generates a walk of steps + number of steps + + + Generates a walk of steps + root vertex + number of steps + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge being added to the tree + + + Gets the next out-edge according to the Markov Chain generator. + Source vertex + next edge in the chain, null if u has no out-edges + + + Raised on the sink vertex once after the end of the search. + + + Raised on the source vertex once before the start of the search. + + + Occurs when an edge is added to the tree. + + + Markov chain generator with the propability vector distributed over the out-edges weights. + + + Gets or sets the random generator + Random number generator + + + Gets the edge-weight dictionary + Edge weight dictionary + + + Selects the next out- in the Markov Chain. + visted graph + source vertex + Random next out-edge + + or is a null reference + + + When implemented by a class, defines methods to generate a random Markov chain of . + + + Selects the next out- in the Markov Chain. + visted graph + source vertex + Random next out-edge + + or is a null reference + + + Algorithm that computes the PageRank ranking over a graph. + + + Gets or sets the damping factor in the PageRank iteration. + Damping factor in the PageRank formula (d). + + + Gets or sets the maximum number of iterations + The maximum number of iteration. + + + Gets the page rank dictionary + The of - rank entries.ank entries. + + + Gets or sets the tolerance to stop iteration + The tolerance to stop iteration. + + + Gets the visited graph + A instance + + + Computes the PageRank over the . + + + Initializes the rank map. + + + Iteratively removes the dangling links from the rank map + + + Performs a breadth-first traversal of a directed or undirected graph. + + + Gets the to dictionary + + to dictionary + + + Visited graph + + + Computes the bfs starting at s + starting vertex + s is null + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + + + + Registers the predecessors handler + + + + + + + + + + Computes the bfs starting at s without initalization. + starting vertex + current depth + s is null + + + Invoked (in addition to NonTreeEdge()) if the target vertex is colored black at the time of examination. The color black indicates that the vertex is no longer in the queue. + + + Invoked the first time the algorithm encounters vertex u. All vertices closer to the source vertex have been discovered, and vertices further from the source have not yet been discovered. + + + Invoked on every out-edge of each vertex immediately after the vertex is removed from the queue. + + + Invoked in each vertex as it is removed from the queue + + + Invoked after all of the out edges of u have been examined and all of the adjacent vertices have been discovered. + + + Invoked (in addition to non_tree_edge()) if the target vertex is colored gray at the time of examination. The color gray indicates that the vertex is currently in the queue. + + + Invoked on every vertex before the start of the search + + + Invoked (in addition to examine_edge()) if the edge is not a tree edge. + + + Invoked (in addition to ExamineEdge()) if the edge is a tree edge. The target vertex of edge e is discovered at this time. + + + The DepthFirstSearchAlgorithm performs a depth-first traversal of the vertices in a directed graph. + + + Gets the vertex color map + Vertex color () dictionary + + + Gets or sets the maximum exploration depth, from the start vertex. + Maximum exploration depth. + + + Visited graph + + + Execute the DFS search. + + + Execute the DFS starting with the vertex s + Starting vertex + + + Initializes the vertex color map + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Registers the predecessors handler + + + + + + + + + + + + + Does a depth first search on the vertex u + vertex to explore + current recursion depth + u cannot be null + + + Invoked on the back edges in the graph. + + + Invoked when a vertex is encountered for the first time. + + + Invoked on every out-edge of each vertex after it is discovered. + + + Invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on every vertex of the graph before the start of the graph search. + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + The EdgeDepthFirstSearchAlgorithm performs a depth-first traversal of the edges in a directed graph. + + + Gets the edge dictionary + Edge dictionary + + + Gets or sets the maximum exploration depth, from the start edge. + Maximum exploration depth. + + + Gets the visited graph + The visited graph + + + Compute the algorithm starting at the first vertex. + + + Execute the EDFS starting with the vertex s + Starting vertex + + + Initiliaze color map + + + Triggers the BackEdge event. + + + + Triggers DiscoverEdge event + + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the StartEdge event. + + + + Triggers the StartVertex event. + + + + Triggers the TreeEdge event. + + + + Registers the handlers of a visitor. + visitor to "attach" + + + Registers the handlers of a visitor. + visitor to "attach" + + + Does a depth first search on the vertex u + edge to explore + current exploration depth + se cannot be null + + + Invoked on the back edges in the graph. + + + Invoked on a edge after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on every vertex of the graph before the start of the graph search. + + + Invoked on the first edge of a test case + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + The EdgeDepthFirstSearchAlgorithm performs a depth-first traversal of the edges in a directed graph. + + + Gets the edge dictionary + Edge dictionary + + + Gets or sets the maximum exploration depth, from the start edge. + Maximum exploration depth. + + + Gets the visited graph + The visited graph + + + Compute the algorithm starting at the first vertex. + + + Execute the EDFS starting with the vertex s + Starting vertex + + + Initiliaze color map + + + Triggers the BackEdge event. + + + + Triggers DiscoverEdge event + + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the StartEdge event. + + + + Triggers the StartVertex event. + + + + Triggers the TreeEdge event. + + + + Registers the handlers of a visitor. + visitor to "attach" + + + Registers the handlers of a visitor. + visitor to "attach" + + + Does a depth first search on the vertex u + edge to explore + current exploration depth + se cannot be null + + + Invoked on the back edges in the graph. + + + Invoked on a edge after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on every vertex of the graph before the start of the graph search. + + + Invoked on the first edge of a test case + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + Gets the vertex color map + Vertex color () dictionary + + + Gets or sets the maximum exploration depth, from the start vertex. + Maximum exploration depth. + + + Visited graph + + + Execute the DFS search. + + + Execute the DFS starting with the vertex s + Starting vertex + + + Initializes the vertex color map + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Registers the predecessors handler + + + + + + + + + + + + + Does a depth first search on the vertex u + vertex to explore + current recursion depth + u cannot be null + + + Invoked on the back edges in the graph. + + + Invoked when a vertex is encountered for the first time. + + + Invoked on every out-edge of each vertex after it is discovered. + + + Invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on every vertex of the graph before the start of the graph search. + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + Gets the vertex color map + Vertex color () dictionary + + + Gets or sets the maximum exploration depth, from the start vertex. + Maximum exploration depth. + + + Gets the Visited graph + + + Does an implicit depth first search on the graph + Start vertex of the depth first search + + + Initializes the algorithm before computation. + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Registers the predecessors handler + + + + + + + + + + Visit vertex . + + + + + Invoked on the back edges in the graph. + + + Invoked when a vertex is encountered for the first time. + + + Invoked on every out-edge of each vertex after it is discovered. + + + Invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + Gets the vertex color map + Vertex color () dictionary + + + Gets or sets the maximum exploration depth, from the start vertex. + Maximum exploration depth. + + + Gets the Visited graph + + + Does an implicit depth first search on the graph + Start vertex of the depth first search + + + Initializes the algorithm before computation. + + + Triggers the BackEdge event. + + + + Triggers DiscoverEdge event + + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the ForwardOrCrossEdge event. + + + + Triggers the StartEdge event. + + + + Triggers the StartVertex event. + + + + Triggers the TreeEdge event. + + + + Registers the handlers of a visitor. + visitor to "attach" + + + Does a depth first search on the vertex u + edge to explore + current exploration depth + se cannot be null + + + Invoked on the back edges in the graph. + + + Invoked on a edge after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on the first edge of a test case + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + The DepthFirstSearchAlgorithm performs a depth-first traversal of the vertices in a directed graph. + + + Gets the vertex color map + Vertex color () dictionary + + + Gets or sets the maximum exploration depth, from the start vertex. + Maximum exploration depth. + + + Visited graph + + + Execute the DFS search. + + + Execute the DFS starting with the vertex s + Starting vertex + + + Initializes the vertex color map + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Registers the predecessors handler + + + + + + + + + + + + + Does a depth first search on the vertex u + vertex to explore + current recursion depth + u cannot be null + + + Invoked on the back edges in the graph. + + + Invoked on the back edges in the graph. + + + Invoked when a vertex is encountered for the first time. + + + Invoked on every out-edge of each vertex after it is discovered. + + + Invoked on every out-edge of each vertex after it is discovered. + + + Invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on forward or cross edges in the graph. (In an undirected graph this method is never called.) + + + Invoked on every vertex of the graph before the start of the graph search. + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + Performs a undirected (depth first and height first) depth first search on a directed bidirectional graph. + + + Vertex color map + + + Edge color map + + + Visited graph + + + Computes the dfs + + + Computes the dfs starting at s + start vertex + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + vertex that raised the event + + + Raises the event. + edge that raised the event + + + Registers the predecessors handler + + + + + + + + + + Visits vertex s + vertex to visit + + + Invoked on the back edges in the graph. + + + Invoked when a vertex is encountered for the first time. + + + Invoked on every out-edge of each vertex after it is discovered. + + + Invoked on a vertex after all of its out edges have been added to the search tree and all of the adjacent vertices have been discovered (but before their out-edges have been examined). + + + Invoked on every vertex of the graph before the start of the graph search. + + + Invoked on the source vertex once before the start of the search. + + + Invoked on each edge as it becomes a member of the edges that form the search tree. If you wish to record predecessors, do so at this event point. + + + Bellman Ford shortest path algorithm. + + + Vertex color map + + + Constructed distance map + + + Constructed predecessor map + + + Edge weights + + + Computes all the shortest path from s to the oter vertices + Start vertex + true if successful, false if there was a negative cycle. + s is null + + + Applies the Bellman Ford algorithm + true if successful, false if there was a negative cycle. + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Raises the event. + vertex that raised the event + + + Invoked during the second stage of the algorithm, during the test of whether each edge was minimized. If the edge is minimized then this function is invoked. + + + Invoked during the second stage of the algorithm, during the test of whether each edge was minimized. If the edge was not minimized, this function is invoked. This happens when there is a negative cycle in the graph. + + + Invoked if the distance label for the target vertex is not decreased. + + + Invoked when the distance label for the target vertex is decreased. The edge that participated in the last relaxation for vertex v is an edge in the shortest paths tree. + + + Invoked on every edge in the graph |V| times. + + + Invoked on each vertex in the graph before the start of the algorithm. + + + Directed Acyclic Graph single source shortest path algorithm. + + + Vertex color map + + + Constructed distance map + + + Constructed predecessor map + + + Visited graph + + + Computes all the shortest path from s to the oter vertices + Start vertex + s is null + + + Triggers the DiscoverVertex event + + + + Triggers the EdgeNotRelaxed event + + + + Triggers the EdgeRelaxed event + + + + Triggers the ExamineEdge event + + + + Triggers the ExamineVertex event + + + + Triggers the FinishVertex event + + + + Triggers the InitializeVertex event + + + + + + + Invoked on vertex v when the edge (u,v) is examined and v is White. Since a vertex is colored Gray when it is discovered, each reachable vertex is discovered exactly once. This is also when the vertex is inserted into the priority queue. + + + Invoked if the edge is not relaxed. . + + + invoked on edge (u,v) if d[u] + w(u,v) < d[v]. The edge (u,v) that participated in the last relaxation for vertex v is an edge in the shortest paths tree. + + + Invoked on each out-edge of a vertex immediately after it has been added to set S. + + + Invoked on a vertex as it is added to set S. + + + Invoked on a vertex after all of its out edges have been examined. + + + Invoked on each vertex in the graph before the start of the algorithm. + + + Dijkstra shortest path algorithm. + + + Vertex color map + + + Constructed distance map + + + Vertex priorithized queue. Used internally. + + + Visited graph + + + Computes all the shortest path from s to the oter vertices + Start vertex + s is null + + + Raises the event. + edge that raised the event + + + Raises the event. + edge that raised the event + + + Add event handlers to the corresponding events. + Distance recorder visitor + + + Register the predecessor handlers + visitor + + + + + + Create a edge unary weight dictionary. + graph to map + Dictionary where each edge wheight is 1 + + + Create a edge unary weight dictionary. + graph to map + Dictionary where each edge wheight is 1 + + + Invoked on vertex v when the edge (u,v) is examined and v is WHITE. Since a vertex is colored GRAY when it is discovered, each reachable vertex is discovered exactly once. This is also when the vertex is inserted into the priority queue. + + + Invoked if the edge is not relaxed. . + + + invoked on edge (u,v) if d[u] + w(u,v) < d[v]. The edge (u,v) that participated in the last relaxation for vertex v is an edge in the shortest paths tree. + + + Invoked on each out-edge of a vertex immediately after it has been added to set S. + + + Invoked on a vertex as it is removed from the priority queue and added to set S. At this point we know that (p[u],u) is a shortest-paths tree edge so d[u] = delta(s,u) = d[p[u]] + w(p[u],u). Also, the distances of the examined vertices is monotonically increasing d[u1] <= d[u2] <= d[un]. + + + Invoked on a vertex after all of its out edges have been examined. + + + Invoked on each vertex in the graph before the start of the algorithm. + + + Optimal winning strategy calculation algorithm. + + + A Strategy as defined in section 3 of the article. + + + + A TestGraph as defined in the section 2 of the article. + + + + + Get the choice point enumerable collection (CP). + Choice point vertices enumerable collection. + + + Gets the underlying graph representing the Finite State Machine. + + instance representing the fsm. + + + Get the state enumerable collection (V-CP). + State vertices enumerable collection. + + + Gets a value indicating if is in CP. + vertex to test + true if is in CP + + + Gets a value indicating if is in the state set. + vertex to test + true if is in the state set + + + Gets a cost associated to the . + edge to test + Cost associated to + + + Gets a probability associated to the . + edge to test + Probability associated to + + + Under construction + + + Eulerian circuit on modified graph + + + Visited Graph + + + Adds temporary edges to the graph to make all vertex even. + + + + Merges the temporary circuit with the current circuit + true if all the graph edges are in the circuit + + + Computes the eulerian trails + + + Computes the number of eulerian trail in the graph. If negative, there is an eulerian circuit. + + number of eulerian trails + + + + + + + + + + + + Removes temporary edges + + + + Search a new path to add to the current circuit + start vertex + true if successfull, false otherwize + + + Computes the set of eulerian trails that traverse the edge set. + Eulerian trail set + + + Computes a set of eulerian trail, starting at that spans the entire graph. + start vertex + eulerian trail set, all starting at s + s is a null reference. + Eulerian trail not computed yet. + + + Looks for a new path to add to the current vertex. + true if found a new path, false otherwize + + + Records the vertex distance + + + Vertex distance dictionary + + + d[u] = 0; + + + + + d[u] = + intfy + Algorithm using the visitor + Contains the vertex + + + Let e = (u,v), d[ v ] = d[ u ] + 1; + + + + + Visitor that computes the edge predecessors. + + + Vertex Edge predecessor map. + + + End path edges collection + + + Returns the array of merged paths + + + Returns the minimal set of path from the entry point that executes all actions + + + Records edge predecessor + + + Records end path edges + + + + + Not used + + + + + Create a merged path. + end edge + edge color dictionary + path to edge + + + Returns the path leading to the vertex v. + end of the path + path leading to v + + + A visitor that records edges. + + + Recorded edges + + + Record edge handler + + + + + Scales the edge weights at each call + + + Gets or sets the scale factor + Scale factor + + + Gets the edge weight dictionary + Edge weight dictionary + + + Event handler that applies the factor the edge weight + + event arguement containing the edge + + + Visitor that computes the vertices predecessors. + + + End of path vertices + + + Vertex Edge predecessor map. + + + Returns the minimal set of path from the entry point that executes all actions + + + Records end of path vertex + + + + + Returns the path leading to the vertex v. + end of the path + path leading to v + + + Let e = (u,v), p[v]=u + + + Visitor that records the sink vertices in the visited tree. + + + Gets the sink collection + A of sink vertices + + + Gets the visited instance + The visited graph + + + Removes + + + + + Let e = (u,v), p[u]=e + + + Description résumée de TimeStamperVisitor. + + + Vertex discover time dictionary + + + Vertex finish time dictionary + + + Current time + + + Store the current time in the discover dictionary and increment the current time. + + + + + Store the current time in the finish dictionary and increment the current time. + + + + + A visitor that records vertices. + + + Recorded vertices + + + Record vertex handler + + + + + Record vertex handler + + + + + Record vertex handler + + + + + A mutable incidence graph implemetation + + + Gets a value indicating if the graph allows parralell edges. + true if the graph is a multi-graph, false otherwise + + + Gets the provider + + provider + + + Enumerable collection of edges. + + + Gets the edge count + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the graph is directed. + true if the graph is directed, false if undirected. + + + Vertex Out edges dictionary + Dictionary of to out edge collection. + + + Gets the provider + + provider + + + Enumerable collection of vertices. + + + Gets the number of vertices + Number of vertices in the graph + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Add a new vertex from source to target Complexity: 2 search + 1 insertion + Source vertex + Target vertex + Created Edge + source or target is null + source or target are not part of the graph + + + Used for serialization. Not for private use. + edge to add. + + + Add a new vertex to the graph and returns it. Complexity: 1 insertion. + Create vertex + + + Add a new vertex to the graph and returns it. Complexity: 1 insertion. + Create vertex + + + Gets an enumerable collection of adjacent vertices + + Enumerable collection of adjacent vertices + + + Remove all of the edges and vertices from the graph. + + + Remove all edges to and from vertex u from the graph. + + + + Tests if a edge is part of the graph + Edge to test + true if is part of the graph, false otherwize + + + Test if an edge (u,v) is part of the graph + source vertex + target vertex + true if part of the graph + + + Tests if a vertex is part of the graph + Vertex to test + true if is part of the graph, false otherwize + + + Returns the number of out-degree edges of v + vertex + number of out-edges of the v + + + Returns an iterable collection over the edge connected to v + + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + Removes an edge from the graph. Complexity: 2 edges removed from the vertex edge list + 1 edge removed from the edge list. + edge to remove + e is null + + + Remove the edge (u,v) from the graph. If the graph allows parallel edges this remove all occurrences of (u,v). + source vertex + target vertex + + + Remove all the edges from graph g for which the predicate pred returns true. + edge predicate + + + Remove all the out-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + Removes the vertex from the graph. + vertex to remove + v is null + + + Returns the collection of edges that matches the predicate + Edge predicate + enumerable colleciton of vertices that matches the criteron + ep is null + + + Returns the collection of out-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the first Edge that matches the predicate + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + ep is null + + + Returns the first out-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + Returns the first vertex that matches the predicate + vertex predicate + null if not found, otherwize the first vertex that matches the predicate. + vp is null + + + Returns the collection of vertices that matches the predicate + vertex predicate + enumerable colleciton of vertices that matches the criteron + vp is null + + + Creates a bidirectional graph out of a graph. + + + True if parallel edges allowed + + + Adapted graph + + + Directed state + + + Gets a value indicating if the set of edges connected to v is empty + true if the adjacent edge set is empty, false otherwise. + v is a null reference + + + Gets an enumerable collection of the v adjacent vertices + + + + + + + + + + + Returns the number of in-edges plus out-edges (for directed graphs) or the number of incident edges (for undirected graphs) of vertex v in graph g. + vertex to test + out-degree + + + Returns the number of in-edges (for directed graphs) or the number of incident edges (for undirected graphs) of vertex v in graph g. + vertex to test + out-degree + + + Enumerable collection of in-edges + + + Gets a value indicating if the set of in-edges is empty + true if the in-edge set is empty, false otherwise. + v is a null reference + + + Returns the number of out-degree edges of v + vertex to test + out-degree + + + Returns an iterable collection of the out edges of v + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + A mutable bidirectional graph implemetation + + + Vertex Out edges dictionary + + + Add a new vertex from source to target Complexity: 2 search + 1 insertion + Source vertex + Target vertex + Created Edge + source or target is null + source or target are not part of the graph + + + Adds a new edge to the graph + + + + Add a new vertex to the graph and returns it. Complexity: 1 insertion. + Create vertex + + + Adds a new vertex to the graph. + + + + Gets a value indicating if the set of edges connected to v is empty + true if the adjacent edge set is empty, false otherwise. + v is a null reference + + + Remove all of the edges and vertices from the graph. + + + Remove all edges to and from vertex u from the graph. + + + + Returns the number of in-edges plus out-edges. + + + + Returns the number of in-degree edges of v + + + + Returns an iterable collection over the in-edge connected to v + + + + Gets a value indicating if the set of in-edges is empty + true if the in-edge set is empty, false otherwise. + v is a null reference + + + Removes an edge from the graph. Complexity: 2 edges removed from the vertex edge list + 1 edge removed from the edge list. + edge to remove + e is null + + + Remove the edge (u,v) from the graph. If the graph allows parallel edges this remove all occurrences of (u,v). + source vertex + target vertex + + + Remove all the out-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + Removes the vertex from the graph. + vertex to remove + v is null + + + Returns the collection of in-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the first in-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + A clustered adjacency graph + + + Gets a value indicating whether the graph allows parallel edges. + true if the graph allows parallel edges, false otherwize. + + + Gets an enumerable collection of clusters + Enumerable collection of clusters + + + Gets the number of clusters + Number of clusters + + + Not implemented yet. + + + Gets the used to generate the edges. + + instance used to generate the new edges. + + + Gets an enumerable collection of edges. + + collection of edges. + + + Gets the edge count. + Edge count. + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating whether the graph is directed. + true if the graph is directed, false otherwize. + + + Gets the parent . + Parent . + + + Gets the used to generate the vertices. + + instance used to generate the new vertices. + + + Gets an enumerable collection of vertices. + + collection of vertices. + + + Gets the vertex count. + Vertex count. + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets the wrapped object. + + + Adds a new cluster. + New cluster + + + Adds a new edge + source vertex + target edge + added edge + u or v is a null reference + + + Adds an existing edge to the cluster + edge to add + + + Adds a new vertex to the cluster + new vertex + + + Adds an existing vertex to the cluster + vertex to add + + + Gets an enumerable collection of the v adjacent vertices + + + + Clears vertex out-edges + + + + Determines whether the contains the edge . + The edge to locate in . + true if the contains the edge ; otherwise, false. + + + Determines whether the contains an edge from the vertex to the vertex . + The source vertex of the edge(s) to locate in . + The target vertex of the edge(s) to locate in . + true if the contains the edge (, ); otherwise, false. + + + Determines whether the contains the vertex . + The vertex to locate in . + true if the contains the vertex ; otherwise, false. + + + + + + + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + Removes a cluster + cluster to remove + cluster is a null reference. + + + Remove a specific edge + + + + Remove edges from u to v + + + + + Remove edge satifying the predicate + + + + Remove out edge satisfying the predicate + + + + + Removes a vertex from the cluster + + + + Gets a filtered collection of edges. + edge predicate + filetered collection + + + + + + + + + + + + + + + + + + + + An edge-list representation of a graph is simply a sequence of edges, where each edge is represented as a pair of vertex ID's. + + + Returns an enumerator providing access to all the edges in the graph. + + + Returns the number of edges in the graph. + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + + + + A mutable tree-like graph + + + Gets a value indicating if the tree allows cycles + true if it allows cycle, false otherwise + + + Adds a child vertex to the tree + parent vertex + created vertex + parent is a null reference + if AllowCycles is false and the edge creates a cycle + + + Removes vertex and sub-tree + vertex to remove + v is a null reference + Removing the vertex breaks the graph connectivity + + + Records all the edges that are part of the subtree of v + visited graph + root edge + maximum expolration depth + + + Records all the vertices that are part of the in-subtree of v + visited graph + root vertex + Maximum exploration depth + + + Records all the edges that are part of the subtree of v + visited graph + root edge + maximum expolration depth + + + Records all the vertices that are part of the out-subtree of v + visited graph + root vertex + Maximum exploration depth + + + Adaptor to flip in-edges and out-edges. + + + Reversed graph + + + Gets a value indicating if the set of edges connected to v is empty + true if the adjacent edge set is empty, false otherwise. + v is a null reference + + + Gets an enumerable collection of the v adjacent vertices + + + + Check the graph contains an edge from to . + + + + + Vertex degree + vertex to compute + vertex edgree + + + Flipped out-degree + vertex to compute + transposed out-edgree + + + Returns a transposed out-edges enumerable + vertex to compute + transposed out edges enumerable + + + Gets a value indicating if the set of in-edges is empty + true if the in-edge set is empty, false otherwise. + v is a null reference + + + Flipped in-degree + vertex to compute + transposed in-edgree + + + Returns a transposed in-edges enumerable + vertex to compute + transposed in edges enumerable + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + A tree-like wrapper for bidirectional graph + + + Gets the wrapped instance. + + + Gets an enumerable collection of child + current + An enumerable collection of adjacent vertices + + is a null reference + + + Gets the first adjacent vertex + current vertex + first out-vertex + + is a null reference + + + Gets a value indicating if the has out-edges + + to test + true if has out-edges. + + is a null reference + + + + + is a null reference + + + Gets the parent. + current vertex + parent vertex if any, null reference otherwize + + is a null reference + + has multiple in-edges + + + A mutable incidence graph implemetation + + + Gets a value indicating if the graph allows parralell edges. + true if the graph is a multi-graph, false otherwise + + + Gets the provider + + provider + + + Enumerable collection of edges. + + + Gets the edge count + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the graph is directed. + true if the graph is directed, false if undirected. + + + Vertex Out edges dictionary + Dictionary of to out edge collection. + + + Gets the provider + + provider + + + Enumerable collection of vertices. + + + Gets the number of vertices + Number of vertices in the graph + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Add a new vertex from source to target Complexity: 2 search + 1 insertion + Source vertex + Target vertex + Created Edge + source or target is null + source or target are not part of the graph + + + Used for serialization. Not for private use. + edge to add. + + + Add a new vertex to the graph and returns it. Complexity: 1 insertion. + Create vertex + + + Add a new vertex to the graph and returns it. Complexity: 1 insertion. + Create vertex + + + Gets an enumerable collection of adjacent vertices + + Enumerable collection of adjacent vertices + + + Remove all of the edges and vertices from the graph. + + + Remove all edges to and from vertex u from the graph. + + + + Tests if a edge is part of the graph + Edge to test + true if is part of the graph, false otherwize + + + Test is an edge (u,v) is part of the graph + source vertex + target vertex + true if part of the graph + + + Tests if a vertex is part of the graph + Vertex to test + true if is part of the graph, false otherwize + + + Returns the number of out-degree edges of v + vertex + number of out-edges of the v + + + Returns an iterable collection over the edge connected to v + + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + Removes an edge from the graph. Complexity: 2 edges removed from the vertex edge list + 1 edge removed from the edge list. + edge to remove + e is null + + + Remove the edge (u,v) from the graph. If the graph allows parallel edges this remove all occurrences of (u,v). + source vertex + target vertex + + + Remove all the edges from graph g for which the predicate pred returns true. + edge predicate + + + Remove all the out-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + Removes the vertex from the graph. + vertex to remove + v is null + + + Returns the collection of edges that matches the predicate + Edge predicate + enumerable colleciton of vertices that matches the criteron + ep is null + + + Returns the collection of out-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the first Edge that matches the predicate + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + ep is null + + + Returns the first out-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + Returns the first vertex that matches the predicate + vertex predicate + null if not found, otherwize the first vertex that matches the predicate. + vp is null + + + Returns the collection of vertices that matches the predicate + vertex predicate + enumerable colleciton of vertices that matches the criteron + vp is null + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.dll new file mode 100644 index 00000000..d9aac723 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.xml b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.xml new file mode 100644 index 00000000..bec1fb7d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/QuickGraph.xml @@ -0,0 +1,3126 @@ + + + + QuickGraph + + + + An edge that can hold a value + + + associated property value + + + A vertex that can hold a value + + + Vertex associated property value + + + A graph edge + + + Edge unique identification number + + + Source vertex + + + Source vertex id, for serialization + + + Target Vertex + + + Source vertex id, for serialization + + + Compares two edges + Edge to compare + obj is not of type Edge. + + + + + + Hash code, using ID + + + Reads no data from serialization info + data holder + info is null + info is serializing + + + Converts to string. + + + Converts to string by returning the formatted ID + + + + Adds nothing to serialization info + data holder + info is null + info is not serializing + + + + + + + + + + + A vertex with a name + + + Vertex name + + + Reads no data from serialization info + data holder + info is null + info is serializing + + + Adds nothing to serialization info + data holder + info is null + info is not serializing + + + A vertex with a name + + + Vertex name + + + Reads no data from serialization info + data holder + info is null + info is serializing + + + Adds nothing to serialization info + data holder + info is null + info is not serializing + + + A Graph Vertex. + + + Unique identification number + + + Compares two vertices + vertex to compare + obj is not of type Vertex + + + + + + Hash code. ID used as identification number. + + + Reads no data from serialization info + data holder + info is null + info is serializing + + + Converts to string by returning the ID. + + + Converts to string by returning the formatted ID + + + + Adds nothing to serialization info + data holder + info is null + info is not serializing + + + + + + + + + + + Given a Distance map, compare two vertex distance + + + Compare the distance between vertex x and y + First vertex + Second vertex + -1 if d[x]<d[y], 0 if d[x] equals d[y] and +1 if d[x] > d[y] + + + A collection of elements of type Double + + + Gets or sets the Double at the given index in this DoubleCollection. + + + Adds an instance of type Double to the end of this DoubleCollection. + The Double to be added to the end of this DoubleCollection. + + + Adds the elements of an array to the end of this DoubleCollection. + The array whose elements are to be added to the end of this DoubleCollection. + + + Adds the elements of another DoubleCollection to the end of this DoubleCollection. + The DoubleCollection whose elements are to be added to the end of this DoubleCollection. + + + Determines whether a specfic Double value is in this DoubleCollection. + The Double value to locate in this DoubleCollection. + true if value is found in this DoubleCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this DoubleCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this DoubleCollection + The Double value to locate in the DoubleCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the DoubleCollection at the specified index + The index at which the Double is to be inserted. + The Double to insert. + + + Removes the first occurrence of a specific Double from this DoubleCollection. + The Double value to remove from this DoubleCollection. + + + Type-specific enumeration class, used by DoubleCollection.GetEnumerator. + + + A collection of elements of type Edge This class cannot be inherited. + + + Gets or sets the Edge at the given index in this EdgeCollection. + + + Adds an instance of type Edge to the end of this EdgeCollection. + The Edge to be added to the end of this EdgeCollection. + + + Adds the elements of an array to the end of this EdgeCollection. + The array whose elements are to be added to the end of this EdgeCollection. + + + Adds the elements of another EdgeCollection to the end of this EdgeCollection. + The EdgeCollection whose elements are to be added to the end of this EdgeCollection. + + + Determines whether a specfic Edge value is in this EdgeCollection. + The Edge value to locate in this EdgeCollection. + true if value is found in this EdgeCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this EdgeCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this EdgeCollection + The Edge value to locate in the EdgeCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the EdgeCollection at the specified index + The index at which the Edge is to be inserted. + The Edge to insert. + + + Removes the first occurrence of a specific Edge from this EdgeCollection. + The Edge value to remove from this EdgeCollection. + + + Type-specific enumeration class, used by EdgeCollection.GetEnumerator. This class cannot be inherited. + + + The current element. + + + Moves cursor to next element. + true if current is valid, false otherwize + + + Resets the cursor to the position before the first element. + + + A collection of elements of type EdgeCollection This class cannot be inherited. + + + Gets or sets the EdgeCollection at the given index in this EdgeCollectionCollection. + + + Adds an instance of type EdgeCollection to the end of this EdgeCollectionCollection. + The EdgeCollection to be added to the end of this EdgeCollectionCollection. + + + Adds the elements of an array to the end of this EdgeCollectionCollection. + The array whose elements are to be added to the end of this EdgeCollectionCollection. + + + Adds the elements of another EdgeCollectionCollection to the end of this EdgeCollectionCollection. + The EdgeCollectionCollection whose elements are to be added to the end of this EdgeCollectionCollection. + + + Determines whether a specfic EdgeCollection value is in this EdgeCollectionCollection. + The EdgeCollection value to locate in this EdgeCollectionCollection. + true if value is found in this EdgeCollectionCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this EdgeCollectionCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this EdgeCollectionCollection + The EdgeCollection value to locate in the EdgeCollectionCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the EdgeCollectionCollection at the specified index + The index at which the EdgeCollection is to be inserted. + The EdgeCollection to insert. + + + Removes the first occurrence of a specific EdgeCollection from this EdgeCollectionCollection. + The EdgeCollection value to remove from this EdgeCollectionCollection. + + + Type-specific enumeration class, used by EdgeCollectionCollection.GetEnumerator. This class cannot be inherited. + + + Gets the current edge collection + Current edge collection + + + A dictionary with keys of type Edge and values of type GraphColor This class cannot be inherited. + + + Gets or sets the GraphColor associated with the given Edge + The Edge whose value to get or set. + + + Gets a collection containing the keys in this EdgeGraphColorDictionary. + + + Gets a collection containing the values in this EdgeGraphColorDictionary. + + + Adds an element with the specified key and value to this EdgeGraphColorDictionary. + The Edge key of the element to add. + The GraphColor value of the element to add. + + + Determines whether this EdgeGraphColorDictionary contains a specific key. + The Edge key to locate in this EdgeGraphColorDictionary. + true if this EdgeGraphColorDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeGraphColorDictionary contains a specific key. + The Edge key to locate in this EdgeGraphColorDictionary. + true if this EdgeGraphColorDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeGraphColorDictionary contains a specific value. + The GraphColor value to locate in this EdgeGraphColorDictionary. + true if this EdgeGraphColorDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this EdgeGraphColorDictionary. + The Edge key of the element to remove. + + + A dictionary with keys of type Edge and values of type Double This class cannot be inherited. + + + Gets or sets the Double associated with the given Edge + The Edge whose value to get or set. + + + Gets a collection containing the keys in this EdgeDoubleDictionary. + + + Gets a collection containing the values in this EdgeDoubleDictionary. + + + Adds an element with the specified key and value to this EdgeDoubleDictionary. + The Edge key of the element to add. + The Double value of the element to add. + + + Determines whether this EdgeDoubleDictionary contains a specific key. + The Edge key to locate in this EdgeDoubleDictionary. + true if this EdgeDoubleDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeDoubleDictionary contains a specific key. + The Edge key to locate in this EdgeDoubleDictionary. + true if this EdgeDoubleDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeDoubleDictionary contains a specific value. + The Double value to locate in this EdgeDoubleDictionary. + true if this EdgeDoubleDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this EdgeDoubleDictionary. + The Edge key of the element to remove. + + + A dictionary with keys of type IEdge and values of type IEdge This class cannot be inherited. + + + Gets or sets the IEdge associated with the given IEdge + The IEdge whose value to get or set. + + + Gets a collection containing the keys in this EdgeEdgeDictionary. + + + Gets a collection containing the values in this EdgeEdgeDictionary. + + + Adds an element with the specified key and value to this EdgeEdgeDictionary. + The IEdge key of the element to add. + The IEdge value of the element to add. + + + Determines whether this EdgeEdgeDictionary contains a specific key. + The IEdge key to locate in this EdgeEdgeDictionary. + true if this EdgeEdgeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeEdgeDictionary contains a specific key. + The IEdge key to locate in this EdgeEdgeDictionary. + true if this EdgeEdgeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeEdgeDictionary contains a specific value. + The IEdge value to locate in this EdgeEdgeDictionary. + true if this EdgeEdgeDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this EdgeEdgeDictionary. + The IEdge key of the element to remove. + + + A wrapper class for weak collection of IEdge This class cannot be inherited. + + + Wrapped enumerable + + + Return a strongly typed enumerator + strongly typed enumerator + + + Wraps up the weakly typed collection in a strongly typed (IEdge) collection. + Collection to wrap + Edge enumerable collection + + + Strongly typed enumerator + + + Current Edge + + + Wrapped enumerator + + + A dictionary with keys of type IEdge and values of type Int This class cannot be inherited. + + + Gets or sets the Int associated with the given IEdge + The IEdge whose value to get or set. + + + Gets a collection containing the keys in this EdgeIntDictionary. + + + Gets a collection containing the values in this EdgeIntDictionary. + + + Adds an element with the specified key and value to this EdgeIntDictionary. + The IEdge key of the element to add. + The Int value of the element to add. + + + Determines whether this EdgeIntDictionary contains a specific key. + The IEdge key to locate in this EdgeIntDictionary. + true if this EdgeIntDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeIntDictionary contains a specific key. + The IEdge key to locate in this EdgeIntDictionary. + true if this EdgeIntDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeIntDictionary contains a specific value. + The Int value to locate in this EdgeIntDictionary. + true if this EdgeIntDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this EdgeIntDictionary. + The IEdge key of the element to remove. + + + A dictionary with keys of type Edge and values of type Object This class cannot be inherited. + + + Gets or sets the Object associated with the given Edge + The Edge whose value to get or set. + + + Gets a collection containing the keys in this EdgeObjectDictionary. + + + Gets a collection containing the values in this EdgeObjectDictionary. + + + Adds an element with the specified key and value to this EdgeObjectDictionary. + The Edge key of the element to add. + The Object value of the element to add. + + + Determines whether this EdgeObjectDictionary contains a specific key. + The Edge key to locate in this EdgeObjectDictionary. + true if this EdgeObjectDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeObjectDictionary contains a specific key. + The Edge key to locate in this EdgeObjectDictionary. + true if this EdgeObjectDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeObjectDictionary contains a specific value. + The Object value to locate in this EdgeObjectDictionary. + true if this EdgeObjectDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this EdgeObjectDictionary. + The Edge key of the element to remove. + + + A dictionary with keys of type Edge and values of type String This class cannot be inherited. + + + Gets or sets the String associated with the given Edge + The Edge whose value to get or set. + + + Gets a collection containing the keys in this EdgeStringDictionary. + + + Gets a collection containing the values in this EdgeStringDictionary. + + + Adds an element with the specified key and value to this EdgeStringDictionary. + The Edge key of the element to add. + The String value of the element to add. + + + Determines whether this EdgeStringDictionary contains a specific key. + The Edge key to locate in this EdgeStringDictionary. + true if this EdgeStringDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeStringDictionary contains a specific key. + The Edge key to locate in this EdgeStringDictionary. + true if this EdgeStringDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this EdgeStringDictionary contains a specific value. + The String value to locate in this EdgeStringDictionary. + true if this EdgeStringDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this EdgeStringDictionary. + The Edge key of the element to remove. + + + Description résumée de FilteredEdgeCollection. This class cannot be inherited. + + + Base collection + + + Edge predicate + + + Returns the enumerator + + + Filetred enumerator class This class cannot be inherited. + + + Current edge + + + Moves the cursor to the next in-edge. + True if successful, false if the iteration ended. + + + Positions the cursor before the first element. + + + Filtered vertex collectiohn This class cannot be inherited. + + + Base collection + + + Predicate + + + Returns a filtered enumerator + enumerator + + + Filtered enumerator This class cannot be inherited. + + + Current Vertex + + + Moves the cursor to the next Vertex. + True if successful, false if the iteration ended. + + + Positions the cursor before the first element. + + + A Priorithized (with respect to distance) vertex buffer. This class cannot be inherited. + + + Push a new vertex on the buffer. + new vertex + + + Updates the buffer order + modified vertex + + + + + + Defines the == operator + + + + + + + + + A dictionary with keys of type String and values of type IEdge This class cannot be inherited. + + + Gets or sets the IEdge associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringEdgeDictionary. + + + Gets a collection containing the values in this StringEdgeDictionary. + + + Adds an element with the specified key and value to this StringEdgeDictionary. + The String key of the element to add. + The IEdge value of the element to add. + + + Determines whether this StringEdgeDictionary contains a specific key. + The String key to locate in this StringEdgeDictionary. + true if this StringEdgeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringEdgeDictionary contains a specific key. + The String key to locate in this StringEdgeDictionary. + true if this StringEdgeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringEdgeDictionary contains a specific value. + The IEdge value to locate in this StringEdgeDictionary. + true if this StringEdgeDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this StringEdgeDictionary. + The String key of the element to remove. + + + A dictionary with keys of type String and values of type IVertex This class cannot be inherited. + + + Gets or sets the IVertex associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringVertexDictionary. + + + Gets a collection containing the values in this StringVertexDictionary. + + + Adds an element with the specified key and value to this StringVertexDictionary. + The String key of the element to add. + The IVertex value of the element to add. + + + Determines whether this StringVertexDictionary contains a specific key. + The String key to locate in this StringVertexDictionary. + true if this StringVertexDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringVertexDictionary contains a specific key. + The String key to locate in this StringVertexDictionary. + true if this StringVertexDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringVertexDictionary contains a specific value. + The IVertex value to locate in this StringVertexDictionary. + true if this StringVertexDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this StringVertexDictionary. + The String key of the element to remove. + + + A vertex buffer that acts like a stack. + + + The number of vertices in the buffer + + + Returns an enumerator over the buffer + Buffer enumerator + + + Returns the latest vertex in the buffer. Leaves it in the buffer. + Latest vertex + + + Removes the latest vertex. + + + Pushes a new vertex at the end of the buffer: + Vertex to push + + + Sorts the buffer using the comparer + Comparer used to sort the buffer + + + A collection of elements of type Vertex This class cannot be inherited. + + + Gets or sets the Vertex at the given index in this VertexCollection. + + + Adds an instance of type Vertex to the end of this VertexCollection. + The Vertex to be added to the end of this VertexCollection. + + + Adds the elements of an array to the end of this VertexCollection. + The array whose elements are to be added to the end of this VertexCollection. + + + Adds the elements of another to the end of this VertexCollection. + The whose elements are to be added to the end of this VertexCollection. + + + Determines whether a specfic Vertex value is in this VertexCollection. + The Vertex value to locate in this VertexCollection. + true if value is found in this VertexCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this VertexCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this VertexCollection + The Vertex value to locate in the VertexCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the VertexCollection at the specified index + The index at which the Vertex is to be inserted. + The Vertex to insert. + + + Removes the first occurrence of a specific Vertex from this VertexCollection. + The Vertex value to remove from this VertexCollection. + + + Type-specific enumeration class, used by VertexCollection.GetEnumerator. This class cannot be inherited. + + + Current vertex + + + A dictionary with keys of type Vertex and values of type GraphColor This class cannot be inherited. + + + Gets or sets the GraphColor associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexColorDictionary. + + + Gets a collection containing the values in this VertexColorDictionary. + + + Adds an element with the specified key and value to this VertexColorDictionary. + The Vertex key of the element to add. + The GraphColor value of the element to add. + + + Determines whether this VertexColorDictionary contains a specific key. + The Vertex key to locate in this VertexColorDictionary. + true if this VertexColorDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexColorDictionary contains a specific key. + The Vertex key to locate in this VertexColorDictionary. + true if this VertexColorDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexColorDictionary contains a specific value. + The GraphColor value to locate in this VertexColorDictionary. + true if this VertexColorDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexColorDictionary. + The Vertex key of the element to remove. + + + A dictionary with keys of type Vertex and values of type Double This class cannot be inherited. + + + Gets or sets the Double associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexDistanceDictionary. + + + Gets a collection containing the values in this VertexDistanceDictionary. + + + Adds an element with the specified key and value to this VertexDistanceDictionary. + The Vertex key of the element to add. + The Double value of the element to add. + + + Determines whether this VertexDistanceDictionary contains a specific key. + The Vertex key to locate in this VertexDistanceDictionary. + true if this VertexDistanceDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexDistanceDictionary contains a specific key. + The Vertex key to locate in this VertexDistanceDictionary. + true if this VertexDistanceDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexDistanceDictionary contains a specific value. + The Double value to locate in this VertexDistanceDictionary. + true if this VertexDistanceDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexDistanceDictionary. + The Vertex key of the element to remove. + + + A dictionary with keys of type IVertex and values of type DoubleCollection + + + Gets or sets the DoubleCollection associated with the given IVertex + The IVertex whose value to get or set. + + + Gets a collection containing the keys in this VertexDoublesDictionary. + + + Gets a collection containing the values in this VertexDoublesDictionary. + + + Adds an element with the specified key and value to this VertexDoublesDictionary. + The IVertex key of the element to add. + The DoubleCollection value of the element to add. + + + Determines whether this VertexDoublesDictionary contains a specific key. + The IVertex key to locate in this VertexDoublesDictionary. + true if this VertexDoublesDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexDoublesDictionary contains a specific key. + The IVertex key to locate in this VertexDoublesDictionary. + true if this VertexDoublesDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexDoublesDictionary contains a specific value. + The DoubleCollection value to locate in this VertexDoublesDictionary. + true if this VertexDoublesDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexDoublesDictionary. + The IVertex key of the element to remove. + + + A dictionary with keys of type Vertex and values of type Edge This class cannot be inherited. + + + Gets or sets the Edge associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexEdgeDictionary. + + + Gets a collection containing the values in this VertexEdgeDictionary. + + + Adds an element with the specified key and value to this VertexEdgeDictionary. + The Vertex key of the element to add. + The Edge value of the element to add. + + + Determines whether this VertexEdgeDictionary contains a specific key. + The Vertex key to locate in this VertexEdgeDictionary. + true if this VertexEdgeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexEdgeDictionary contains a specific key. + The Vertex key to locate in this VertexEdgeDictionary. + true if this VertexEdgeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexEdgeDictionary contains a specific value. + The Edge value to locate in this VertexEdgeDictionary. + true if this VertexEdgeDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexEdgeDictionary. + The Vertex key of the element to remove. + + + A dictionary with keys of type Vertex and values of type EdgeCollection This class cannot be inherited. + + + Gets or sets the EdgeCollection associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexEdgesDictionary. + + + Gets a collection containing the values in this VertexEdgesDictionary. + + + Adds an element with the specified key and value to this VertexEdgesDictionary. + The Vertex key of the element to add. + The EdgeCollection value of the element to add. + + + Determines whether this VertexEdgesDictionary contains a specific key. + The Vertex key to locate in this VertexEdgesDictionary. + true if this VertexEdgesDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexEdgesDictionary contains a specific key. + The Vertex key to locate in this VertexEdgesDictionary. + true if this VertexEdgesDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexEdgesDictionary contains a specific value. + The EdgeCollection value to locate in this VertexEdgesDictionary. + true if this VertexEdgesDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexEdgesDictionary. + The Vertex key of the element to remove. + + + A simple IEnumerable class that provides an enumerator over the graph edges. This class cannot be inherited. + + + Provides an enumerator over the graph edges + An enumerator + + + An adaptor class to enumerate edges. This class cannot be inherited. + + + Gets the current element in the collection. + The enumerator is positioned before the first element of the collection or after the last element. + + + Advances the enumerator to the next element of the collection. + true if the enumerator was successfully advanced to the next edge; false if the enumerator has passed the end of the collection. + + + Move the vertex iterator to the next vertex. + + + Sets the enumerator to its initial position, which is before the first element in the collection. + + + A wrapper class for weak collection of IVertex This class cannot be inherited. + + + Wrapped enumerable + + + Return a strongly typed enumerator + strongly typed enumerator + + + Wraps up the weakly typed collection in a strongly typed (IVertex) collection. + Collection to wrap + vertex enumerable collection + + + Strongly typed enumerator This class cannot be inherited. + + + Current vertex + + + Wrapped enumerator + + + A dictionary with keys of type Vertex and values of type int This class cannot be inherited. + + + Gets or sets the int associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexIntDictionary. + + + Gets a collection containing the values in this VertexIntDictionary. + + + Adds an element with the specified key and value to this VertexIntDictionary. + The Vertex key of the element to add. + The int value of the element to add. + + + Determines whether this VertexIntDictionary contains a specific key. + The Vertex key to locate in this VertexIntDictionary. + true if this VertexIntDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexIntDictionary contains a specific key. + The Vertex key to locate in this VertexIntDictionary. + true if this VertexIntDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexIntDictionary contains a specific value. + The int value to locate in this VertexIntDictionary. + true if this VertexIntDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexIntDictionary. + The Vertex key of the element to remove. + + + A dictionary with keys of type Vertex and values of type Object This class cannot be inherited. + + + Gets or sets the Object associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexObjectDictionary. + + + Gets a collection containing the values in this VertexObjectDictionary. + + + Adds an element with the specified key and value to this VertexObjectDictionary. + The Vertex key of the element to add. + The Object value of the element to add. + + + Determines whether this VertexObjectDictionary contains a specific key. + The Vertex key to locate in this VertexObjectDictionary. + true if this VertexObjectDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexObjectDictionary contains a specific key. + The Vertex key to locate in this VertexObjectDictionary. + true if this VertexObjectDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexObjectDictionary contains a specific value. + The Object value to locate in this VertexObjectDictionary. + true if this VertexObjectDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexObjectDictionary. + The Vertex key of the element to remove. + + + A dictionary with keys of type VertexPair and values of type double This class cannot be inherited. + + + Gets or sets the double associated with the given VertexPair + The VertexPair whose value to get or set. + + + Returns + + + + + Gets a collection containing the keys in this VertexPairDoubleDictionary. + + + Gets a collection containing the values in this VertexPairDoubleDictionary. + + + Adds an element with the specified key and value to this VertexPairDoubleDictionary. + The VertexPair key of the element to add. + The double value of the element to add. + + + Determines whether this VertexPairDoubleDictionary contains a specific key. + The VertexPair key to locate in this VertexPairDoubleDictionary. + true if this VertexPairDoubleDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexPairDoubleDictionary contains a specific key. + The VertexPair key to locate in this VertexPairDoubleDictionary. + true if this VertexPairDoubleDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexPairDoubleDictionary contains a specific value. + The double value to locate in this VertexPairDoubleDictionary. + true if this VertexPairDoubleDictionary contains an element with the specified value; otherwise, false. + + + + + + + Removes the element with the specified key from this VertexPairDoubleDictionary. + The VertexPair key of the element to remove. + + + + + + + + A dictionary with keys of type IVertex and values of type PointF This class cannot be inherited. + + + Gets or sets the PointF associated with the given IVertex + The IVertex whose value to get or set. + + + Adds an element with the specified key and value to this VertexPointFDictionary. + The IVertex key of the element to add. + The PointF value of the element to add. + + + Determines whether this VertexPointFDictionary contains a specific key. + The IVertex key to locate in this VertexPointFDictionary. + true if this VertexPointFDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexPointFDictionary contains a specific key. + The IVertex key to locate in this VertexPointFDictionary. + true if this VertexPointFDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexPointFDictionary contains a specific value. + The PointF value to locate in this VertexPointFDictionary. + true if this VertexPointFDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexPointFDictionary. + The IVertex key of the element to remove. + + + A dictionary with keys of type IVertex and values of type Size This class cannot be inherited. + + + Gets or sets the Size associated with the given IVertex + The IVertex whose value to get or set. + + + Gets a collection containing the keys in this VertexSizeDictionary. + + + Gets a collection containing the values in this VertexSizeDictionary. + + + Adds an element with the specified key and value to this VertexSizeDictionary. + The IVertex key of the element to add. + The Size value of the element to add. + + + Determines whether this VertexSizeDictionary contains a specific key. + The IVertex key to locate in this VertexSizeDictionary. + true if this VertexSizeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexSizeDictionary contains a specific key. + The IVertex key to locate in this VertexSizeDictionary. + true if this VertexSizeDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexSizeDictionary contains a specific value. + The Size value to locate in this VertexSizeDictionary. + true if this VertexSizeDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexSizeDictionary. + The IVertex key of the element to remove. + + + A dictionary with keys of type Vertex and values of type String This class cannot be inherited. + + + Gets or sets the String associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexStringDictionary. + + + Gets a collection containing the values in this VertexStringDictionary. + + + Adds an element with the specified key and value to this VertexStringDictionary. + The Vertex key of the element to add. + The String value of the element to add. + + + Determines whether this VertexStringDictionary contains a specific key. + The Vertex key to locate in this VertexStringDictionary. + true if this VertexStringDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexStringDictionary contains a specific key. + The Vertex key to locate in this VertexStringDictionary. + true if this VertexStringDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexStringDictionary contains a specific value. + The String value to locate in this VertexStringDictionary. + true if this VertexStringDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexStringDictionary. + The Vertex key of the element to remove. + + + A dictionary with keys of type IVertex and values of type Vector2D This class cannot be inherited. + + + Gets or sets the Vector2D associated with the given IVertex + The IVertex whose value to get or set. + + + Gets a collection containing the keys in this VertexVector2DDictionary. + + + Gets a collection containing the values in this VertexVector2DDictionary. + + + Adds an element with the specified key and value to this VertexVector2DDictionary. + The IVertex key of the element to add. + The Vector2D value of the element to add. + + + Determines whether this VertexVector2DDictionary contains a specific key. + The IVertex key to locate in this VertexVector2DDictionary. + true if this VertexVector2DDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexVector2DDictionary contains a specific key. + The IVertex key to locate in this VertexVector2DDictionary. + true if this VertexVector2DDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexVector2DDictionary contains a specific value. + The Vector2D value to locate in this VertexVector2DDictionary. + true if this VertexVector2DDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexVector2DDictionary. + The IVertex key of the element to remove. + + + A dictionary with keys of type Vertex and values of type Vertex This class cannot be inherited. + + + Gets or sets the Vertex associated with the given Vertex + The Vertex whose value to get or set. + + + Gets a collection containing the keys in this VertexVertexDictionary. + + + Gets a collection containing the values in this VertexVertexDictionary. + + + Adds an element with the specified key and value to this VertexVertexDictionary. + The Vertex key of the element to add. + The Vertex value of the element to add. + + + Determines whether this VertexVertexDictionary contains a specific key. + The Vertex key to locate in this VertexVertexDictionary. + true if this VertexVertexDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexVertexDictionary contains a specific key. + The Vertex key to locate in this VertexVertexDictionary. + true if this VertexVertexDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this VertexVertexDictionary contains a specific value. + The Vertex value to locate in this VertexVertexDictionary. + true if this VertexVertexDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this VertexVertexDictionary. + The Vertex key of the element to remove. + + + A class containing a pair of . + + + Gets or sets the first instance + First instance. + set property, value is a null reference + + + Gets or sets the second instance + Second instance. + set property, value is a null reference + + + + + + A filtered adjacency graph + + + Filtered adjacency graph + + + Vertex predicate used to filter the vertices + + + Returns a filtered enumerable collection of adjacent vertices + + + + A filtered bidirectional graph + + + Underlying incidence graph + + + Gets a value indicating if the set of edges connected to v is empty + true if the adjacent edge set is empty, false otherwise. + v is a null reference + + + Vertex filtered degre + v to compute degree of + filtered degree + + + Returns the number of out-degree edges of v + vertex to test + out-degree + + + Returns an iterable collection of the out edges of v + + + Gets a value indicating if the set of in-edges is empty + true if the in-edge set is empty, false otherwise. + v is a null reference + + + A filtered IEdgeListAndIncidenceGraph. + + + Underlying incidence graph + + + Wrapped filtered edge list + + + Gets an enumerable collection of the v adjacent vertices + + + + Gets a value indicating if there is an edge between the vertices , . + source vertex + target vertex + true if (, ) exists. + u or v is a null reference + + + Returns the number of out-degree edges of v + vertex to test + out-degree + + + Returns an iterable collection of the out edges of v + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + A filtered edge list graph + + + Underlying incidence graph + + + Returns an iterable collection of filtered edges + + + Returns the number of filtered edges in the graph + number of edges + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the edge is part of the list. + edge to test + true if part of the list, false otherwize + e is a null reference + + + Base class for filtered graphs + + + True if underlying graph allows parallel edges + + + Edge predicate used to filter the edges + + + Underlying filtered graph + + + True if underlying graph in directed + + + Vertex predicate used to filter the vertices + + + A filtered incidence graph + + + Underlying incidence graph + + + Gets an enumerable collection of the v adjacent vertices + + + + Gets a value indicating if there is an edge between the vertices , . + source vertex + target vertex + true if (, ) exists. + u or v is a null reference + + + Returns the number of out-degree edges of v + vertex to test + out-degree + + + Returns an iterable collection of the out edges of v + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + A filtered edge list graph + + + Returns an iterable collection of filtered edges + + + Returns the number of filtered edges in the graph + number of edges + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Wrapped filtered edge list + + + Underlying incidence graph + + + + + + Underlying incidence graph + + + Filtered enumerable collection of vertices + + + Gets the filtered vertices count + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the vertex is part of the list. + vertex to test + true if part of the list, false otherwize + v is a null reference + + + Default object comparer. + + + + + + + Default swap class + + + Default swap operation + + + + + + http://www.codeproject.com/csharp/csquicksort.asp + + + Sorts the array. + The array to sort. + + + + + + + + Abstract base class for Swap sort algorithms. This class is and so cannot be instantiated. + + + Gets or sets the object + Comparer object + Set property, the value is a null reference + + + Gets or set the swapper object + The swapper. + Swapper is a null reference + + + + + + Sorts the . + + + + Object swapper interface + + + Swaps left and right in the list + + + + + + Event argument that contains two . + + + Edge passed to the event + + + Event argument that contains an . + + + Edge passed to the event + + + Utility class for graph color conversion This is a and so cannot be inherited or instantiated. + + + Converts GraphColor to System.Drawing.Color + graph color to convert + alpha component + corresponding Color + + + Converts GraphColor to System.Drawing.Color + graph color to convert + corresponding Color + + + Event argument that contains a . + + + Vertex passed to the event + + + Edge interface + + + Edge identification number + + + Source vertex + + + Target vertex + + + The Graph concept contains a few requirements that are common to all the graph concepts. + + + Parallel edge handling + + + Directed or undirected graph + True if directed graph + + + A port represents an anchor between an edge and a vertex + + + Port identification number + + + Gets or sets the parent vertex + The parent instance + + + The name of the port + + + An edge with ports attachement + + + Source vertex + + + Source port + + + Target vertex + + + Target port + + + A with . + + + Gets a collection of associated to the vertex + A of instance attached to the vertex + + + Vertex interface + + + Vertex unique identification number + + + Edge port enumeration + + + Unknown port + + + Lower left port + + + Lower right port + + + Upper left port + + + Upper right port + + + Middle left port + + + Middle right port + + + Middle top port + + + Middle bottom port + + + Colors used to mark the vertex and edges in the algorithms + + + White color, usually describes describes vertex. + + + Black color, usually describes finished vertex. + + + Gray color + + + Delegate that handles an edge that sends a vertex. + + + Delegate that handles an edge that sends a vertex. + + + Delegate that handles an event that sends a vertex. + + + IAlgorithm interface. + + + Visited graph object + + + Defines an algorithm that supports vertex distance recording. + + + Add event handlers to the corresponding events. + Distance recorder visitor + + + Edge colorzing algorithm + + + Edge color map + + + + + + Defines an algorithm that support edge predecessor recording. + + + Register the predecessor handlers + visitor + + + Defines an algorithm that support predecessor recording. + + + Register the predecessor handlers + visitor + + + Defines an algorithm that supports time stamping. + + + + + + An algorithm that implement TreeEdge event. + + + + + + Description résumée de IVertexColorizerAlgorithm. + + + Vertex color map + + + + + + An edge enumerable collection + + + Edge enumerable collection + + + An edge enumerator + + + Current edge + + + A collection of instance + + + + enumerable collection + + + Gets an instance + A instance. + + + An enumerator + + + Current + + + A vertex enumerable collection + + + + + + + + + + + + Edge enumerable collection + + + An edge enumerator + + + Current edge + + + + + + + + + + + + Description résumée de RandomGraph. This is a and so cannot be inherited or instantiated. + + + Picks an edge randomly in the edge list + edge list + random generator + randomaly chosen edge + + + + + + + + Generates a random graph + Graph to fill + number of vertices + number of edges + random generator + self edges allowed + + + Picks a vertex randomly in the vertex list + vertex list + random generator + randomaly chosen vertex + + + + + + + + Returns the vertex provider + + + Inserts the edge (u,v) into the graph, and returns the new edge. + + + Remove all edges to and from vertex u from the graph. + + + + Remove the edge (u,v) from the graph. If the graph allows parallel edges this remove all occurrences of (u,v). + source vertex + target vertex + + + Removes the edge e + edge to remove + Edge not found + + + Description résumée de IMutableBidirectionalGraph. + + + Remove all the in-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + Remove all the edges from graph g for which the predicate pred returns true. + edge predicate + + + Clears the graph. + + + Remove all the out-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + A mutable tree-like graph + + + Gets a value indicating if the tree allows cycles + true if it allows cycle, false otherwise + + + Adds a child vertex to the tree + parent vertex + created vertex + parent is a null reference + if AllowCycles is false and the edge creates a cycle + + + Removes vertex and sub-tree + vertex to remove + v is a null reference + Removing the vertex breaks the graph connectivity + + + Fusion of and . + + + Defines a graph that can be modified by adding or removing vertices. + + + Returns the vertex provider + + + Adds a new vertex to the graph. + new instance + + + Remove u from the vertex set of the graph. Note that undefined behavior may result if there are edges remaining in the graph who's target is u. Typically the ClearVertex function should be called first. + vertex to clear + u is a null reference + + + A fusion of , + + + Union of , + + + A directed edge of a net which may connect a to a or a to a . + + + Gets or sets a value indicating if the instance is a input arc. + + + Gets or sets the instance attached to the . + The attached to the . + set property, value is a null reference (Nothing in Visual Basic). + + + Gets or sets the instance attached to the . + The attached to the . + set property, value is a null reference (Nothing in Visual Basic). + + + A High Level Petri Graph. + + + Gets a collection of instances. + A collection of instances. + + + Gets a collection of instances. + A collection of instances. + + + Gets a collection of instances. + A collection of instances. + + + A vertex (node) of a Petri Graph. + + + Gets or sets the name of the node + A representing the name of the node. + + + A Place in the HLPN framework + + + A node of a net, taken from the transition kind. + + + A boolean expression associated with the transition + + + A predicate applied to an edge + + + Tests the predicate and returns the result + edge to test + true if successful + e is null + + + A predicate applied to a vertex + + + Tests the predicate and returns the result + Vertex to test + true if successful + v is null + + + A edge generator + + + The edge full type. + + + Returns an edge e=(u,v) + + + Updates edge that has not been created with the provider + vertex to update + + + A vertex generator object + + + The vertex full type. + + + Generates a new vertex + + + Updates a vertex that has not been created with the provider + vertex to update + + + Defines an instance that can be deserialized from a instance. + + + Reads data from serialization info + data holder + info is a null reference + info is serializing + + + A serializable graph structure (graph, vertex or edge) + + + Adds data to serialization info + data holder + info is null + info is not serializing + + + A class for adding and retreiving atomic data. + + + Get a value indicating if the object is serializing + true if serializing, false if deserializing + + + Gets or sets a value from a key + value identifier + value associated with the key. If the key is not present in the data, null value is returned + get,set property, key is a null reference + + + Adds a new key-value pair + value identifier + value + key is a null reference + + + Gets a value indicating if the key is in the entry collection + key to test + true if key is in the dictionary, false otherwise + key is a null reference + + + Adds an edge to the graph + edge to add + + + Union of the , and interfaces. + + + Add a vertex to the graph + vertex to add + + + A small helper class for traversals This is a and so cannot be inherited or instantiated. + + + Returns the first edge of the graph + graph + first edge if any, otherwise a null reference + + + Returns the first edge of the graph + graph + first edge if any, otherwise a null reference + + + Returns the first source vertex of the enumerable + enumerable collection of + first source vertex if any, otherwise a null reference + + + Returns the first vertex of the enumerable + enumerable collection of + first target vertex if any, otherwise a null reference + + + Returns the first vertex of the enumerable + enumerable collection of + first vertex if any, otherwise a null reference + + + Returns the first vertex of the graph + graph + first vertex if any, otherwise a null reference + + + Returns the first vertex of the enumerable that matches the predicate. + enumerable collection of + vertex predicate + first vertex if any, otherwise a null reference + + + Returns the last edge of the edge collection + edge collection + last edge if any, otherwise a null reference + + + Returns the last edge of the graph + graph + last edge if any, otherwise a null reference + + + Returns the last source vertex of the enumerable + enumerable collection of + last source vertex if any, otherwise a null reference + + + Returns the last vertex of the enumerable + enumerable collection of + last target vertex if any, otherwise a null reference + + + Returns the first vertex of the enumerable + enumerable collection of + first vertex if any, otherwise a null reference + + + Returns the last vertex of the graph + graph + last vertex if any, otherwise a null reference + + + AdjacentGraph concept + + + Returns a enumerable collection of adjacent vertices + + + Adds access to in-edges. + + + Gets a value indicating if the set of edges connected to v is empty + true if the adjacent edge set is empty, false otherwise. + v is a null reference + + + Returns the number of in-edges plus out-edges (for directed graphs) or the number of incident edges (for undirected graphs) of vertex v in graph g. + vertex to test + out-degree + + + Returns the number of in-edges (for directed graphs) or the number of incident edges (for undirected graphs) of vertex v in graph g. + vertex to test + out-degree + + + Enumerable collection of in-edges + + + Gets a value indicating if the set of in-edges is empty + true if the in-edge set is empty, false otherwise. + v is a null reference + + + A fusion of and . + + + A graph with clusters. + + + Gets an enumerable collection of . + + + Gets the number of clusters + + + Gets a value indicating wheter the cluster is collapsed + true if the cluster is colapsed; otherwize, false. + + + Adds a new cluster to the graph. + Added cluster + + + Removes a cluster from the graph + cluster to remove + g is null + + + Defines the union of EdgeListGraph and IncidenceListGraph. + + + The EdgeListGraph concept refines the Graph concept, and adds the requirement for efficient access to all the edges in the graph. + + + Returns an enumerator providing access to all the edges in the graph. + + + Returns the number of edges in the graph. + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the edge is part of the list. + edge to test + true if part of the list, false otherwize + e is a null reference + + + A bidirectional graph that supports filtered traversals + + + Returns the collection of in-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the first in-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + A edge list graph that supports filtered traversals + + + Returns the collection of edges that matches the predicate + Edge predicate + enumerable colleciton of vertices that matches the criteron + vp is null + + + Returns the first Edge that matches the predicate + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + vp is null + + + An incidence graph that supports filtered traversals + + + Returns the collection of out-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the first out-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + Union of , and . + + + A vertex list graph that supports filtered traversals + + + Returns the first vertex that matches the predicate + vertex predicate + null if not found, otherwize the first vertex that matches the predicate. + vp is null + + + Returns the collection of vertices that matches the predicate + vertex predicate + enumerable colleciton of vertices that matches the criteron + vp is null + + + A graph defined by a out-edges method. + + + Returns the out-degree edges of v + vertex to test + out-degree + + + Returns an iterable collection of the out edges of v + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference + + + Access to each vertex out-edges. + + + Gets a value indicating if there is an edge between the vertices , . + source vertex + target vertex + true if (, ) exists. + u or v is a null reference + + + A tree-like interface definition + + + Gets an enumerable collection of child + current + An enumerable collection of adjacent vertices + + is a null reference + + + Gets the first adjacent vertex + current vertex + first out-vertex + + is a null reference + + + Gets a value indicating if the has out-edges + + to test + true if has out-edges. + + is a null reference + + + + + is a null reference + + + Gets the parent. + current vertex + parent vertex if any, null reference otherwize + + is a null reference + + has multiple in-edges + + + Defines the union of VertexListGraph and EdgeListGraph. + + + The VertexListGraph concept refines the Graph concept, and adds the requirement for efficient traversal of all the vertices in the graph. + + + Gets an iterator-range providing access to all the vertices in the graph. + + collection over the instances of the graph. + + + Gets the number of in the graph. + The number of in the graph + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the vertex is part of the list. + vertex to test + true if part of the list, false otherwize + v is a null reference + + + A distance recorder visitor + + + + + + + + + + + + + + + + + + + + + + + + + + + Visitor that records the edge predecessor from a vertex. + + + Records edge predecessor + + + Records end path edges + + + + + Not used + + + + + Visitor that records the edge predecessor from a vertex. + + + Finished a vertex exploration + + + + + Predecessor record + + + + + Description résumée de ITimeStamperVisitior. + + + + + + + + + + + Tree edge visitor + + + + + + + A vertex colorizer visitor + + + + + + + + + + + + + + + Exception throwed when not finding a vertex. + + + Exception throwed when not finding a vertex. + + + Not a acyclic graph execption + + + Multiple In Edge exception + + + Negative cycle execption + + + Not a acyclic graph execption + + + ParrallelEdgeNotAllowedException. + + + Exception throwed when not finding a vertex. + + + Exception throwed when not finding a vertex. + + + A predicate that filter edge connecting two vertices + + + Test if edge connects source and target vertex + edge to test + true if e connects source and target + + + Edge predicate + + + Applies the edge predicate to e and to it's vertices? + edge to test + EdgePredicate(e) && VertexPredicate(e.Source) && VertexPredicate(e.Target) + e is null + + + Predicate for checking that a vertex is in a collection + + + Gets a value indicating if is in the collection. + vertex to test + true if is in the collection, false otherwize + + + Predicate for checking that a vertex is in a collection + + + Gets a value indicating if is in the collection. + vertex to test + true if is in the collection, false otherwize + + + In edge predicate + + + Applies the edge predicate to e and to it's source + edge to test + EdgePredicate(e) and VertexPredicate(e.Source) + e is null + + + Predicate that checks if a edge is an edge + + + + + + Predicate that checks if a edge is an inedge + + + + + + + + + Predicate that always returns true + + + Always returns true. + + + + Predicate that always returns true + + + Always returns true. + + + + An predicate that checks that the edge is not in both circuit and temporary circuit. + + + Edge circuit + + + Temporary circuit + + + Test method + + + + Not operator to predicate + + + + + + Out-edge predicate + + + Applies the edge predicate to e and to it's target vertex + edge to test + EdgePredicate(e) and VertexPredicate(e.Target) + e is null + + + Static helper class for creating predicates This is a and so cannot be inherited or instantiated. + + + + + + + + Checks ep(e) && vp(e.Source) && vp(e.Target) + predicate to apply to edge + predicate to apply to edge source and target + + + Check if a vertex is equal to v + vertex to test + predicate + + + Check if vertex is in list + + + + Creates a predicate that check the edge and the edge source + edge predicate to apply to the edge + vertex predicate to apply to the edge source + in-edge predicate + + + Creates a predicate that checks wheter an edge is adjacent to a given vertex. + vertex to test + is adjacent predicate + + + Creates a predicate that checks if an edge is an in-edge of a vertex. + vertex to check + in-edge predicate + + + Creates a predicate that checks if an edge is an out-edge of a vertex. + vertex to check + out-edge predicate + + + Returns a edge predicate that always returns true. + + + Returns a vertex predicate that always returns true. + + + Negates a predicate + + + + Creates a predicate that check the edge and the edge target + edge predicate to apply to the edge + vertex predicate to apply to the edge target + out-edge predicate + + + Source vertex prodicate + + + + Predicate that test if an edge is residual + + + Residual capacities map + + + Test if edge e has a positive residual capacity + edge to test + 0 < ResidualCapacities[e] + e is null + + + Predicate that test if an edge's reverse is residual + + + Residual capacities map + + + Reversed edges map + + + Test if edge e has a positive residual capacity + edge to test + 0 < ResidualCapacities[e] + e is null + + + A predicate to test if a is a root vertex (no in-edges). + + + Tests if the vertex is a root + vertex to test + true is the vertex has no in-edges, false otherwise + + + A predicate to test if a is a root vertex (no in-edges). + + + Tests if the vertex is a root + vertex to test + true is the vertex has no in-edges, false otherwise + + + Predicate that checks to two vertex are equal + + + Reference vertex + + + Test if v == u + vertex to test + v == u + + + Custom edge provider This class cannot be inherited. + + + Returns typeof(CustomEdge) + + + Creates a new edge + + + + + Updates an edge that has not been created with the provider + vertex to update + + + Default custom vertex provider This class cannot be inherited. + + + Returns typeof(CustomVertex) + + + Creates a new vertex + + + Updates a vertex that has not been created with the provider + vertex to update + + + Default edge provider This class cannot be inherited. + + + Edge type. + + + Creates a new edge + + + + + Updates an edge that has not been created with the provider + edge to update + + + Named edge provider This class cannot be inherited. + + + Returns typeof(NamedEdge) + + + Creates a new edge + + + + + Updates an edge that has not been created with the provider + edge to update + + + Default custom vertex provider This class cannot be inherited. + + + Returns typeof(NamedVertex) + + + Creates a new vertex + + + Updates a vertex that has not been created with the provider + vertex to update + + + Default custom edge provider + + + Returns typeof(CustomEdge) + + + Creates a new edge + + + Updates a edge that has not been created with the provider + edge to update + + + Default custom vertex provider + + + Returns typeof(CustomVertex) + + + Creates a new vertex + + + Updates a vertex that has not been created with the provider + vertex to update + + + Vertex provider This class cannot be inherited. + + + Vertex type. + + + Creates a new vertex + + + Updates a vertex that has not been created with the provider + vertex to update + + + Graph serializer to the GraphML format. + + + Serializes g to xml + xml writer + graph to serialize + writer or g are null + g vertex or edge does not implement . + + + Serializes the filtered graph g to xml + xml writer + "base" graph of g + graph to serialize + writer or g are null + g vertex or edge does not implement . + + + A data holder class + + + Number of key-value pair in the data bag. + + + True if serializing + + + Gets or sets a data entry in the graph info collection + set property,set a value while the graph info is deserializing + get property, the requested key is not found + + + Adds a new key-value pair + value identifier + value + key + + + Gets a value indicating if the key is in the data entries. + key to test + true if key is in the data collection, false otherwise + + + Base class for Graph serializers. This class is and so cannot be instantiated. + + + Created vertices table + + + Created vertices table + + + + + + + + + + Deserializes data from Xml stream. + xml stream + deserialized data + + + Formats the edge ID number + edge + e.ID formatted + + + Formats the vertex ID number + vertex + v.ID formatted + + + Returns qualifed type name of o + + + + + + + Moves reader to element with name = name + + + + + + + + + + + + Moves reader to element with name = name + + + + + + + + + + Parses edge id of the form 'edd' where dd is the id number + id identifier + id number + + + Parses vertex id of the form 'vdd' where dd is the id number + id identifier + id number + + + + + + Reads graph data and creates new graph instance + xml reader opened on graph data + created graph instance + + + Reads vertex or edge data + + + + + Serializes g to xml + xml writer + graph to serialize + writer or g are null + g vertex or edge does not implement . + + + Serializes the filtered graph g to xml + xml writer + "base" graph of g + graph to serialize + writer or g are null + g vertex or edge does not implement . + + + Writes a vertex element and it's custom data stored in info. + xml writer + edge to store + edge custom data + + + Closes the graph element. + xml writer + + + Create the graph element and stores graph level data. + xml writer + "base" graph of g + graph to serialize + + + Writes a vertex element and it's custom data stored in info. + xml writer + vertex to store + vertex custom data + + + Graph serializer to the GXL format. + + + + + + + + + + Reads graph data and creates new graph instance + xml reader opened on graph data + created graph instance + + + Reads custom info from GraphMl + xml reader + custom data + + + + + + + Reads vertex or edge data + + + + + Writes a vertex element and it's custom data stored in info. + xml writer + edge to store + edge custom data + + + Closes the graph element. + xml writer + + + Create the graph element and stores graph level data. + xml writer + "base" graph of g + graph to serialize + + + Writes custom info to GraphMl + xml writer + custom data + + + Writes a vertex element and it's custom data stored in info. + xml writer + vertex to store + vertex custom data + + + Gets the dictionary of key-and-value pairs + Data entries + + + Reads no data from serialization info + data holder + info is null + info is serializing + + + Adds nothing to serialization info + data holder + info is null + info is not serializing + + + Gets the dictionary of key-and-value pairs + Data entries + + + Reads no data from serialization info + data holder + info is null + info is serializing + + + Adds nothing to serialization info + data holder + info is null + info is not serializing + + + A wrapper for serializings graphs + + + Serialized graph + + + + + + + + + + + + + Reads graph data from Xml and create the graph object. + opened xml reader + deserialized graph + + + Serializes graph to xml. + + + + Serializes the graph to xml + opened xml writer + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/Readme.txt b/lib/Gallio_3.1.397.0/bin/MbUnit2/Readme.txt new file mode 100644 index 00000000..09a9d193 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/Readme.txt @@ -0,0 +1,9 @@ +MbUnit v2 Adapter Plugin +======================== + +This plugin uses the MbUnit v2 test runner to adapt MbUnit v2 tests so that +they can run within Gallio and be manipulated by Gallio-based tools. + +The plugin assembly is deliberately NOT signed using a strong name. +You can replace the underlying test framework with newer versions as +long as they are binary compatible with the originally distributed version. diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/Refly.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/Refly.dll new file mode 100644 index 00000000..c6eba39f Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/Refly.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/Refly.xml b/lib/Gallio_3.1.397.0/bin/MbUnit2/Refly.xml new file mode 100644 index 00000000..fbfe8e00 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/Refly.xml @@ -0,0 +1,1327 @@ + + + + Refly + + + + An attribute argument. + + + An attribute declaration + + + A collection of elements of type AttributeDeclaration + + + Adds an instance of type AttributeDeclaration to the end of this AttributeDeclarationCollection. + The AttributeDeclaration to be added to the end of this AttributeDeclarationCollection. + + + Determines whether a specfic AttributeDeclaration value is in this AttributeDeclarationCollection. + The AttributeDeclaration value to locate in this AttributeDeclarationCollection. + true if value is found in this AttributeDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this AttributeDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Inserts an element into the AttributeDeclarationCollection at the specified index + The index at which the AttributeDeclaration is to be inserted. + The AttributeDeclaration to insert. + + + Removes the first occurrence of a specific AttributeDeclaration from this AttributeDeclarationCollection. + The AttributeDeclaration value to remove from this AttributeDeclarationCollection. + + + Type-specific enumeration class, used by AttributeDeclarationCollection.GetEnumerator. + + + A class declaration + + + Gets or sets the output type. + A instance. + + + A class that controls the generation of code. + + + A constant value declaration. + + + A constructor declaration + + + Abstract base class for declarations. This class is and so cannot be instantiated. + + + A delegate declaration + + + A enum declaration + + + A event declaration. + + + Helper class containing static methods to create instances. This is a and so cannot be inherited or instantiated. + + + Create a base reference expression + + + Create a false expression + + + Create a null expression + + + Create a this reference expression + + + Create a true expression + + + Create a value reference expression of a set section inside a property + + + Creates a reference to a given argument + The instance to reference. + A instance referencing . + + is a null reference (Noting in Visual Basic) + + + Creates a case of the to the . + Target + + instance to case + A that will generate the cast. + + is a null reference (Noting in Visual Basic) + + + Creates a case of the to the . + Target + + instance to case + A that will generate the cast. + + is a null reference (Noting in Visual Basic) + + + Creates a case of the to the . + Target + + instance to case + A that will generate the cast. + + is a null reference (Noting in Visual Basic) + + + Creates a delegate constructr + The delegate type + The listener method + A representing the delegate creation. + + or is a null reference (Nothing in Visual Basic) + + + Creates a delegate constructr + The delegate type + The listener method + A representing the delegate creation. + + or is a null reference (Nothing in Visual Basic) + + + Creates a delegate constructr + The delegate type + The listener method + A representing the delegate creation. + + or is a null reference (Nothing in Visual Basic) + + + Creates a new type(...) expression. + Target name. + Parameters of the construcotr. + + is a null reference (Noting in Visual Basic) + + + Creates a new type(...) expression. + Target . + Parameters of the construcotr. + + is a null reference (Noting in Visual Basic) + + + Creates a new t(...) expression. + Target . + Parameters of the construcotr. + + is a null reference (Noting in Visual Basic) + + + Creates a new type[size] expression + Array item type + Array size + A instance + + is a null reference. + + + Creates a new type[size] expression + Array item type + Array size + A instance + + is a null reference. + + + Creates a new type[size] expression + Array item type + Array size + A instance + + is a null reference. + + + Creates a new type[expression] expression + Array item type + Array size + A instance + + or is a null reference. + + + Creates a new type[expression] expression + Array item type + Array size + A instance + + or is a null reference. + + + Creates a new type[expression] expression + Array item type + Array size + A instance + + or is a null reference. + + + Creates a new type[] { initializers } expression + Array item type + Array items + A instance + + is a null reference. + + + Creates a new type[] { initializers } expression + Array item type + Array items + A instance + + is a null reference. + + + Creates a new type[] { initializers } expression + Array item type + Array items + A instance + + is a null reference. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a primitive value. + + value to generate. + A instance that will generate the value. + + + Creates a snippet of code that will be outputed as such. + Snippet of code + A instance that will output the snippet. + + + Creates a reference expression to a given . + Target name + A that will generate the expression. + + is a null reference (Nothing in Visual Basic) + + + Creates a reference expression to a given . + Target name + A that will generate the expression. + + is a null reference (Nothing in Visual Basic) + + + Creates a reference expression to a given . + Target name + A that will generate the expression. + + is a null reference (Nothing in Visual Basic) + + + Creates a typeof(type) expression. + Target name. + A that will generate the expression. + + is a null reference (Nothing in Visual Basic) + + + Creates a typeof(type) expression. + Target + A that will generate the expression. + + is a null reference (Nothing in Visual Basic) + + + Creates a typeof(type) expression. + Target + A that will generate the expression. + + is a null reference (Nothing in Visual Basic) + + + Creates a reference to a given variable + The instance to reference. + A instance referencing . + + is a null reference (Noting in Visual Basic) + + + A field declaration + + + Abstract class for implementation members declarations. This class is and so cannot be instantiated. + + + A index declaration. + + + Abstract class for member declaration This class is and so cannot be instantiated. + + + A method declaration + + + A method signature + + + A namespace declaration + + + A parameter declaration + + + A property declaration + + + Helper containing static methods for creating statements. This is a and so cannot be inherited or instantiated. + + + Creates an assign statement: left = right + Left instance + Right instance + A instance. + + or is a null reference (Nothing in Visual Basic) + + + Helper static class for Type related tasks This class cannot be inherited. + + + Gets the first instance of from the type custom attributes. + type to test + custom attribute type to search + First instance of from the type custom attributes. + + or is a null reference + + is not tagged by an attribute of type + + + Gets the first instance of from the property custom attributes. + property to test + custom attribute type to search + First instance of from the property custom attributes. + + or is a null reference + + is not tagged by an attribute of type + + + Gets a value indicating if the type is tagged by a instance. + type to test + custom attribute type to search + true if is tagged by a attribute, false otherwise. + + or is a null reference + + + Gets a value indicating if the property info is tagged by a instance. + property to test + custom attribute type to search + true if is tagged by a attribute, false otherwise. + + or is a null reference + + + A type declaration. + + + Gets the type full name. + Type full name + + + Gets the type name. + Type name + + + Gets the + Corresponding instance. + + + Different possible output types + + + Generates a class + + + Generates a struct + + + Generates a class and it's interface + + + Generates the interface only + + + A collection of elements of type Assembly + + + Gets or sets the Assembly at the given index in this AssemblyCollection. + + + Adds an instance of type Assembly to the end of this AssemblyCollection. + The Assembly to be added to the end of this AssemblyCollection. + + + Adds the elements of an array to the end of this AssemblyCollection. + The array whose elements are to be added to the end of this AssemblyCollection. + + + Adds the elements of another AssemblyCollection to the end of this AssemblyCollection. + The AssemblyCollection whose elements are to be added to the end of this AssemblyCollection. + + + Determines whether a specfic Assembly value is in this AssemblyCollection. + The Assembly value to locate in this AssemblyCollection. + true if value is found in this AssemblyCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this AssemblyCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this AssemblyCollection + The Assembly value to locate in the AssemblyCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the AssemblyCollection at the specified index + The index at which the Assembly is to be inserted. + The Assembly to insert. + + + Removes the first occurrence of a specific Assembly from this AssemblyCollection. + The Assembly value to remove from this AssemblyCollection. + + + Type-specific enumeration class, used by AssemblyCollection.GetEnumerator. + + + A collection of elements of type CatchClause + + + Gets or sets the CatchClause at the given index in this CatchClauseCollection. + + + Adds an instance of type CatchClause to the end of this CatchClauseCollection. + The CatchClause to be added to the end of this CatchClauseCollection. + + + Adds the elements of an array to the end of this CatchClauseCollection. + The array whose elements are to be added to the end of this CatchClauseCollection. + + + Adds the elements of another CatchClauseCollection to the end of this CatchClauseCollection. + The CatchClauseCollection whose elements are to be added to the end of this CatchClauseCollection. + + + Determines whether a specfic CatchClause value is in this CatchClauseCollection. + The CatchClause value to locate in this CatchClauseCollection. + true if value is found in this CatchClauseCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this CatchClauseCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this CatchClauseCollection + The CatchClause value to locate in the CatchClauseCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the CatchClauseCollection at the specified index + The index at which the CatchClause is to be inserted. + The CatchClause to insert. + + + Removes the first occurrence of a specific CatchClause from this CatchClauseCollection. + The CatchClause value to remove from this CatchClauseCollection. + + + Type-specific enumeration class, used by CatchClauseCollection.GetEnumerator. + + + A collection of elements of type ConstructorDeclaration + + + Gets or sets the ConstructorDeclaration at the given index in this ConstructorDeclarationCollection. + + + Adds an instance of type ConstructorDeclaration to the end of this ConstructorDeclarationCollection. + The ConstructorDeclaration to be added to the end of this ConstructorDeclarationCollection. + + + Adds the elements of an array to the end of this ConstructorDeclarationCollection. + The array whose elements are to be added to the end of this ConstructorDeclarationCollection. + + + Adds the elements of another ConstructorDeclarationCollection to the end of this ConstructorDeclarationCollection. + The ConstructorDeclarationCollection whose elements are to be added to the end of this ConstructorDeclarationCollection. + + + Determines whether a specfic ConstructorDeclaration value is in this ConstructorDeclarationCollection. + The ConstructorDeclaration value to locate in this ConstructorDeclarationCollection. + true if value is found in this ConstructorDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this ConstructorDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this ConstructorDeclarationCollection + The ConstructorDeclaration value to locate in the ConstructorDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the ConstructorDeclarationCollection at the specified index + The index at which the ConstructorDeclaration is to be inserted. + The ConstructorDeclaration to insert. + + + Removes the first occurrence of a specific ConstructorDeclaration from this ConstructorDeclarationCollection. + The ConstructorDeclaration value to remove from this ConstructorDeclarationCollection. + + + Type-specific enumeration class, used by ConstructorDeclarationCollection.GetEnumerator. + + + A collection of elements of type DelegateDeclaration + + + Gets or sets the DelegateDeclaration at the given index in this DelegateDeclarationCollection. + + + Gets or sets the DelegateDeclaration with the given name in this DelegateDeclarationCollection. + + + Adds an instance of type DelegateDeclaration to the end of this DelegateDeclarationCollection. + The DelegateDeclaration to be added to the end of this DelegateDeclarationCollection. + + + Adds the elements of an array to the end of this DelegateDeclarationCollection. + The array whose elements are to be added to the end of this DelegateDeclarationCollection. + + + Adds the elements of another DelegateDeclarationCollection to the end of this DelegateDeclarationCollection. + The DelegateDeclarationCollection whose elements are to be added to the end of this DelegateDeclarationCollection. + + + Determines whether a specfic DelegateDeclaration value is in this DelegateDeclarationCollection. + The DelegateDeclaration value to locate in this DelegateDeclarationCollection. + true if value is found in this DelegateDeclarationCollection; false otherwise. + + + Checks the existence of a method name. + + + + Returns an enumerator that can iterate through the elements of this DelegateDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this DelegateDeclarationCollection + The DelegateDeclaration value to locate in the DelegateDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the DelegateDeclarationCollection at the specified index + The index at which the DelegateDeclaration is to be inserted. + The DelegateDeclaration to insert. + + + Removes the first occurrence of a specific DelegateDeclaration from this DelegateDeclarationCollection. + The DelegateDeclaration value to remove from this DelegateDeclarationCollection. + + + Type-specific enumeration class, used by DelegateDeclarationCollection.GetEnumerator. + + + A collection of elements of type EventDeclaration + + + Gets or sets the EventDeclaration at the given index in this EventDeclarationCollection. + + + Adds an instance of type EventDeclaration to the end of this EventDeclarationCollection. + The EventDeclaration to be added to the end of this EventDeclarationCollection. + + + Adds the elements of an array to the end of this EventDeclarationCollection. + The array whose elements are to be added to the end of this EventDeclarationCollection. + + + Adds the elements of another EventDeclarationCollection to the end of this EventDeclarationCollection. + The EventDeclarationCollection whose elements are to be added to the end of this EventDeclarationCollection. + + + Determines whether a specfic EventDeclaration value is in this EventDeclarationCollection. + The EventDeclaration value to locate in this EventDeclarationCollection. + true if value is found in this EventDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this EventDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this EventDeclarationCollection + The EventDeclaration value to locate in the EventDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the EventDeclarationCollection at the specified index + The index at which the EventDeclaration is to be inserted. + The EventDeclaration to insert. + + + Removes the first occurrence of a specific EventDeclaration from this EventDeclarationCollection. + The EventDeclaration value to remove from this EventDeclarationCollection. + + + Type-specific enumeration class, used by EventDeclarationCollection.GetEnumerator. + + + A collection of elements of type Expression + + + Adds an instance of type Expression to the end of this ExpressionCollection. + The Expression to be added to the end of this ExpressionCollection. + + + Adds the elements of an array to the end of this ExpressionCollection. + The array whose elements are to be added to the end of this ExpressionCollection. + + + Adds the elements of another ExpressionCollection to the end of this ExpressionCollection. + The ExpressionCollection whose elements are to be added to the end of this ExpressionCollection. + + + Returns an enumerator that can iterate through the elements of this ExpressionCollection. + An object that implements System.Collections.IEnumerator. + + + Type-specific enumeration class, used by ExpressionCollection.GetEnumerator. + + + A collection of elements of type FieldDeclaration + + + Gets or sets the FieldDeclaration at the given index in this FieldDeclarationCollection. + + + Adds an instance of type FieldDeclaration to the end of this FieldDeclarationCollection. + The FieldDeclaration to be added to the end of this FieldDeclarationCollection. + + + Adds the elements of an array to the end of this FieldDeclarationCollection. + The array whose elements are to be added to the end of this FieldDeclarationCollection. + + + Adds the elements of another FieldDeclarationCollection to the end of this FieldDeclarationCollection. + The FieldDeclarationCollection whose elements are to be added to the end of this FieldDeclarationCollection. + + + Determines whether a specfic FieldDeclaration value is in this FieldDeclarationCollection. + The FieldDeclaration value to locate in this FieldDeclarationCollection. + true if value is found in this FieldDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this FieldDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this FieldDeclarationCollection + The FieldDeclaration value to locate in the FieldDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the FieldDeclarationCollection at the specified index + The index at which the FieldDeclaration is to be inserted. + The FieldDeclaration to insert. + + + Removes the first occurrence of a specific FieldDeclaration from this FieldDeclarationCollection. + The FieldDeclaration value to remove from this FieldDeclarationCollection. + + + Type-specific enumeration class, used by FieldDeclarationCollection.GetEnumerator. + + + A collection of elements of type IndexerDeclaration + + + Gets or sets the IndexerDeclaration at the given index in this IndexerDeclarationCollection. + + + Adds an instance of type IndexerDeclaration to the end of this IndexerDeclarationCollection. + The IndexerDeclaration to be added to the end of this IndexerDeclarationCollection. + + + Adds the elements of an array to the end of this IndexerDeclarationCollection. + The array whose elements are to be added to the end of this IndexerDeclarationCollection. + + + Adds the elements of another IndexerDeclarationCollection to the end of this IndexerDeclarationCollection. + The IndexerDeclarationCollection whose elements are to be added to the end of this IndexerDeclarationCollection. + + + Determines whether a specfic IndexerDeclaration value is in this IndexerDeclarationCollection. + The IndexerDeclaration value to locate in this IndexerDeclarationCollection. + true if value is found in this IndexerDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this IndexerDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this IndexerDeclarationCollection + The IndexerDeclaration value to locate in the IndexerDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the IndexerDeclarationCollection at the specified index + The index at which the IndexerDeclaration is to be inserted. + The IndexerDeclaration to insert. + + + Removes the first occurrence of a specific IndexerDeclaration from this IndexerDeclarationCollection. + The IndexerDeclaration value to remove from this IndexerDeclarationCollection. + + + Type-specific enumeration class, used by IndexerDeclarationCollection.GetEnumerator. + + + A collection of elements of type MethodDeclaration + + + Gets or sets the MethodDeclaration at the given index in this MethodDeclarationCollection. + + + Gets or sets the MethodDeclaration with the given name in this MethodDeclarationCollection. + + + Adds an instance of type MethodDeclaration to the end of this MethodDeclarationCollection. + The MethodDeclaration to be added to the end of this MethodDeclarationCollection. + + + Adds the elements of an array to the end of this MethodDeclarationCollection. + The array whose elements are to be added to the end of this MethodDeclarationCollection. + + + Adds the elements of another MethodDeclarationCollection to the end of this MethodDeclarationCollection. + The MethodDeclarationCollection whose elements are to be added to the end of this MethodDeclarationCollection. + + + Determines whether a specfic MethodDeclaration value is in this MethodDeclarationCollection. + The MethodDeclaration value to locate in this MethodDeclarationCollection. + true if value is found in this MethodDeclarationCollection; false otherwise. + + + Checks the existence of a method name. + + + + Returns an enumerator that can iterate through the elements of this MethodDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this MethodDeclarationCollection + The MethodDeclaration value to locate in the MethodDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the MethodDeclarationCollection at the specified index + The index at which the MethodDeclaration is to be inserted. + The MethodDeclaration to insert. + + + Removes the first occurrence of a specific MethodDeclaration from this MethodDeclarationCollection. + The MethodDeclaration value to remove from this MethodDeclarationCollection. + + + Type-specific enumeration class, used by MethodDeclarationCollection.GetEnumerator. + + + A collection of elements of type ParameterDeclaration + + + Gets or sets the ParameterDeclaration at the given index in this ParameterDeclarationCollection. + + + Adds the elements of an array to the end of this ParameterDeclarationCollection. + The array whose elements are to be added to the end of this ParameterDeclarationCollection. + + + Adds the elements of another ParameterDeclarationCollection to the end of this ParameterDeclarationCollection. + The ParameterDeclarationCollection whose elements are to be added to the end of this ParameterDeclarationCollection. + + + Determines whether a specfic ParameterDeclaration value is in this ParameterDeclarationCollection. + The ParameterDeclaration value to locate in this ParameterDeclarationCollection. + true if value is found in this ParameterDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this ParameterDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this ParameterDeclarationCollection + The ParameterDeclaration value to locate in the ParameterDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the ParameterDeclarationCollection at the specified index + The index at which the ParameterDeclaration is to be inserted. + The ParameterDeclaration to insert. + + + Removes the first occurrence of a specific ParameterDeclaration from this ParameterDeclarationCollection. + The ParameterDeclaration value to remove from this ParameterDeclarationCollection. + + + Type-specific enumeration class, used by ParameterDeclarationCollection.GetEnumerator. + + + A collection of elements of type PropertyDeclaration + + + Gets or sets the PropertyDeclaration at the given index in this PropertyDeclarationCollection. + + + Adds an instance of type PropertyDeclaration to the end of this PropertyDeclarationCollection. + The PropertyDeclaration to be added to the end of this PropertyDeclarationCollection. + + + Adds the elements of an array to the end of this PropertyDeclarationCollection. + The array whose elements are to be added to the end of this PropertyDeclarationCollection. + + + Adds the elements of another PropertyDeclarationCollection to the end of this PropertyDeclarationCollection. + The PropertyDeclarationCollection whose elements are to be added to the end of this PropertyDeclarationCollection. + + + Determines whether a specfic PropertyDeclaration value is in this PropertyDeclarationCollection. + The PropertyDeclaration value to locate in this PropertyDeclarationCollection. + true if value is found in this PropertyDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this PropertyDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this PropertyDeclarationCollection + The PropertyDeclaration value to locate in the PropertyDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the PropertyDeclarationCollection at the specified index + The index at which the PropertyDeclaration is to be inserted. + The PropertyDeclaration to insert. + + + Removes the first occurrence of a specific PropertyDeclaration from this PropertyDeclarationCollection. + The PropertyDeclaration value to remove from this PropertyDeclarationCollection. + + + Type-specific enumeration class, used by PropertyDeclarationCollection.GetEnumerator. + + + A collection of elements of type Statement + + + Adds an instance of type Statement to the end of this StatementCollection. + The Statement to be added to the end of this StatementCollection. + + + Adds the elements of an array to the end of this StatementCollection. + The array whose elements are to be added to the end of this StatementCollection. + + + Adds the elements of another StatementCollection to the end of this StatementCollection. + The StatementCollection whose elements are to be added to the end of this StatementCollection. + + + Returns an enumerator that can iterate through the elements of this StatementCollection. + An object that implements System.Collections.IEnumerator. + + + Type-specific enumeration class, used by StatementCollection.GetEnumerator. + + + A dictionary with keys of type string and values of type AttributeArgument + + + Gets or sets the AttributeArgument associated with the given string + The string whose value to get or set. + + + Gets a collection containing the keys in this StringAttributeArgumentDictionary. + + + Gets a collection containing the values in this StringAttributeArgumentDictionary. + + + Adds an element with the specified key and value to this StringAttributeArgumentDictionary. + The string key of the element to add. + The AttributeArgument value of the element to add. + + + Determines whether this StringAttributeArgumentDictionary contains a specific key. + The string key to locate in this StringAttributeArgumentDictionary. + true if this StringAttributeArgumentDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringAttributeArgumentDictionary contains a specific key. + The string key to locate in this StringAttributeArgumentDictionary. + true if this StringAttributeArgumentDictionary contains an element with the specified key; otherwise, false. + + + Removes the element with the specified key from this StringAttributeArgumentDictionary. + The string key of the element to remove. + + + A dictionary with keys of type String and values of type ClassDeclaration + + + Gets or sets the ClassDeclaration associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringClassDeclarationDictionary. + + + Gets a collection containing the values in this StringClassDeclarationDictionary. + + + Adds an element with the specified key and value to this StringClassDeclarationDictionary. + The String key of the element to add. + The ClassDeclaration value of the element to add. + + + Determines whether this StringClassDeclarationDictionary contains a specific key. + The String key to locate in this StringClassDeclarationDictionary. + true if this StringClassDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringClassDeclarationDictionary contains a specific key. + The String key to locate in this StringClassDeclarationDictionary. + true if this StringClassDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringClassDeclarationDictionary contains a specific value. + The ClassDeclaration value to locate in this StringClassDeclarationDictionary. + true if this StringClassDeclarationDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this StringClassDeclarationDictionary. + The String key of the element to remove. + + + A dictionary with keys of type String and values of type ConstantDeclaration + + + Gets or sets the ConstantDeclaration associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringConstantDeclaration. + + + Gets a collection containing the values in this StringConstantDeclaration. + + + Adds an element with the specified key and value to this StringConstantDeclaration. + The String key of the element to add. + The ConstantDeclaration value of the element to add. + + + Determines whether this StringConstantDeclaration contains a specific key. + The String key to locate in this StringConstantDeclaration. + true if this StringConstantDeclaration contains an element with the specified key; otherwise, false. + + + Removes the element with the specified key from this StringConstantDeclaration. + The String key of the element to remove. + + + A dictionary with keys of type String and values of type EnumDeclaration + + + Gets or sets the EnumDeclaration associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringEnumDeclarationDictionary. + + + Gets a collection containing the values in this StringEnumDeclarationDictionary. + + + Adds an element with the specified key and value to this StringEnumDeclarationDictionary. + The String key of the element to add. + The EnumDeclaration value of the element to add. + + + Determines whether this StringEnumDeclarationDictionary contains a specific key. + The String key to locate in this StringEnumDeclarationDictionary. + true if this StringEnumDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringEnumDeclarationDictionary contains a specific key. + The String key to locate in this StringEnumDeclarationDictionary. + true if this StringEnumDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringEnumDeclarationDictionary contains a specific value. + The EnumDeclaration value to locate in this StringEnumDeclarationDictionary. + true if this StringEnumDeclarationDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this StringEnumDeclarationDictionary. + The String key of the element to remove. + + + A dictionary with keys of type String and values of type FieldDeclaration + + + Gets or sets the FieldDeclaration associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringFieldDeclarationDictionary. + + + Gets a collection containing the values in this StringFieldDeclarationDictionary. + + + Adds an element with the specified key and value to this StringFieldDeclarationDictionary. + The String key of the element to add. + The FieldDeclaration value of the element to add. + + + Determines whether this StringFieldDeclarationDictionary contains a specific key. + The String key to locate in this StringFieldDeclarationDictionary. + true if this StringFieldDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringFieldDeclarationDictionary contains a specific key. + The String key to locate in this StringFieldDeclarationDictionary. + true if this StringFieldDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringFieldDeclarationDictionary contains a specific value. + The FieldDeclaration value to locate in this StringFieldDeclarationDictionary. + true if this StringFieldDeclarationDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this StringFieldDeclarationDictionary. + The String key of the element to remove. + + + A dictionary with keys of type String and values of type NamespaceDeclaration + + + Gets or sets the NamespaceDeclaration associated with the given String + The String whose value to get or set. + + + Gets a collection containing the keys in this StringNamespaceDeclarationDictionary. + + + Gets a collection containing the values in this StringNamespaceDeclarationDictionary. + + + Adds an element with the specified key and value to this StringNamespaceDeclarationDictionary. + The String key of the element to add. + The NamespaceDeclaration value of the element to add. + + + Determines whether this StringNamespaceDeclarationDictionary contains a specific key. + The String key to locate in this StringNamespaceDeclarationDictionary. + true if this StringNamespaceDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringNamespaceDeclarationDictionary contains a specific key. + The String key to locate in this StringNamespaceDeclarationDictionary. + true if this StringNamespaceDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this StringNamespaceDeclarationDictionary contains a specific value. + The NamespaceDeclaration value to locate in this StringNamespaceDeclarationDictionary. + true if this StringNamespaceDeclarationDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this StringNamespaceDeclarationDictionary. + The String key of the element to remove. + + + A collection of elements of type ThrowedExceptionDeclaration + + + Gets or sets the ThrowedExceptionDeclaration at the given index in this ThrowedExceptionDeclarationCollection. + + + Adds an instance of type ThrowedExceptionDeclaration to the end of this ThrowedExceptionDeclarationCollection. + The ThrowedExceptionDeclaration to be added to the end of this ThrowedExceptionDeclarationCollection. + + + Adds the elements of an array to the end of this ThrowedExceptionDeclarationCollection. + The array whose elements are to be added to the end of this ThrowedExceptionDeclarationCollection. + + + Adds the elements of another ThrowedExceptionDeclarationCollection to the end of this ThrowedExceptionDeclarationCollection. + The ThrowedExceptionDeclarationCollection whose elements are to be added to the end of this ThrowedExceptionDeclarationCollection. + + + Determines whether a specfic ThrowedExceptionDeclaration value is in this ThrowedExceptionDeclarationCollection. + The ThrowedExceptionDeclaration value to locate in this ThrowedExceptionDeclarationCollection. + true if value is found in this ThrowedExceptionDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this ThrowedExceptionDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this ThrowedExceptionDeclarationCollection + The ThrowedExceptionDeclaration value to locate in the ThrowedExceptionDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the ThrowedExceptionDeclarationCollection at the specified index + The index at which the ThrowedExceptionDeclaration is to be inserted. + The ThrowedExceptionDeclaration to insert. + + + Removes the first occurrence of a specific ThrowedExceptionDeclaration from this ThrowedExceptionDeclarationCollection. + The ThrowedExceptionDeclaration value to remove from this ThrowedExceptionDeclarationCollection. + + + Type-specific enumeration class, used by ThrowedExceptionDeclarationCollection.GetEnumerator. + + + A collection of elements of type Type + + + Gets or sets the Type at the given index in this TypeCollection. + + + Adds an instance of type Type to the end of this TypeCollection. + The Type to be added to the end of this TypeCollection. + + + Adds the elements of an array to the end of this TypeCollection. + The array whose elements are to be added to the end of this TypeCollection. + + + Adds the elements of another TypeCollection to the end of this TypeCollection. + The TypeCollection whose elements are to be added to the end of this TypeCollection. + + + Determines whether a specfic Type value is in this TypeCollection. + The Type value to locate in this TypeCollection. + true if value is found in this TypeCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this TypeCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this TypeCollection + The Type value to locate in the TypeCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the TypeCollection at the specified index + The index at which the Type is to be inserted. + The Type to insert. + + + Removes the first occurrence of a specific Type from this TypeCollection. + The Type value to remove from this TypeCollection. + + + Type-specific enumeration class, used by TypeCollection.GetEnumerator. + + + A collection of elements of type ITypeDeclaration + + + Gets or sets the ITypeDeclaration at the given index in this TypeDeclarationCollection. + + + Adds an instance of type ITypeDeclaration to the end of this TypeDeclarationCollection. + The ITypeDeclaration to be added to the end of this TypeDeclarationCollection. + + + Adds the elements of an array to the end of this TypeDeclarationCollection. + The array whose elements are to be added to the end of this TypeDeclarationCollection. + + + Adds the elements of another TypeDeclarationCollection to the end of this TypeDeclarationCollection. + The TypeDeclarationCollection whose elements are to be added to the end of this TypeDeclarationCollection. + + + Determines whether a specfic ITypeDeclaration value is in this TypeDeclarationCollection. + The ITypeDeclaration value to locate in this TypeDeclarationCollection. + true if value is found in this TypeDeclarationCollection; false otherwise. + + + Returns an enumerator that can iterate through the elements of this TypeDeclarationCollection. + An object that implements System.Collections.IEnumerator. + + + Return the zero-based index of the first occurrence of a specific value in this TypeDeclarationCollection + The ITypeDeclaration value to locate in the TypeDeclarationCollection. + The zero-based index of the first occurrence of the _ELEMENT value if found; -1 otherwise. + + + Inserts an element into the TypeDeclarationCollection at the specified index + The index at which the ITypeDeclaration is to be inserted. + The ITypeDeclaration to insert. + + + Removes the first occurrence of a specific ITypeDeclaration from this TypeDeclarationCollection. + The ITypeDeclaration value to remove from this TypeDeclarationCollection. + + + Type-specific enumeration class, used by TypeDeclarationCollection.GetEnumerator. + + + A dictionary with keys of type Type and values of type ITypeDeclaration + + + Gets or sets the ITypeDeclaration associated with the given Type + The Type whose value to get or set. + + + Gets a collection containing the keys in this TypeTypeDeclarationDictionary. + + + Gets a collection containing the values in this TypeTypeDeclarationDictionary. + + + Adds an element with the specified key and value to this TypeTypeDeclarationDictionary. + The Type key of the element to add. + The ITypeDeclaration value of the element to add. + + + Determines whether this TypeTypeDeclarationDictionary contains a specific key. + The Type key to locate in this TypeTypeDeclarationDictionary. + true if this TypeTypeDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this TypeTypeDeclarationDictionary contains a specific key. + The Type key to locate in this TypeTypeDeclarationDictionary. + true if this TypeTypeDeclarationDictionary contains an element with the specified key; otherwise, false. + + + Determines whether this TypeTypeDeclarationDictionary contains a specific value. + The ITypeDeclaration value to locate in this TypeTypeDeclarationDictionary. + true if this TypeTypeDeclarationDictionary contains an element with the specified value; otherwise, false. + + + Removes the element with the specified key from this TypeTypeDeclarationDictionary. + The Type key of the element to remove. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/Resources/MbUnit.ico b/lib/Gallio_3.1.397.0/bin/MbUnit2/Resources/MbUnit.ico new file mode 100644 index 00000000..71926959 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/Resources/MbUnit.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/TestFu.dll b/lib/Gallio_3.1.397.0/bin/MbUnit2/TestFu.dll new file mode 100644 index 00000000..229932e9 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit2/TestFu.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit2/TestFu.xml b/lib/Gallio_3.1.397.0/bin/MbUnit2/TestFu.xml new file mode 100644 index 00000000..515cec83 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit2/TestFu.xml @@ -0,0 +1,1932 @@ + + + + TestFu + + + + Abstract class to perform administrative tasks on a database This class is and so cannot be instantiated. + + + Gets or sets the connection string with Initial Catalog information + Connection string. + + + Gets the connection string with Initial Catalog information. + Connection string with Initial catalog information. + + + Gets or sets the database name + The database name. + + + Gets or sets the database owner. + Database owner name. + + + Creates a backup of the specified database using the specified and . + A defining the type of output device. + Device path. + + is a null reference (Nothing in Visual Basic) + + + Gets a value indicating if the current database exists. + true if it exists; otherwise, false. + + + Gets a value indicating if the database contains the table. + Name of the table to search + true if a table named is contained in the databse;oterwise false. + + + Creates a new database on the server + + + Drops an existing new database on the server + + is a null reference (Nothing in Visual Basic) + + + Drops the table. + Name of the table to drop + + + Executes a non-query in a safe, transactional environement. + The connection string. + Query to execute. + Optional arguments. + + + Restores a backup of the specified database using the specified and . + A defining the type of output device. + Device path. + + is a null reference (Nothing in Visual Basic) + + + An abstract base class for test fixtures involving database testing. This class is and so cannot be instantiated. + + + Gets the database instance + A instance. + + + Gets the current connection instance. + + instance. + + + Gets the connection string to access the db server (without database information. + + + Gets the connection string to connecto the test database. + + + Gets the test database name. + + + Gets the current transaction. + A instance if was called and the connection not closed; otherwise, a null reference (Nothing in Visual Basic) + + + Begins a new transaction. + The current connection is not created or not opened. + + + Closes the current connection. + + + Commits the current transaction if any. + + + Executes a non-query command with the given parameters + Query format string + Query arguments for the format string + Number of affected rows + + + Executes query and returns the instance + Query format string + Query arguments for the format string + A resulting from the query. + + + Executes a scalar query with the given parameters + Query format string + Query arguments for the format string + Query result + + + Opens a instance with the . + + + Rollsback the current transaction if any. + + + A validator check checks constraints + + + Preprocesses the row modifies it to fullfill the constraint + + + + A database populator instance. + + + Gets the instance associated to this populator. + A schema used to set-up the generators. + + + Gets the associated to the database. + + + Gets a collection associated to each table. + A containing populator associated to each . + + + Sets up the generators for the given instance. + A representing the structure of the database to populate. + + is a null reference (Nothing in Visual Basic) + + + An random data generator. + + + Gets the target column + Target instance. + + + Gets the generated type + Generated . + + + Gets or sets the probability to produce a NULL + The probability to produce a null object. + + + Generates a new value and fills it in the corresponding . + + + Resets the generator + + + A collection of . + + + Gets the associated to the . + + is a null reference (Nothing in Visual Basic) + + + Gets the associated to the column named . + + is a null reference (Nothing in Visual Basic) + + + Adds a to the collection. + + to add to the collection. + + is a null reference (Nothing in Visual Basic) + + + Removes a from the collection. + + to remove from the collection. + + is a null reference (Nothing in Visual Basic) + + + Removes a associated to from the collection. + + whose generator is to be removed from the collection. + + is a null reference (Nothing in Visual Basic) + + + Removes a associated to from the collection. + Column named whose generator is to be removed from the collection. + + is a null reference (Nothing in Visual Basic) + + + A factory for and instances. + + + Creates a instance. + Connection string to server + A instance. + + + An instance that can fill a with data that are compatible with a given . + + + Gets the foreign constraint that needs to be satisfied. + The associated to this provider. + + + Gets the table populator associated to the foreign table. + The instance associated to the foreign table. + + + Gets a value indicating that the foreign table is empty and cannot provide keys. + true if the foreign table is empty; otherwise false. + + + Fill the row with data that is compatible with the foreign key. + + instance to fill. + + is a null reference (Nothing in Visual Basic). + + + A collection of . + + + An random generator compatible with the schema of a given . + + + Gets the that ensures CHECK constraints. + A instance if any check constraint to verify; otherwize a null reference. + + + Gets a collection of associated to each column of the table. + A instance containing the generators associated to each column. + + + Gets an instance of the $ that contains this populator. + Parent instance. + + + Gets a collection of associated to each . + A instance containing the providers associated to each foreign key. + + + Gets the latest generated . + Latest generated . + + + Gets the instance that is the model to be populated. + A instance whos schema is used to create new . + + + Gets a collection of associated to each . + A instance containing the validators associated to each unique constraint. + + + Updates randomly a number of rows + The row to update. + + + Updates randomly a number of rows + The row to update. + Flag to update any foreign keys. + + + Generates a new . + Generated instance. + + + A collection of . + + + A validator for constraints. + + + A collection of . + + + Enumeration of available SQL backup devices + + + DISK device + + + TAPE device + + + Output to named dump + + + Static helper class for creating data binders This is a and so cannot be inherited or instantiated. + + + A random data generator for values. This class is and so cannot be instantiated. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated length. Default is 16. + + + Gets or sets the minimum length of the generated value + Minimum generated length. Default is 16. + + + Generates a new value + New random data. + + + A random generator of values. + + + Gets the generated type + Generated type. + + + Gets or sets the probability to return true. + Probability to return true. + + is not in [0,1]. + + + Generates a new value + New random data. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + Abstract base class from instance. This class is and so cannot be instantiated. + + + Gets the target column + Target instance. + + + Gets the generated type + Generated type. + + + Gets or sets the probability to produce a NULL + The probability to produce a null object. + + + Generates a new value + New random data. + + + Resets the generator + + + Updates the internal data and verifies column information. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + A random generator of values. + + + Gets the generated type + Generated type. + + + Generates a new value + New random data. + + + A random data generator for binary values. + + + Gets the generated type + Generated type. + + + Gets or sets the pixel format + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + A random data generator for values. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is + + + Gets or sets the minimum generated value + Minimum generated value. Default is + + + Generates a new value + New random data. + + + Generates a new value + New random data. + + + Generates a new value + New random data. + + + A random generator of instances. + + + Gets or sets the string containing the generated characters + + + Generates a new value + New random data. + + + + Gets the generated type + Generated type. + + + Gets or sets the maximum generated value + Maximum generated value. Default is 0 + + + Gets or sets the minimum generated value + Minimum generated value. Default is 0 + + + Generates a new value + New random data. + + + A random generator of instances. This class is and so cannot be instantiated. + + + Gets the generated type + Generated type. + + + Gets or sets the maximum length of the string + Maximum length of the string. + set proprety, the value is less than 1. + + + Gets or sets the minimum length of the string + Minimum length of the string. + set proprety, the value is negative. + + + A graph of (vertices) and (edges). + + + Gets a value indicating if the allows parallel edges. + true if the is a multi-graph, false otherwise + + + Gets the provider + + provider + + + Enumerable collection of edges. + + + Gets the edge count + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Gets a value indicating if the is directed. + true if the graph is directed, false if undirected. + + + Gets the provider + + provider + + + Enumerable collection of vertices. + + + Gets the number of vertices + Number of vertices in the graph + + + Gets a value indicating if the vertex set is empty + true if the vertex set is empty, false otherwise. + + + Add a new vertex from source to target Complexity: 2 search + 1 insertion + Source vertex + Target vertex + Relation + Created Edge + source or target is a null reference + source or target are not part of the graph + + + Add a new DataTableVertex to the graph and returns it. + Created vertex + + + Gets a value indicating if the set of edges connected to v is empty + true if the adjacent edge set is empty, false otherwise. + v is a null reference + + + Gets an enumerable collection of adjacent vertices + + Enumerable collection of adjacent vertices + + + Remove all of the edges and vertices from the graph. + + + Remove all edges to and from vertex u from the graph. + + + + Test is an edge (u,v) is part of the graph + source vertex + target vertex + true if part of the graph + + + Tests if a () is part of the graph + Edge to test + true if is part of the graph, false otherwize + + + Tests if a is part of the graph + Vertex to test + true if is part of the graph, false otherwize + + + Returns the number of in-edges plus out-edges. + + + + Returns the number of in-degree edges of v + + number of in-edges of the vertex v + v is a null reference (Nothing in Visual Basic) + + is not part of the graph. + + + Returns an iterable collection over the in-edge connected to v + + in-edges of v + v is a null reference (Nothing in Visual Basic) + + is not part of the graph. + + + Gets a value indicating if the set of in-edges is empty + true if the in-edge set is empty, false otherwise. + v is a null reference (Nothing in Visual Basic) + + is not part of the graph. + + + Returns the number of out-degree edges of v + vertex + number of out-edges of the v + v is a null reference (Nothing in Visual Basic) + v is not part of the graph. + + + Returns an iterable collection over the edge connected to v + + out-edges of v + v is a null reference. + v is not part of the graph. + + + Gets a value indicating if the set of out-edges is empty + true if the out-edge set is empty, false otherwise. + v is a null reference (Nothing in Visual Basic) + v is not part of the graph. + + + Removes an edge from the graph. Complexity: 2 edges removed from the vertex edge list + 1 edge removed from the edge list. + edge to remove + e is a null reference (Nothing in Visual Basic) + + is not part of the graph + + + Remove the edge (u,v) from the graph. If the graph allows parallel edges this remove all occurrences of (u,v). + source vertex + target vertex + + + Remove all the edges from graph g for which the predicate pred returns true. + edge predicate + + + Remove all the out-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + Remove all the out-edges of vertex u for which the predicate pred returns true. + vertex + edge predicate + + + Removes the vertex from the graph. + vertex to remove + v is null + + + Returns the collection of edges that matches the predicate + Edge predicate + enumerable colleciton of vertices that matches the criteron + ep is null + + + Returns the collection of in-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the collection of out-edges that matches the predicate + + Edge predicate + enumerable colleciton of vertices that matches the criteron + v or ep is null + + + Returns the first Edge that matches the predicate + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + ep is null + + + Returns the first in-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + Returns the first out-edge that matches the predicate + + Edge predicate + null if not found, otherwize the first Edge that matches the predicate. + v or ep is null + + + Returns the first that matches the predicate + vertex predicate + null if not found, otherwize the first vertex that matches the predicate. + vp is null + + + Returns the collection of vertices that matches the predicate + vertex predicate + enumerable colleciton of vertices that matches the criteron + vp is null + + + A populator of instance. + + + A with a instance. + + + Default implementation. + + + A querying the databse. This class is and so cannot be instantiated. + + + A based on a . + + + Default implementation of + + + Default implementation of This class is and so cannot be instantiated. + + + An smart random generator. + + + Base class for implementation. This class is and so cannot be instantiated. + + + Helper class to performe task on a SQL server. + + + Gets the connection string with Initial Catalog information. + Connection string with Initial catalog information. + + + Creates a backup of the specified database using the specified and . + A defining the type of output device. + Device path. + + is a null reference (Nothing in Visual Basic) + + + Creates a new database on the server + + + Drops an existing new database on the server + + is a null reference (Nothing in Visual Basic) + + + Restores a backup of the specified database using the specified and . + A defining the type of output device. + Device path. + + is a null reference (Nothing in Visual Basic) + + + A implementation for MSSQL server. This class cannot be inherited. + + + Creates a instance. + + + + + Creates a instance. + Connection string to server + A instance. + + + Abstract base class for MSSQL server database testing. This class is and so cannot be instantiated. + + + Gets the current connection instance. + + instance. + + + Gets the current transaction. + A instance if was called and the connection not closed; otherwise, a null reference (Nothing in Visual Basic) + + + Provides functions to capture the entire screen, or a particular window, and save it to a file. This is a and so cannot be inherited or instantiated. + + + Creates an Image object containing a screen shot of the + + + Creates an Image object containing a screen shot of a specific window + The handle to the window. (In windows forms, this is obtained by the Handle property) + + + Creates an Image object containing a screen shot of the entire desktop + + + Creates an Image object containing a screen shot of the entire desktop + + + A that simulates a MouseDown event. + + + Executes the mouse down event + + + A that simulates a MouseUp event + + + Executes the mouse up event + + + A that simulates a button click + + + Executes the mouse click + + + A that moves the cursor to the center of a . + + + Offset of the target on the + + + Gets the center of the target . + A representing the center of the target control in client coordiantes + + + Gets or sets the target + A instance where the cursor has to move + + + A that steers the cursor to a target + + + Gets or sets the target of the movement, in client coordinates + A in client coordinates + + + Gets the target of the movement, in client coordinates. + A in client coordinates + + + Abstract base class for implementation. This class is and so cannot be instantiated. + + + Gets or sets the instance targeted by the + A instance + + + Raises the event. + + + + Converts the target from screen to client coordinates + Position in screen coordinates + Position converted into client coordinates + + + Converts the target from client to screen coordinates + Position in client coordinates + Position converted into screen coordinates + + + Executes the gesture. + + + Raised when the target is changed + + + A helper factory of instance. + + + Gets the target instance + A instance that is targetted by the gestures + + + Creates a that simulates a left click of the mouse + A instance + + + Creates a that simulates a left click of the mouse + Control to click + A instance + + + Creates a that simulates a left click of the mouse + The control to click. + Which button(s) to use. + A instance + + + Creates a that simulates a left click of the mouse + value representing the involved in the gesture + A instance + + + Creates a new instance that simulates a Mouse down event (left click) + A instance + + + Creates a new instance that simulates a Mouse down event with the buttons + value representing the involved in the gesture + A instance + + + Creates a instance that simulates a drag and drop between and + Source client coordinate + Target client coordinate + A instance that simulates the drag and drop + + + Creates a instance that simulates a drag and drop between and + Source client coordinate + Target + A instance that simulates the drag and drop + + + Creates a instance that simulates a drag and drop between and + Source + Target client coordinate + A instance that simulates the drag and drop + + + Creates a instance that simulates a drag and drop between and + Source + Target + A instance that simulates the drag and drop + + + Creates a instance that simulates a drag and drop between and + Source + Target client coordinate + A instance that simulates the drag and drop + + + Creates a that simulates the movement of the mouse to the target + Target client coordinate + A instance + + + Creates a that simulates the movement of the mouse to the target and the buttons down + Target client coordinate + value representing the involved in the gesture + A instance + + + Creates a that simulates the movement of the mouse to the center of the + Target instance + A instance + + + Creates a that simulates the movement of the mouse to the center of the with the buttons down + Target instance + value representing the involved in the gesture + A instance + + + Creates a new instance that simulates a Mouse up event (left click) + A instance + + + Creates a new instance that simulates a Mouse up event with the buttons + value representing the involved in the gesture + A instance + + + Creates a new with the gesture and the repeat count + Target instance + Number of repetition + A instance + + + Creates a instance with a variable list of instances. + gestures to execute in sequence. + A instance + + + Creates a that makes the thread sleep a given number of milliseconds + Duration in milliseconds of the sleep + A instance + + + Creates a for the method and starts it. + The to execute + The started instance + + + Abstract base class for instance. This class is and so cannot be instantiated. + + + Gets or sets a value indicating the involved in the gesture. + A combined value of flags. + + + An abstract base class for implementations that simulates a mouse movement This class is and so cannot be instantiated. + + + Gets or sets a value indicating the maximum velocity of the cursor + A representing the maximum velocity of the cursor + + + Gets the target of the movement, in client coordinates + A in client coordinates + + + Steers the mouse towards the target + + + A that executes a Repeat of instances. + + + Gets the collection of to execute in Repeat + A instance + + + Gets or sets the number of gesture repetition + The repetition count + + + Executes the contained in in Repeat. + + + A that executes a sequence of instances. + + + Gets the collection of to execute in sequence + A instance + + + Executes the contained in in sequence. + + + A that makes the sleep. + + + Gets or sets the sleep duration (in milliseconds) + Number of milliseconds of sleep + + + Executes the sleep gestures + + + A static helper for artificially generationg mouse and keyboard input. This is a and so cannot be inherited or instantiated. + + + Notfies that a mouse movement is starting with the buttons settings + Combined flag describing the current button state + + + Notfies that a mouse movement is finishing with the buttons settings + Combined flag describing the current button state + + + Mouse click using button state + Combined flag describing the current button state + + + Mouse down event + + + + Generates a mouse event + Combined flag describing the mouse event + + + Mouse event with additional data + Combined flag describing the mouse event + Relative horizontal movement of the cursor + Relative vertical movement of the cursor + Additional data + + + Mouse up event + + + + Mouse wheel event + Wheel movement + + + Move mouse of units + horizontal movement + vertical movement + + + Simulates a Backspace + handle of control to receive the event + + + Simulates a Key action (KeyDown, Key, KeyUp message sequence) + character pressed + handle of control to receive the event + + + Simulates a user typing text + text to enter + handle of control to receive the event + + + A user gesture. + + + Gets the that is targeted by the gesture + + + Executes the gesture + + + Gets the CodeDom statement creating this gesture + + + A mutable collection of + + + Gets or sets the at position + index of the gesture + get property, the at position + + + Adds a instance to the collection + A instance to add to the collection + + + A mouse gesture. + + + Gets or sets a value indicating the involved in the gesture. + A combined value of flags. + + + Mouse even type enumeration + + + No event + + + Mouse move where dx,dy are in absolute coordinate + + + Left button bown + + + Left button up + + + Middle button down + + + middle button up + + + Mouse moved + + + Right button down + + + Right button up + + + Mouse wheel movement + + + Additional button down + + + Additional button up + + + A that choose from a set of sub-. + + + Gets or sets the instance + + instance. + + + Choose a and launch its production. + Authorizing token + + + Abstract rule containing other rules. This class is and so cannot be instantiated. + + + Gets the list of rules stored in the rule. + + containing the child rules. + + + If then else rule fashion. + + + Gets or sets the rule executed when the predicate is false + + instance executed when is false. + + + Gets or sets the predicate for the condition. + + instance used for testing the condition. + set property, value is a null reference + + + Gets or sets the rule executed when the predicate is true + + instance executed when is true. + set property, value is a null reference + + + Executes one of the rules depending on the predicate result. + A production token authorizing production. + + is a null reference (Nothing in Visual Basic) + + + A instance that executes a . + + + Invokes the instance and returns the result. + + + + A class that limits the number of terminal execution. + + + Processes the request for a done by a rule and returns the token or throws. + + instance that requests the token. + A valid instance. + The maximum number of terminal rule execution was hitted. + + + Factory for instance. + + + Creates new instances of + A instance + + + A that wraps a call. + + + Invokes handler. + + + + A grammar containing a set of rules, a . + + + Gets or sets the instance. + + instance used for creating new productions. + + + Gets or sets the starting rule. + The start . + + + Launches a production. + + + A that guard an inner instance execution from a specific exceptionType. + + + Gets or sets the regular expression to match the message. + The instance used to mach the message. + + + Gets or sets the rule name (for debugging purpose) + The rule name. + + + Gets a value indicating if the rule is terminal. + Always returns true. + + + Gets or sets a value indicating the rule importance + Value indicating the rule importance + + + Raises the event. + + + Executes the inner and guards for a particular exception type. + Authorization token + + + Semantic actions event + + + A rule that executes a . + + + Invokes the instance. + Autorization token + + + Exception throwed when an exception is catched and is not from the expected type. + + + Exception throwed when an exception message does not match with the message regular expression + + + Gets the instance used to match the exception message + + message matcher. + + + A static helper class for creating . This is a and so cannot be inherited or instantiated. + + + Creates a around + condition to wrap + A + + + Expection class used to stop production. + + + Gets the production that stopped. + + + Default implementation of + + + Gets a value indicating if the production is authorized + true if authorized, otherwise false. + + + Gets the that emited the token. + The instance that emited the token. + + + A rule that executes a . + + + Invokes the instance. + Autorization token + + + System implementation of + + + Uniform random rule selector. + + + Gets or sets the random generator + The instance used for random data generation + set property, value is a null reference + + + Select a from + + array to select from + Select instance + + is a null reference + + is empty + + + Select a from + + collection to select from + Select instance + + is a null reference + + is empty + + + A that executes repeatidely an inner + + + Gets the maximum of rule execution + Maximum of rule execution + + + Gets the minimum of rule execution + Minimum of rule execution + + + Gets or sets the random generator used for selection repetition counts + The random generator. + set property, value is a null reference + + + Gets the inner instance + Repeated instance. + + + Executes repeatidely the inner rule. + Authorization token + + + Converts rule to EBNF like representation + EBNF-like string representing the rule. + + + Round Robin rule selector. + + + Gets or sets the current rule index. + Current rule index + + + Select a from + + array to select from + Select instance + + is a null reference + + is empty + + + Select a from + + collection to select from + Select instance + + is a null reference + + is empty + + + Abstract rule class This class is and so cannot be instantiated. + + + Gets or sets the rule name + The rule name + + + Gets a value indicating if the rule is terminal + true if the rule is terminal; otherwise, false. + + + Gets or sets the rule weight + The rule weight + set property, weight is negative + + + Raises the event. + + + Executes the production using the rule (abstract class). + A production token authorizing production. + + is a null reference (Nothing in Visual Basic) + + + Semantic action event. + + + A collection of elements of type IRule + + + Gets or sets the IRule at the given index in this RuleList. + + + Adds an instance of type IRule to the end of this RuleList. + The IRule to be added to the end of this RuleList. + + + Determines whether a specfic IRule value is in this RuleList. + The IRule value to locate in this RuleList. + true if value is found in this RuleList; false otherwise. + + + Returns an enumerator that can iterate through the elements of this RuleList. + An object that implements System.Collections.IEnumerator. + + + Inserts an element into the RuleList at the specified index + The index at which the IRule is to be inserted. + The IRule to insert. + + + Removes the first occurrence of a specific IRule from this RuleList. + The IRule value to remove from this RuleList. + + + Type-specific enumeration class, used by RuleList.GetEnumerator. + + + Static helper class for creating rules. This is a and so cannot be inherited or instantiated. + + + Creates an alternative of rules. + Set of rule to choose from alternatively. + An instance implementing the alternative rule choosing. + + + Creates a that executes an . + + to execute + + instance that contains + + + Guards the execution of a from an expected type. + + instance to guard. + Expected throwed exception when is executed + A instance guarding + + + Creates a conditional rule with "if" rule. + Condition expression + + to execute if condition is true. + A implementing condition rule execution. + + + Creates a conditional rule with "if" rule and "else" rule. + Condition expression + + to execute if condition is true. + + to execute if condition is false. + A implementing condition rule execution. + + + Creates a conditional rule with "if" rule. + Condition expression + + to execute if condition is true. + + to execute if condition is false. + A implementing condition rule execution. + + + Creates a conditional rule with "if" rule and "else" rule. + Condition expression + + to execute if condition is true. + A implementing condition rule execution. + + + Creates a rule to be execute zero or more times. + Rule to be executed. + An instance implementing the * operator. + + + Creates a that executes an . + + to execute + + instance that contains + + + Creates a that executes an . + + to execute + + instance that contains + + + Creates an optional rule. + Rule to execute optionaly. + An instance implementing the ? operator. + + + Creates a rule to be execute one or more times. + Rule to be executed. + An instance implementing the + operator. + + + Creates a rule to be execute between and times. + Rule to be executed. + minimum number of execution of + maximum number of execution of + An instance implementing the {m,n} operator. + + + Creates a sequence of rules. + Set of rule to execute in sequence. + An instance implementing the sequence of rules. + + + Creates a weighted alternative of rules. + Set of rule to choose from alternatively. + An instance implementing the alternative rule choosing. + + + A sequence of rules. + + + Executes sub-rule production in sequence. + + to authorize production. + + + Weighted random rule selector. + + + Select a from + + array to select from + Select instance + + is a null reference + + is empty + + + Select a from + + collection to select from + Select instance + + is a null reference + + is empty + + + A grammar containing a set of rules, a . + + + Gets or sets the starting rule. + The start . + + + Launches a production. + + + Raised when production is finished. + + + Predicate that checks a given condition. + + + Checks a condition and returns result. + Current production token + Predicate result + + + A production done by a grammar and its set of rules. + + + Gets the seed that created the production + Seed used to create the production + + + Processes the request for a done by a rule and returns the token or throws. + + instance that requests the token. + A valid instance. + The request was defined using the internal production logic. + + + A factory for instances. + + + Creates a new instance. + A valid instance. + + + An authorization to execute a production. + + + Gets a value indicating if the production is authorized + true if authorized, otherwise false. + + + Gets the that emited the token. + The instance that emited the token. + + + A class that creates random values. + + + Returns a nonnegative random number. + A 32-bit signed integer greater than or equal to zero and less than . + + + Returns a nonnegative random number less than the specified maximum. + + A 32-bit signed integer greater than or equal to zero and less than . + + + Returns a random number within a specified range. + The lower bound of the random number returned. + The upper bound of the random number returned. maxValue must be greater than or equal to minValue. + A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not MaxValue. If minValue equals maxValue, minValue is returned. + + + Returns a random number between 0.0 and 1.0. + A double-precision floating point number greater than or equal to 0.0, and less than 1.0. + + + A production rule + + + Gets or sets the rule name (for debugging purpose) + The rule name. + + + Gets a value indicating if the rule is terminal + true if the rule is terminal; otherwise, false. + + + Gets or sets a value indicating the rule importance + Value indicating the rule importance + set property, value is negative. + + + Executes the production using the rule. + A production token authorizing production. + + is a null reference (Nothing in Visual Basic) + + + Semantic actions event. + + + A collection of . + + + Gets an instance of the rules. + A valid instance. + + + An enumerator over instance. + + + Gets the current instance + Current instance. + + + A list of + + + Gets or sets the at position . + + index. + + + Adds a to the list. + + to add + + + Clears the list. + + + Gets a value indicating if is in the list. + + to test. + true if is in the list; otherwise, false. + + + Inserts a instance at position + position to insert the rule + + to insert + + + Removes the first occurence of . + + to remove + + + A object that select a rule between a collection of rules. + + + Select a from + + array to select from + Select instance + + is a null reference + + is empty + + + Select a from + + collection to select from + Select instance + + is a null reference + + is empty + + + Method that returns a bool. + Current instance. + + + A class to generate permutations. This class cannot be inherited. + + + Gets the order of the permutation + + + Applis the permutation to the array + A array of Length equal to . + A new array containing the permutated element of + + + Creates the next permutation in lexicographic order. + The next instance if there remain any; otherwize a null reference. + + + Gets an enumerable collection of successors. + + + Creates the inverse of the permutation. + + + Converts the permutation to a string representation. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit35.dll b/lib/Gallio_3.1.397.0/bin/MbUnit35.dll new file mode 100644 index 00000000..b3831b84 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit35.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit35.pdb b/lib/Gallio_3.1.397.0/bin/MbUnit35.pdb new file mode 100644 index 00000000..373e90d0 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit35.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit35.plugin b/lib/Gallio_3.1.397.0/bin/MbUnit35.plugin new file mode 100644 index 00000000..7d5c1676 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit35.plugin @@ -0,0 +1,30 @@ + + + + MbUnit v3 Extensions for .Net 3.5 + 3.1.0.0 + Provides additional MbUnit v3 features for use with .Net 3.5. + plugin://MbUnit/Resources/MbUnit.ico + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit35.xml b/lib/Gallio_3.1.397.0/bin/MbUnit35.xml new file mode 100644 index 00000000..2fbac130 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit35.xml @@ -0,0 +1,34 @@ + + + + MbUnit35 + + + + + Provides extended assertions for .Net 3.5. + + + + Initializes a new instance of the class + + + + Verifies that a particular condition holds true. + + The conditional expression to evaluate. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + + Verifies that a particular condition holds true. + + The conditional expression to evaluate. + The custom assertion message format, or null if none. + The custom assertion message arguments, or null if none. + Thrown if is null. + Thrown if the verification failed unless the current indicates otherwise. + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit40.dll b/lib/Gallio_3.1.397.0/bin/MbUnit40.dll new file mode 100644 index 00000000..122ccfcb Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit40.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit40.pdb b/lib/Gallio_3.1.397.0/bin/MbUnit40.pdb new file mode 100644 index 00000000..6d8b5d13 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/MbUnit40.pdb differ diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit40.plugin b/lib/Gallio_3.1.397.0/bin/MbUnit40.plugin new file mode 100644 index 00000000..37e3c1b5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit40.plugin @@ -0,0 +1,30 @@ + + + + MbUnit v3 Extensions for .Net 4.0 + 3.1.0.0 + Provides additional MbUnit v3 features for use with .Net 4.0. + plugin://MbUnit/Resources/MbUnit.ico + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/MbUnit40.xml b/lib/Gallio_3.1.397.0/bin/MbUnit40.xml new file mode 100644 index 00000000..dff68d4d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/MbUnit40.xml @@ -0,0 +1,8 @@ + + + + MbUnit40 + + + + diff --git a/lib/Gallio_3.1.397.0/bin/NCover/Gallio.NCoverIntegration.dll b/lib/Gallio_3.1.397.0/bin/NCover/Gallio.NCoverIntegration.dll new file mode 100644 index 00000000..ac0f52db Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/Gallio.NCoverIntegration.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/Gallio.NCoverIntegration.plugin b/lib/Gallio_3.1.397.0/bin/NCover/Gallio.NCoverIntegration.plugin new file mode 100644 index 00000000..11b11c71 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/Gallio.NCoverIntegration.plugin @@ -0,0 +1,140 @@ + + + + NCover Integration Plugin + 3.1.0.0 + Provides support for running tests with NCover code coverage. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${NCoverIntegration.NCoverTestIsolationProvider.v1.5.8} + + + NCover + + Runs tests in an external process with NCover v1.5.8. NCover v1.5.8 is included and does not need to be installed. + + Supported test runner properties: + - NCoverArguments: Specifies additional command-line arguments for NCover. eg. "//eas Gallio" + - NCoverCoverageFile: Specifies the path of the coverage file to write. The default is 'Coverage.xml' in the current working directory. + + + + + + + V1 + + + + + + + + ${NCoverIntegration.NCoverTestIsolationProvider.v2} + + + NCover2 + + Runs tests in an external process with NCover v2. NCover v2 must be installed separately. + + Supported test runner properties: + - NCoverArguments: Specifies additional command-line arguments for NCover. eg. "//eas Gallio" + - NCoverCoverageFile: Specifies the path of the coverage file to write. The default is 'Coverage.xml'. + + + + + + + V2 + + + + + + + + ${NCoverIntegration.NCoverTestIsolationProvider.v3} + + + NCover3 + + Runs tests in an external process with NCover v3. NCover v3 must be installed separately. + + Supported test runner properties: + - NCoverArguments: Specifies additional command-line arguments for NCover. eg. "//eas Gallio" + - NCoverCoverageFile: Specifies the path of the coverage file to write. The default is 'Coverage.xml'. + + + + + + + V3 + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover Readme.txt b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover Readme.txt new file mode 100644 index 00000000..73d17153 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover Readme.txt @@ -0,0 +1,8 @@ +NCover v1.5.8 is included in the Gallio distribution (along with its license file). + +The NCover.Console.exe's CORFLAGs have been modified to force it to run as a +32bit process using the Windows SDK corflags command. It has not been modified +in any other way. + +You may also use other versions of NCover if they have been separately +installed on the local machine. \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/CoverLib.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/CoverLib.dll new file mode 100644 index 00000000..e038b330 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/CoverLib.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/Coverage.xsl b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/Coverage.xsl new file mode 100644 index 00000000..164ff148 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/Coverage.xsl @@ -0,0 +1,339 @@ + + + + + + + NCover Code Coverage Report + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + javascript:toggle( + ) + + + + + + + + +
    + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VisitsLineEndColumnEndDocument
    + + + exdatacell + hldatacell + datacell + + + + --- + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + +
    + javascript:toggle( + ) + + + + + + + + +
    + + + +
    + + + + + + + +
    + + +
    +
    + + + + + + +
    + + + +
    + + + + + + + + +
    + + +

    Modules summary

    + + + + + + + + +
    +
    +
    +
    + + + + + + +
    + + + +
    + + + + + + + + +
    + + +

    + NCover Code Coverage Report +

    + + + + + + +
    + Expand + | + Collapse +
    +
    +
    + +
    + Top +
    + + + + + + + + + + + + + + + + + +
    Excluded + + + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/MSVCP80.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/MSVCP80.dll new file mode 100644 index 00000000..f0b52ebf Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/MSVCP80.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/MSVCR80.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/MSVCR80.dll new file mode 100644 index 00000000..53c005ef Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/MSVCR80.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/Microsoft.VC80.CRT.manifest b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/Microsoft.VC80.CRT.manifest new file mode 100644 index 00000000..6a8a0e23 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/Microsoft.VC80.CRT.manifest @@ -0,0 +1,8 @@ + + + + + n9On8FItNsK/DmT8UQxu6jYDtWQ= + 0KJ/VTwP4OUHx98HlIW2AdW1kuY= + YJuB+9Os2oxW4mY+2oC/r8lICZE= + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Console.exe b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Console.exe new file mode 100644 index 00000000..80330112 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Console.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Console.exe.config b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Console.exe.config new file mode 100644 index 00000000..eb0a31af --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Console.exe.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Framework.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Framework.dll new file mode 100644 index 00000000..a9539e68 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCover.Framework.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCoverFAQ.html b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCoverFAQ.html new file mode 100644 index 00000000..f63b8f13 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCover/NCoverFAQ.html @@ -0,0 +1,429 @@ + + + + + + + + + + +

    NCover FAQ

    +

    If you have questions that this document does not address, contact + Peter Waldschmidt or try the NCover Forums.

    +

    1. What is code coverage analysis?

    +

    A code coverage analyzer monitors your code at runtime and + records information about which lines of code were executed. NCover shows each + sequence point in your application along with the number of times that point + was executed. Sequence points are generated by the compiler and stored in the + debug information (.pdb) files. A sequence point basically corresponds to a + single program statement (often a line of code) in your high-level language.

    +

    2. Why would I want to do code coverage analysis?

    +

    Unit test suites are often used as a quality tool during the + development process to keep the codebase stable as it changes and expands. + Tools such as NUnit are often used to run and + report on the test suites. However, when implementing unit testing in your + build process, you have no way of knowing how much of your code the unit tests + are actually testing. This is where code coverage comes in. You can run NUnit + within NCover and use the code coverage report to determine which code was not + tested by that particular test suite.

    +

    3. What versions of the CLR does NCover support?

    +

    + NCover 1.5.x requires the .NET framework version 2.0.50727 to be installed; however, + the application being profiled can be written against any shipping version of the + framework. NCover + has been tested profiling coverage of .NET 2.0, .NET 1.1 and .NET 1.0 applications.

    +

    4. Which version of NCover should I install?

    +

    + If you have the .NET 2.0 framework installed on your machine then you should use + the latest NCover version available. NCover as of version 1.5 can profile .NET 2.0, 1.1 and 1.0 applications.

    +

    + For development teams who do not have the .NET framework 2.0 installed but do have + the .NET framework version 1.1.4322, you can + try NCover 1.3.3. Note however that this version is no longer supported as + it has a number of known issues and limitations.

    +

    5. What is the command line syntax for NCover?

    +

    Here is the usage info from the NCover command line (for NCover versions from 1.5.6 + only):

    +
    NCover.Console [<command line> [<command args>]]
    +               [//svc <service name>]
    +               [//iis]
    +               [//a <assembly list>]
    +               [//w <working directory>]
    +               [//ea <exclusion list>]
    +               [//reg]
    +               [//x <xml output file>]
    +               [//s [<settings file>]] [//r [<settings file>]]
    +               [//v] [//q] 
    +               [//l <log file>]
    +
    +//svc  For profiling windows services
    +//iis  For profiling web applications
    +
    +//a    List of assemblies to profile separated by semi-colons i.e. "MyAssembly1;MyAssembly2". Do not include paths or suffixes.
    +//w    Working directory for profiled application 
    +//ea   List of attributes marking classes or methods to exclude from coverage 
    +
    +//reg  Register profiler temporarily for user. (helps with xcopy deployment) 
    +//x    Specify coverage output file. (default: coverage.xml).
    +//pm   Specify name of process to profile (i.e. myapp.exe)
    +
    +//s    Save settings to a file (defaults: NCover.Settings) 
    +//r    Use settings file, overriding other settings (default: NCover.Settings) 
    +
    +//l    Specify profiler log file (default: coverage.log).
    +//q    No logging (quiet) 
    +//v    Enable verbose logging (show instrumented code)
    +        
    +
      +
    • <command line> - This argument specifies the command-line of the .NET application + you want to analyze. + Any command line arguments not starting with // will be passed + through to that application. NCover will profile the running application until it has exited. See below for examples.
    • //svc - This option is an alternative to the <command line> + for profiling windows services, which cannot be run directly as executables. NCover + will start the service (stopping it first if already running) and profile coverage + until the windows service is stopped.
    • +
    • //iis - This option is an alternative to the <command line> for profiling + web applications. NCover will start the IISAdmin and W3C + services (stopping first if currently running) and profile coverage until the IISAdmin + service is stopped.
      +
    • +
    • //a - This command-line argument specifies the assemblies that you want to analyze. + NCover can only analyze assemblies that have .pdb files included with them. If + you do not specify the //a argument, NCover will attempt to analyze every loaded + assembly that has debug information available. Note that the assembly name arguments are + the module name within the assembly, not the physical file name. e.g. "MyAssembly" + rather than "MyAssembly.dll".
    • //w - If the application being profiled requires the + working directory to be set to something other than the current directory you are + executing the command line from then you can override it with this argument.
    • +
    • //ea - You can choose to exclude classes and methods + from coverage statistics by defining .NET attribute(s) and applying it to the affected + code. When using this argument you must specify the full type namespace of these + attribute(s) separated by semi-colons. See below for an example.
      +
    • +
    • //reg - NCover requires a COM registration of the CoverLib.dll assembly containing + the profiler, which is performed automatically by the default .msi installation. + If you require an xcopy style deployment of NCover like many other .NET tools, then + you can use this argument which will temporarily register the profiler while performing + coverage. This feature was added in NCover 1.5.6.
    • +
    • //x - The output of NCover is an xml file (example below). Use this argument to + specify an alternate filename to "coverage.xml" in the current directory.
      +
    • +
    • //pm - This setting tells NCover to ignore processes that don't have the specified process module name. + This is the name of the executable (i.e. myapp.exe). This setting is useful in cases, where your NCover + command spawns a series of child processes. Using this setting will help NCover determine which process to profile. +
    • +
    • //s - You may find it more convenient to use a settings file rather than specifying + a long list of command line arguments for running NCover. If you get the NCover + command line working as you would like it and then use the //s argument it will + save the required arguments as an xml file that can then be used by the //r argument + below.
    • +
    • //r - For use when you have used //s to construct an NCover settings file containing + your command line arguments. e.g. "ncover.console.exe //r NCover.Settings"
      +
    • +
    • //l - The coverage log file can provide an insight if the desired coverage output + is not obtained. Useful information you may find to assist you includes which assemblies + were loaded by NCover, their file paths and which of those it found the .pdb build + symbols for. Use this argument to specify an alternative log file name or location + to coverage.log in the current directory.
    • +
    • //q - Suppresses writing the coverage.log file.
    • +
    • //v - This command-line argument makes the profiler emit all the original IL and + modified IL instructions to the coverage log. This is useful for debugging + purposes. Beware that this can make your coverage log file very large! +
    • +
    +

    6. Does NCover required a special compilation step for my code?

    +

    No. Some code coverage tools change your source code and force + you to recompile it into a special build.  NCover is designed to work + on shipping code.  NCover uses the .NET Framework profiling API to monitor + your code. It does require build symbols, but can be run on release code + without any modifications.

    +

    7. How does NCover work?

    +

    NCover uses the .NET Framework profiler API to monitor an + application's execution. When a method is loaded by the CLR, NCover retrieves + the IL and replaces it with instrumented IL code.  NCover does not change + your original IL code, it simply inserts new code to update a visit + counter at each sequence point.  Upon + request, (usually after the .NET process has shut down) the profiler outputs statistics + to the coverage file. +

    +

    + 8. What is the output of NCover?

    +

    NCover generally writes out three files after analysis + completes. +

      +
    • + Coverage.log - This file is a log of the events and messages from the profiler + during the analysis process. Most of the time, error messages are recorded in + this log. If you enable verbose logging, the coverage log will contain + disassembly of the original and instrumented IL code.  Verbose logging is not recommended for + normal use.
    • + Coverage.xml - This file is the analysis output of NCover. You can see an + example of the output below. +
    • + Coverage.xsl - This file is a simple XML transformation that makes the XML + output easily readable. +
    • +
    + Example XML output +
    <method class="NCoverTest.ClassLoaded" name="HasDeadCode">
    +    <seqpnt document="C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs"
    +            column="13" line="48" endcolumn="58" endline="48" visitcount="1" /> 
    +    <seqpnt document="C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs" 
    +            column="13" line="49" endcolumn="22" endline="49" visitcount="1" /> 
    +    <seqpnt document="C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs" 
    +            column="17" line="50" endcolumn="24" endline="50" visitcount="1" /> 
    +    <seqpnt document="C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs" 
    +            column="13" line="51" endcolumn="48" endline="51" visitcount="0" /> 
    +    <seqpnt document="C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs" 
    +            column="9" line="52"  endcolumn="10" endline="52" visitcount="0" /> 
    +</method>
    +
    +

    + Example transformed output +
    +
    NCoverTest.ClassLoaded.HasDeadCode
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Visit CountLineColumnEnd LineEnd ColumnDocument
    148134858C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs
    149134922C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs
    150175024C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs
    051135148C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs
    05295210C:\Dev\Utilities\ncover\NCoverTest\NCoverTest.cs
    +
    +

    Suggested usages of the coverage.xml output are to display it in the + NCoverExplorer gui with the source + code highlighted, to generate html reports, or to include it in your continuous build server reports such as CruiseControl.Net. + For more information on these options see below in the FAQ.

    +

    +

    + 9. How do I use coverage exclusions?

    +

    + First you should define an attribute to markup your excluded code with. You will + likely want to put this in a common assembly to make it reusable, or indeed within + a "CommonAssemblyInfo.cs" that you include in all your application assemblies.

    +

    +
    namespace MyNamespace {
    +    class CoverageExcludeAttribute : System.Attribute { }
    +}
    +

    + Apply the attribute to the C# classes and/or methods you wish to mark as excluded + from code coverage statistics:

    +

    +
        [CoverageExclude]
    +    private void SomeMethodToExclude() {}    
    +

    + Finally, ensure you pass the full qualified attribute information in the NCover command line:

    +

    +
        NCover.Console MyApplication.exe //ea MyNamespace.CoverageExcludeAttribute    
    +

    + Note that if you are using the TestDriven.Net + VS.Net add-in to "Test with Coverage" it will automatically + pass through "//ea CoverageExcludeAttribute" + which you should define without a namespace like above. For further information refer to this + + blog entry.

    +

    + 10. Examples

    +

    + Coverage while running a simple executable until it exits:

    +

    +
        NCover.Console MyApplication.exe
    +

    + Coverage while running all the unit tests in an assembly using NUnit, profiling + all loaded assemblies with .pdb build symbols:

    +

    +
        NCover.Console nunit-console.exe MyApplication.Tests.dll
    +

    + Coverage of only a subset of loaded assemblies while running unit tests:

    +

    +
        NCover.Console nunit-console.exe MyApplication.Tests.dll //a MyApplication.Core;MyApplication.Utilities
    +

    + Coverage of a windows service. Stop the service to generate the coverage output:

    +

    +
        NCover.Console //svc MyServiceName
    +

    + Coverage of an ASP.Net application. Stop the IIS service to generate the coverage + output:

    +

    +
        NCover.Console //iis
    +

    + 11. Where can I get help or support?

    +

    + Your best approach is to browse the + NCover forums as well as the + blog by the author Peter Waldschmidt. If you cannot find a similar issue + mentioned feel free to post your query and perhaps someone can help.

    +

    + 12. How do I "xcopy deploy" NCover like my other build tools?

    +

    + Many developers prefer to have their build tools such as NUnit, NAnt etc stored + in source control in a Tools folder along with the source code. This ensures that + a new developer can obtain and build the application without having to install additional + tools on their own machines.

    +

    + NCover can also be deployed in this fashion. However the one gotcha with NCover + versus other tools is that the profiler within CoverLib.dll must be COM registered + on the local machine before you execute it. Prior to NCover 1.5.6 this was usually + achieved as part of your build script, which would call regsvr32 with the path to + the CoverLib.dll in your Tools folder. Alternatively the <ncover> NAnt and + MSBuild tasks described below will do this for you. As of NCover 1.5.6 you can also + use the //reg option in the command line arguments which will temporarily register + the profiler. Note that the //reg option will not work for IIS or Windows Service + profiling unless you are running NCover under the same Windows login account as + the IIS worker process, or your Windows Service.

    +

    + 13. How do I see my source code highlighted with the coverage results?

    +

    + NCoverExplorer is a gui and console-based + .NET application developed by Grant Drake. NCoverExplorer + parses the coverage.xml files output from NCover and displays the results integrated + with your source code. It also includes a number of additional features to merge, + filter, sort and generate html reports. The console version is + designed to be used as part of an automated build process. The support forums for + NCoverExplorer are located with the NCover ones at http://ncover.org/. 

    +

    + 14. How do I run NCover from within the Visual Studio.Net IDE?

    +

    + The TestDriven.Net add-in by + Jamie Cansdale offers a right-click capability within the IDE to execute + your unit tests with code coverage. The results of the NCover code coverage are + displayed with the bundled NCoverExplorer gui for analysis and reporting.

    +

    + 15. How do I run NCover from a NAnt or MSBuild task?

    +

    + You can use an <exec> task with NAnt + or an <Exec> task with MSBuild. Alternatively you may want to use the custom + <ncover> task for NAnt or <NCover> task for MSBuild developed by Grant + Drake for a more developer friendly syntax. The source code, compiled assemblies + and documentation are located in the NCoverExplorer.Extras.zip available from http://ncoverexplorer.org/.

    +

    + 16. How do I include NCover output in my CruiseControl.Net build reports?

    +

    + CruiseControl.Net is a continuous integration + build server which offers web-based reporting of the outputs of a build such as + unit test results and code coverage reporting. The default CruiseControl.Net installation + includes a basic stylesheet which works in combination with the standard coverage.xml + formatted output. So all you need to do is include the execution of NCover as part + of your build, then add a CruiseControl.Net merge file publisher task to integrate + the coverage.xml results into the build output.

    +

    + An improvement on the above to display more attractive and powerful reports as well + as minimize the build log size is to use NCoverExplorer. The NCoverExplorer.Console.exe + is designed to produce a more concise xml report summary that is combined with an + alternate xsl stylesheet for CruiseControl.Net. You can find more information and + screenshots in this + blog entry - all the necessary tasks, examples and documentation are located + within NCoverExplorer.Extras.zip available from + http://ncoverexplorer.org/

    +

    + 17. How do I merge multiple NCover coverage.xml results?

    +

    + You can can use NCoverExplorer to merge the results of multiple coverage runs. For + more information refer to this + blog entry.

    +

    + 18. Troubleshooting: Why is my coverage.xml file empty?

    +
      +
    • If using the command-line, did you COM register CoverLib.dll (or use the //reg option + from NCover 1.5.6)?
    • +
    • Did you generate build symbol files (.pdbs) for the profiled application?
    • +
    • If using the //a option, did you correctly list just the assembly names without + paths or .dll suffixes?
    • +
    +

    + 19. Troubleshooting: I have coverage.xml output but my XYZ assembly is not included in it?

    +
      +
    • NCover will only profile loaded assemblies - did your code execution path while + under coverage force that assembly to be loaded (e.g. by loading a type or calling + a method in that assembly)? 
    • +
    • Did you generate build symbol files (.pdb files) for the missing assembly?
    • +
    • If using the //a option, did you correctly list the assembly names including the + one that is missing?
    • +
    • Can you see information about the assembly being loaded within the coverage.log? + Is the correct assembly being loaded (check the path) - if you have a version in + the GAC it may possibly prevent the .pdb file from being loaded.
    • If using the NCoverExplorer gui, have you got a coverage exclusion defined which + is hiding it from the display?
    • +
    +

    + 20. Troubleshooting: After running NCover my coverage.log says "Failed to load symbols for module XYZ"?

    +
      +
    • This message means that no .pdb build symbol file was found for that assembly so + it cannot be profiled for code coverage. If that assembly is part of the .NET framework + for instance like System.Data.dll, then this is an expected message and should not + cause concern. 
    • If however the assembly belongs to your application, did you generate the + build symbol files (.pdb files) for it?
    • +
    +

    + 21. Troubleshooting: I get a "Profiled process terminated. Profiler connection not + established" message?

    +
      +
    • If using the command-line, did you COM register CoverLib.dll (or use the //reg option + from NCover 1.5.6)?
    • Are you running Windows XP 64-bit? You may want to take a look at + this thread
    +

    + 22. Troubleshooting: My coverage exclusions are not working?

    +
      +
    • Have you put the full namespace type name to the exclusion including the Attribute suffix in the //ea argument? See the "How + do I use coverage exclusions?" question above.
    +   + + diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer Readme.txt b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer Readme.txt new file mode 100644 index 00000000..80436bbb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer Readme.txt @@ -0,0 +1,5 @@ +NCoverExplorer v1.3.6 is included in the Gallio distribution (along with its license file). + +This version of NCoverExplorer is used together with the included copy +of NCover v1.5.8 to merge coverage files. Newer versions of NCover +include a specialized reporting tool for this purpose. diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/CommandBars.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/CommandBars.dll new file mode 100644 index 00000000..921ad777 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/CommandBars.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ConsoleConfig.xsd b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ConsoleConfig.xsd new file mode 100644 index 00000000..05645243 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ConsoleConfig.xsd @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ConsoleExample.config b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ConsoleExample.config new file mode 100644 index 00000000..45daf3c1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ConsoleExample.config @@ -0,0 +1,43 @@ + + + + + + Example.Project + + + + 80 + + None + + Name + + + + Assembly + *.Tests + false + + + Namespace + *.My* + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/CoverageReport.xsl b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/CoverageReport.xsl new file mode 100644 index 00000000..ae8586f4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/CoverageReport.xsl @@ -0,0 +1,494 @@ + + + + + + + + Generated by NCoverExplorer (see http://www.kiwidude.com/blog/) + NCoverExplorer - Merged Report + + + + + + + +
    + + +
    + + + + + + + + + + + + + Unvisited Functions + Unvisited SeqPts + + + + + Function Coverage + Coverage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    NCoverExplorer Coverage Report -   

    + + + + + + + + + + + + + + + +
    Report generated on: at 
    NCoverExplorer version:
    Filtering / Sorting: / 
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Project Statistics:Files: NCLOC:
    Classes:  
    Functions:Unvisited:
    Seq Pts:Unvisited:
    +
    + + +
    + + + + + + + + +   + + + Project + Acceptable + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + +   + + + Modules + Acceptable + + + + + + + + + + + True + + + + + + + + + +   + + + Module + Acceptable + Unvisited SeqPts + Coverage + + + + + + + + + + Namespaces + + + + + + + + + + + + + + + + + + + + +   + + + Module + Acceptable + + + + + + + + + + + + Namespace / Classes + + + + + + + + + padding-left:20px;font-weight:bold + + + + + + + + + padding-left:30px + 160 + + + + + + + + + + +   + + + Namespaces + Unvisited SeqPts + Coverage + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + padding-left:20px + 180 + + + + + + + + + + + + + + + + + + +   + + + Excluded From Coverage Results + All Code Within + + + + + + + + + + + + +   + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + . + + + . + + graphBarSatisfactory + graphBarNotVisited + + + + .
    +
    +
    \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ICSharpCode.TextEditor.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ICSharpCode.TextEditor.dll new file mode 100644 index 00000000..3a311a98 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/ICSharpCode.TextEditor.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.Console.exe b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.Console.exe new file mode 100644 index 00000000..40a1d6d1 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.Console.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.Core.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.Core.dll new file mode 100644 index 00000000..c5a7dbc7 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.Core.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.NCoverRunner.dll b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.NCoverRunner.dll new file mode 100644 index 00000000..2bb80f53 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.NCoverRunner.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.exe b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.exe new file mode 100644 index 00000000..dbd86e58 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.exe differ diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.exe.config b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.exe.config new file mode 100644 index 00000000..4bb5eb0d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorer.exe.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorerFAQ.html b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorerFAQ.html new file mode 100644 index 00000000..0f0d96e1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorerFAQ.html @@ -0,0 +1,301 @@ + + + + + NCoverExplorer FAQ + + + + + +

    NCoverExplorer FAQ

    +

    The latest version of this document is located here. +
    For the latest NCoverExplorer news and updates, visit my blog.

    +

    Expand All | Collapse All

    + 1. What is NCoverExplorer?
    + + 2. What versions of the .NET Framework does it work with?
    + + 2. What versions of NCover does it work with?
    + + 3. Can I integrate it with my Visual Studio.Net version XXX IDE?
    + + 4. Can I integrate it without TestDriven.Net?
    + + 5. How does it compare to Visual Studio Team System?
    + + 6. Why didn't you integrate NCoverExplorer directly into the IDE like VSTS or SharpDevelop?
    + + 7. What do the tree node colours mean?
    + + 8. What do the source code highlighting colours mean?
    + +
    9. What is that "Satisfaction Threshold" all about?
    + + 10. I have a killer idea for XYZ feature - can you add it for me?
    + + 11. Where can I download the latest version?
    + + 12. What are the keyboard shortcuts?
    + + 13. Where are my personal settings stored?
    + + 14. Where can I download the custom NAnt/MSBuild tasks from?
    + + 15. I get an "Illegal characters in path" exception - why?
    + + 16. I get a "System.Format" exception - why?
    + + 17. My module thresholds are not working - why?
    + +

    ---------------------------------
    FAQ last updated Apr 1st 2007.

    + + diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorerReleaseNotes.html b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorerReleaseNotes.html new file mode 100644 index 00000000..21d193ef --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/NCoverExplorerReleaseNotes.html @@ -0,0 +1,790 @@ + + + + NCoverExplorer Release Notes + + + + + +

    NCoverExplorer Release Notes

    +

    The latest version of this document is located here. +
    For the latest NCoverExplorer news and updates, visit my blog.

    +
    + +

    v1.3.6 - Apr 5th 2007

    +

    Bundled with TestDriven.Net from build 2.5.2078.

    +

    The following new features were introduced:

    +
      +
    • + Added a Find dialog (ctrl+F) to quickly navigate to a class. Wildcards are supported. +
    • +
    • + Added a /q or /quiet option to NCoverExplorer.Console.exe to minimise the output. +
    • +
    +

    The following minor changes were made:

    +
      +
    • + Failing if less than a threshold now applies to any assembly not meeting the threshold + rather than comparing against the total coverage across all assemblies. +
    • +
    • + Add some examples to the NCoverExplorer.Console.exe output for the /help or /? (or no arguments). +
    • +
    • + Pressing ESC on the NCover Runner dialog will now close it. +
    • +
    • + Implement a workaround for poor treeview performance under .NET 2.0. +
    • +
    • + Rather than displaying validation errors automatically "fix" paths with matching trailing + slashes in the Change Source Path dialog. +
    • +
    • + Writing of coverage files should now match the schema for the relevant NCover version. + Later NCover versions like 1.5.7 have enhanced the schema, so the results of a merge or + save from NCoverExplorer should offer a comparative schema in the result. +
    • +
    • + Add a message indicating the return code to the output. +
    • +
    +

    The following bug fixes were made:

    +
      +
    • + NCover 1.5.5/6 produce duplicate sequence points. To workaround this fix Jamie Cansdale implemented + a change for me to the way the methods are identified uniquely. The longer term fix is NCover version 1.5.7 + - this should keep things usable until that is released. +
    • +
    • + Another issue up to at least NCover 1.5.7 is that non-instrumented code does not have the sequence + points optimised. When merging multiple coverage files NCoverExplorer was incorrectly merging the noops with + valid instrumented sequence points, resulting in lower coverage information. +
    • +
    • + If CoverageReport.xsl stylesheet already exists in destination output folder for an xml report + and is marked as read-only then the replace would fail. +
    • +
    • + Drag/drop of coverage.xml files would add to the wrong end of the MRU menu once the maximum + number of items is reached. +
    • +
    • + If multiple classes in the same file then selecting a class node was not navigating to that + class in the source code tab. It will now jump to the first unvisited sequence point, or if + there are none of those the first sequence point in the class. +
    • +
    • + Wildcards for coverage exclusions were only working if placed at the ends, not in the middle + e.g. *.Tests or Testing.* would work, but xxx.*.yyy would not. +
    • +
    • + Prevent some of the nasty GDI errors in CommandBars code from disrupting the GUI. Longer + term will utilise another framework. +
    • +
    • + Replacing paths by typing them in had MaxLength set to 50 so impossible to edit long paths + in the Change Source Path dialog. +
    • +
    • + Merging property nodes under a parent in the tree has a dependency on the ordering of the coverage output + to ensure they appear properly. +
    • +
    • + When restoring form position from persisted values, ensure it appears on a visible screen, + catering for the user changing their display settings between sessions. +
    • +
    • + Ensure stylesheet cannot be copied over the top of itself. +
    • +
    • + Supplying a file pattern with no matches to NCoverExplorer.Console.exe was throwing an "Index was + outside the bounds of the array" exception. +
    • +
    • + Multiple coverage exclusion attributes not supplied correctly to NCover (build 26). +
    • +
    • + Check to make sure node is assigned to a TreeView before getting handle to set text (build 32). +
    • +
    • + Sort sequence point nodes when loading and handle merge case of multiple non-instrumented + sequence points becoming a single sequence point. (build 36). +
    • +
    +
    + +

    v1.3.5 - Oct 23rd 2006

    +

    Bundled with TestDriven.Net from build 2.0.1921.

    +

    The following new features were introduced:

    +
      +
    • + Added ability to run NCover from within NCoverExplorer (all versions). User Ctrl+N or + entries on File menu/toolbar to bring up configuration dialog. After successful + execution, the resultant coverage file is displayed in NCoverExplorer. +
    • +
    • + Added ability to generate MSBuild, NAnt and command-line scripts for running NCover + from within NCoverExplorer. See the NCover dialog above. +
    • +
    • + Added new function coverage viewing options and module/class coverage report. + Indicates the percentage of functions covered rather than the sequence points within each. + Supported by a new "satisfactory function threshold" and function % sorting options. +
    • +
    • + Background colours can now be customised for coverage nodes in the tree. +
    • +
    • + Reports will now have the current filtering applied, not just the sorting settings. +
    • +
    • + Reports using NCoverExplorer.Console can now have filtering and sorting applied. Use the + /sort: and /filter: command line arguments, or specify in a .config file (see example.config), + or use the sort/filter arguments to the NAnt/MSBuild tasks. +
    • +
    • + Sorting and filtering options applied are now persisted and reapplied to the next coverage + xml file loaded, both in this and future sessions. +
    • +
    • + Added ability to filter out all nodes exceeding coverage threshold. +
    • +
    • + Revamp to the NAnt/MSBuild tasks. Renamed assemblies and namespaces. Included new attribute of + "AssembliesList" as an alternative to the "Assemblies" group element to allow direct + specification of a list as you would on the command line. The "Version" attribute is now optional + - the task determines it from the NCover assembly instead if not specified. Tasks will automatically + register NCover coverlib.dll using the HKCU entry in the registry - no need for regsvr32 any more! + NCoverExplorer task now writes it's config file to temp folder for passing to the executable. +
    • +
    • + Added documentation for the NAnt and MSBuild tasks. This is included both in the NCoverExplorer.Extras.zip + file, as well as being available online for the custom MSBuild Task Help + and NAnt Task Help. + Links also available off the Help menu for NCoverExplorer. +
    • +
    • + Added a schema file ConsoleConfig.xsd to the distribution for people wanting to know the exact syntax + options for creating .config files to pass to NCoverExplorer.Console using the /config switch. +
    • +
    • + Added regular expression support to the coverage exclusions dialog for people wanting more complex queries. +
    • +
    +

    The following minor changes were made:

    +
      +
    • + Configuration file change - the ModuleThresholds section in .config files passed to NCoverExplorer.Console now + uses propercase attribute names to be consistent with the rest of the configuration file. + i.e. "ModuleName" instead of "moduleName", and "SatisfactoryCoverage" instead of "satisfactoryCoverage". You must update + your NAnt/MSBuild tasks for NCoverExplorer if you use these. If you instead use the <exec> task with a .config + file then you should update the case of the entries in this file. This only affects people who have setup coverage exclusions + at the module level for reporting purposes. +
    • +
    • + If source code is out of date compared to the coverage results, the user is prompted with + the change source path dialog. +
    • +
    • + If the user chooses a new source code location, the tab is now automatically opened for + that location rather than requiring the user to click on the tree node again. +
    • +
    • + Added Help->NCoverExplorer Forum menu option to link to the NCover website. Also included + forum link information on the exception dialog. +
    • +
    • + Added a toolbar button for turning off filtering. +
    • +
    • + Keyboard shortcut change - Changed the keyboard shortcuts for next/previous unvisited class (ALT+UP/DOWN) and + next/previous unvisited line in class (ALT+LEFT/RIGHT). +
    • +
    • + Remember which tab was last opened in the NCoverExplorer options dialog during an NCoverExplorer session. +
    • +
    • + Replaced references to "transparent.gif" with "shim.gif" in the NCoverExplorerSummary.xsl. The "shim.gif" + file is a transparent 1x1 gif already distributed with CC.Net. +
    • +
    • + Coverage exclusions for assemblies are now case insensitive. +
    • +
    • + There are no longer two default coverage exclusions added of "*.Tests" and "*.My*" for first time users. + Intended for demo purposes only but stayed in until now. New users can manually add them if they desire them. +
    • +
    +

    The following bug fixes were made:

    +
      +
    • + Overloaded constructors with class level variable declarations were being merged into a single + constructor in the coverage results as they had the same "start line" of the variable. Now uses + end line as part of the identifying key for each method. +
    • +
    • + Memory leak from opening and closing tabs displaying source code. +
    • +
    • + .Net 2.0 performance is pretty dire due to crap Microsoft changes to the TreeView control. + Change to default to .Net 1.1 in NCoverExplorer.exe.config and wrap updates to the tree + in BeginUpdate/EndUpdate. +
    • +
    • + Parsing Java code would blow up if an accessor had the same name as a nested class (illegal in C#). +
    • +
    • + Bugfix in NCover task where multiple assemblies were specified for NCover 1.5.4, which requires + separate <assembly> nodes. +
    • +
    • + Bugfix in trying to restore selected node text after refreshing file could raise + null reference exception. +
    • +
    • + Bugfix so that module names specified in module thresholds when using NCoverExplorer.Console + are no longer case sensitive for matching. +
    • +
    • + Added support for NCover 1.5.5 - the //q bug is fixed in NCover. Also changed parsing code so that modules + with a blank assembly name (through using TestDriven.Net) are ignored from the coverage. +
    • +
    • + Bugfix for merge functionality for NCover.Console when wildcards were used with relative paths. +
    • +
    • + Bugfix for naming of xml/html arguments for NCover.Console with relative file paths. +
    • +
    • + Bugfix for drag/drop broken while making the memory usage optimisations during the 1.3.5 beta release. +
    • +
    • + Print button was enabled when no source code displayed resulting in exception. +
    • +
    +
    + +

    v1.3.4 - Jul 10th 2006

    +

    Bundled with TestDriven.Net from build 2.0.1702.

    +

    The following new features were introduced:

    +
      +
    • + Added toolbar buttons which support moving to the next and previous unvisited code + within a class or namespace. Shortcut keys of N and P for next/previous unvisited line in the + current class (or mouse forward/back buttons). Use Ctrl+N and Ctrl+P to navigate to the + next/previous partially or unvisited class within the namespace (or Ctrl+forward/back mouse buttons). +
    • +
    • + NCoverExplorer.Console.exe now supports saving the merged results of the coverage xml file(s) with + a /s[ave] option. The NCoverExplorer NAnt and MSBuild tasks have also been enhanced to support this + with an optional "mergeFileName" attribute. +
    • +
    • + NCoverExplorer.Console.exe now supports wildcards for coverage xml filename(s). +
    • +
    • + NCoverExplorer.Console.exe now supports module level coverage thresholds, rather than just a project + coverage threshold. This feature allows finer tolerance for both output on the reports and to fail + a build. Specifying the module thresholds is done either through a .config file (see ConsoleExample.config) + or through parameters in the NAnt/MSBuild tasks. +
    • +
    • + Added a new summary report showing class coverage per namespace per module. +
    • +
    • + Enhanced the NCoverExplorerSummary.xsl to display summaries of each module. +
    • +
    • + Clicking on a class with non-existent source code displays a dialog allowing the user to specify an alternate + folder. For use when the source code location indicated within the coverage.xml file(s) loaded differs from + that on the local machine now (e.g. a different drive letter or folder path). +
    • +
    +

    The following minor changes were made:

    +
      +
    • + NCoverExplorer release is compiled against .Net 1.1 rather than .Net 1.0 due to a dependency on the + FolderBrowserDialog not available in .Net 1.0. +
    • +
    • + Coverage file stylesheet modified to show coverage column and NCoverExplorer version information with + numerous other cosmetic enhancements. +
    • +
    • + Enrich error environment information to include .Net framework version and operating system. +
    • +
    • + Classes without a namespace are now shown under a namespace node of "-" like in Reflector. +
    • +
    +

    The following bug fixes were made:

    +
      +
    • + Warnings about mismatches when merging xml files are no longer issued. NCover seems to inconsistently + produce xml file coverage of methods which caused some users problems when merging. +
    • +
    • + Nested classes without a namespace specified would cause the coverage.xml file to fail to load. +
    • +
    • + Parsing overloaded properties (overloads of this[]) would not show the separate overloads in the tree + and have incorrect coverage stats. +
    • +
    • + Fix memory leaks for when source code tabs are closed. +
    • +
    • + Minimum coverage threshold for NCoverExplorer.Console would sometimes be incorrect due to rounding. +
    • +
    • + Changed NCoverExplorerSummary.xsl to format to 1dp rather than rounding to 0. +
    • +
    • + Sorting by filename for a method then clicking on class node threw exception. +
    • +
    • + VB.Net source code keywords not highlighted with the correct ICSharpCode template. +
    • +
    +
    + +

    v1.3.3 - Apr 4th 2006

    +

    Bundled with TestDriven.Net from build 2.0.1578.

    +

    The following new features were introduced:

    +
      +
    • + Added NCoverExplorer.Console.exe for utilising NCoverExplorer features with automated + coverage builds and NAnt tasks. By default will load up all the specified coverage file(s), apply + any coverage exclusion(s) specified in the NCoverExplorer configuration and display total + coverage statistics in the console output. If all items processed successfully returns an exit code of 0, + if an exception occurs returns an exit code of 2. +
    • +
    • + Added /m:xx (or /minCoverage:xx) argument to NCoverExplorer.Console.exe. When used in conjunction with + /f (or /failMinimum) an exit code of 3 is returned if the min coverage is not reached. Can act + as a trigger for failing an automated build such as with CruiseControl.Net. +
    • +
    • + Added module & namespace summary xml report generation to NCoverExplorer (both the GUI and Console versions). + In the GUI, this is available via the "View->Reports" menu. The three reports that are offered currently are: +
       - Module Summary (Coverage totals for the project and per module); +
       - Namespace Summary (Coverage totals for the project and per namespace); +
       - Module Namespace Summary (Coverage totals for the project, per module and per namespace); +
    • +
    • + Reports can be generated in xml or html format. Native html may be useful for directly attaching to e-mails. + If xml format is chosen a "CoverageReport.xsl" stylesheet is copied from the NCoverExplorer installation + folder to the report directory and linked to the xml file similar to coverage.xml/coverage.xsl by NCover. +
    • +
    • + Reports can contain an "excluded nodes" footer section. This lists at the topmost level all of the items + excluded from coverage at the time the report was run. +
    • +
    • + Added "View->Filter" main menu and context menus, offering the ability to filter out nodes. Filtered + nodes are simply moved under a new "Filtered" tree node and do not alter the coverage statistics + (unlike excluded nodes which are effectively removed from the tree). Filters offered are either to + hide all 100% covered nodes, or hide all unvisited (0%) nodes. +
    • +
    • + Added "Include in Results" context menu option for when clicking on either the "Excluded" bin or one + of it's immediate child nodes. Offers a way to "undo" an exclusion without reloading the file. +
    • +
    • + Added "View->Summary Statistics" menu option (shortcut F3) to show dialog of totals of files, classes, members, + NCLOC (non-commented lines of code) and sequence points. Statistics do not include excluded nodes + (but will include filtered nodes). +
    • +
    • + Created NAnt and MSBuild tasks for execution of NCoverExplorer.Console as an alternative to the <exec> task. + These tasks offer a more developer friendly alternative such as <fileset> for coverage files and creating a + .config file on the fly based on specified parameters such as <exclusions> within the .build/.proj file. +
    • +
    • + Replaced menus with a lightly tweaked variant of Lutz Roeder's excellent CommandBar code to give a more modern + look and assign icons on the menus. +
    • +
    • + Added a toolbar. If not wanted the toolbar can be hidden using the "View->Show Toolbar" menu option. +
    • +
    +

    The following minor changes were made:

    +
      +
    • + Options dialog shortcut changed to F2. +
    • +
    • + Excluding a node will now select the node after by default rather than the one previous. +
    • +
    +

    The following bug fixes were made:

    +
      +
    • + Fix bug where delete key shortcut was active on the root coverage file node, causing an exception to be thrown. +
    • +
    • + Path was being truncated from the module name when saved. +
    • +
    • + Fix bug where changing theme without coverage file loaded caused error. +
    • +
    +
    + +

    v1.3.2 - Mar 14th 2006

    +

    Bundled with TestDriven.Net from build 2.0.1545.

    +

    The following new features were introduced:

    +
      +
    • + Added support for merging multiple coverage files. This can be triggered through a variety of ways: +
       - Selecting multiple test classes/fixtures/projects in TestDriven.Net; +
       - Passing multiple files in the command line arguments; +
       - Selecting multiple files in the Open dialog; +
       - Using a new "File->Merge..." menu option; +
       - Drag/dropping onto the NCoverExplorer application. +
    • +
    • + Added tabs for each source code file you open to explore coverage on. If you click on a partial class + then tabs will be opened for each of the source code files making up the class. +
    • +
    • + Added the ability to exclude assemblies, namespaces or classes from the coverage results by a wildcard capable + case-sensitive match on the name. By default NCoverExplorer includes two exclusions: +
       - Exclude all assemblies with the name ending in ".Tests". +
       - Exclude all namespaces with the name containing ".My" (for VB.Net exclusions). +
    • +
    • + Added support for the NCover 1.5.4 "excluded" attribute which can be found in the coverage.xml files when + the appropriate NCover command-line attributes are used. Note that TestDriven.Net still does not as yet + support this attribute so you need to use the NCover.Console command line for this feature - for more information see + here. NCoverExplorer + will not include nodes marked as 'excluded' by NCover in it's totals but will still display them in the tree. +
    • +
    • + Added an "Excluded" child bin node containing all nodes that have been excluded by the options dialog, by NCover + attributes or by the "Exclude From Results" context menu option (see next point). +
    • +
    • + Replaced the "Remove from Results" context menu feature with "Exclude from Results" (shortcut of the DEL key). + Achieves a similar result of removing nodes from coverage calculations, however the nodes are "moved" to the + Excluded bin rather than being deleted from the tree. +
    • +
    • + Added a custom "theme" capability along with further colour and font customisation options for the coverage tree, + statistics and source code panes. A number of predefined "themes" are supplied and users can add their own. + Users can switch between themes either in the Options dialog or via the "View->Themes" menu. +
    • +
    • + Added a new "View->Coverage" menu which has sub-options related to "Sequence Point Coverage" and + "Function Coverage", assigned shortcut keys ctrl+(1-4): +
       - Choosing one of the "Sequence Point" variants will display the tree nodes with differing naming + combinations of coverage percentage and # unvisited sequence points. +
       - Choosing "Function Coverage" will alter the coverage tree display so that only methods/classes that were + invoked are highlighted. Method nodes show the number of visits to that method. Class, namespace and module nodes + show the maximum visit count by any of their children. +
    • +
    • + Added a "View->Sort By" menu option and context menu on the tree, with sub-options for "Name" (default), + "Class name/line number", "Coverage %" (ascending/descending), "Uncovered Sequence Points" (ascending/descending) + and "Visit Counts" (ascending/descending). + Assigned shortcut keys of ctrl+shift+(1-8). Note that reloading the coverage file will remove the current sort + and default back to by "Name". +
    • +
    • + Added "Save" and "Save As" options to the File menu. These give you the option of overwriting/creating a + new coverage.xml file with the current values loaded in NCoverExplorer. Any coverage exclusions/removed + nodes will not appear in the saved coverage file. Note that the methods are written in the same order as + the sort order specified above. +
    • +
    • + Added an "Explore Coverage Folder" menu option to the file menu. +
    • +
    • + Added an "Expand All" context menu option on the tree (shortcut ctrl+L). +
    • +
    • + Enhanced the statistics pane. When a class node is selected you will now see additional columns of + coverage %, unvisited sequence points and sequence points. When clicking on a method node you will + now see the filename. +
    • +
    • + Implemented "smart expansion" in the tree. If when you expand a node there is only one child node + then that node will also be expanded and so on. Increases speed of tree navigation particularly + if using a style of "Nested" namespaces with deep hierarchies. +
    • +
    • + Display class file name in tab page header bar when a method node is clicked on. Tooltip shows the path. +
    • +
    +

    The following minor changes were made:

    +
      +
    • + Optimised when reloads of the coverage file so it is now only required if you change a coverage exclusion + or the tree grouping/nesting styles in the options dialog. Makes for a snappier UI. +
    • +
    • + Added a "Close" menu option to remove any loaded coverage file(s) from display. +
    • +
    • + Moved all the "Recent Files" into a submenu to tidy up the File menu. +
    • +
    • + Pressing Tab/shift-tab while focus is in the TextEditor pane of source code will now + move focus out of the TextEditor. +
    • +
    • + If a source code file contains multiple classes (not nested), then only the highlighting relevant + to that particular class will be displayed in the editor window as each class tree node is clicked. +
    • +
    • + Excluding the My namespace is now done through the Exclusions feature. +
    • +
    • + Options dialog can be displayed using the F4 shortcut key. +
    • +
    • + Removed last remnants of "non VS.Net standard colors" from the C# ICSharpCode TextEditor template. +
    • +
    • + Make the GUI naming consistent to correctly reference "sequence points" rather than "lines" and "unvisited" + rather than "uncovered". +
    • +
    • + Removed "Edit in VS.Net" from the View menu. +
    • +
    • + Changed NCoverExplorer main form icon to one that includes 32x32 sizes so Alt-Tab switching looks + better than upscaled 16x16 icon. +
    • +
    • + User is now prompted to remove a non-existent coverage file from the "Recent" files list rather than + automatically being removed. +
    • +
    +

    The following bug fixes were made:

    +
      +
    • + Serializing the configuration settings was not flushing the stream - resulting sometimes in a blank settings file + preventing people from loading NCoverExplorer. Will now revert to default settings if an error occurs. +
    • +
    • + Displaying a source code file that has been modified to have less lines of code than at the time of the coverage run + will now display a user friendly message box. +
    • +
    • + Compensation made for NCover not reporting column information when profiling C++ code. NCoverExplorer will now + highlight the entire line rather than throwing an error. +
    • +
    • + In some circumstances properties were not highlighted consistently due to a bug in the property node expansion. +
    • +
    • + Coverage greater than 99.5% will no longer be rounded up to 100% in the display. It is instead shown as ">99.5%". +
    • +
    • + Extremely high visit counts will no longer overflow the visit count. +
    • +
    • + Statistics pane for a class will now always consistently show the property nodes grouped, rather than only + after the class node has been expanded in the tree. +
    • +
    • + Recent file menu would display incorrectly for files numbered from 10 onwards truncating first character. +
    • +
    • + Release notes & FAQ were always directed to website rather than local versions when NCoverExplorer was started + from TestDriven.Net. +
    • +
    +
    + +

    v1.3.1 - Feb 15th 2006

    +

    Bundled with TestDriven.Net from build 2.0.1435.

    +

    The following new features were introduced:

    +
      +
    • + Namespaces are now "flattened" by default in the tree. This looks like the ClassView + browser in VS.Net 2005 (or Lutz Roeder's Reflector). You can retain the nested look by changing it in the View->Options dialog. +
    • +
    • + If you use the original "nested" namespace style (like the VS.Net 2003 class browser), then inner namespaces will now be + listed at the top of each branch with the classes listed underneath which is less confusing to navigate. +
    • +
    • + Option to exclude the "My" namespace for VB.Net projects (for use with with BCL 2.0 & NCover 1.5.x). +
    • +
    • + Right-click menu option on coverage tree (shortcut ctrl+R) to "Remove From Results" that selected node + and all it's children. Will force the coverage values to be recalculated. Intended for use where + you have undesired assemblies, namespaces, classes or methods included in the report that are skewing your + coverage results and you want them removed. +
    • +
    • + Option to specify a satisfactory coverage threshold as a number of lines instead/as well as a percentage. + If either of the conditions are met the node is coloured differently (provided the coverage is not zero). +
    • +
    • + Colours can now be customised for both the source code highlighting and the nodes in the tree. +
    • +
    • + Collapse all nodes context menu option on the coverage tree control (shortcut ctrl-A). Equivalent to reloading + the coverage file (but would preserve any changes you have made such as removing nodes). +
    • +
    • + By default the NCoverExplorer now attempts to restore your currently selected node/caret position after + reloading a coverage.xml file (either F5 or by execution of another "Test With Coverage" command in TestDriven.Net). + You can turn off this behaviour in the View->Options dialog. +
    • +
    • + Statistics pane is now sortable by method name (default), visit count and line number. +
    • +
    • + Statistics pane now summarises all the methods and their visit counts when a class node is clicked. + Can be used as a basic form of method invocation counting for a fairly rudimentary level of profiling. + The colouring used is the same as that of the tree to visually assist in identifying methods invoked. +
    • +
    +

    +

    The following minor changes were made:

    +
      +
    • + Restructured the Options dialog to have a tabbed interface. +
    • +
    • + Renamed the "Show Visit Pane" menu option to "Show Statistics". +
    • +
    • + The statistics pane now includes the method name. Widths of the columns are remembered each time you close NCoverExplorer. +
    • +
    • + Statistics pane now has icons and colouring to match those of the associated nodes in the coverage tree. +
    • +
    • + Inner nested classes now nested internally in the tree under the parent class, sorted to the top. +
    • +
    • + Added FAQ, Release Notes and Blog website to the Help menu. +
    • +
    +

    +

    The following bug fixes were made:

    +
      +
    • + Source code files now loading with "Encoding.Default" rather than previous default of UTF-8. +
    • +
    • + Coverage highlighting not working correctly on multiple line statements. +
    • +
    • + Now handles partial classes and yield statements correctly. +
    • +
    +

    +
    + +

    v1.3 - Feb 6th 2006

    +

    Bundled with TestDriven.Net from build 2.0.1373d.

    +

    The following new features were introduced:

    +
      +
    • + Launching from VS.Net using TestDriven.Net will now re-use the NCoverExplorer instance + opened from a previous "Test with... Coverage" click. Each VS.Net instance has it's own + instance of NCoverExplorer. +
    • +
    • + Added "Edit in VS.Net" functionality (keyboard shortcut ctrl+ E) for classes and methods. + Will navigate to source code in your IDE at same point where your cursor resides in NCoverExplorer. + Replaces and enhances previous "Open File" right-click option which has been removed. +
    • +
    • + Added "Expand Covered" functionality (keyboard shortcut ctrl + Q) - recurses through the child + nodes of the current node and expands all those with partial or complete coverage. Useful when + using in conjunction with TestDriven.Net for isolated unit testing. +
    • +
    • + Added "coverage file" node at the top of the tree showing total coverage across all modules/namespaces. +
    • +
    • + Group by module option (default) to assist with navigating coverage for large solutions. +
    • +
    • + Configuration information for NCoverExplorer now written to Local Settings rather than registry. +
    • +
    • + Increase default number of "recent files" to 10, with ability to alter in the Options dialog. +
    • +
    • + Reload of the current coverage file now has a shortcut key of F5. +
    • +
    • + Display the path to the currently loaded coverage file in the title bar. +
    • +
    +

    +

    The following minor changes were made:

    +
      +
    • + Performance enhancements to improve loading times further for large files. +
    • +
    • + Static constructors now renamed from "cctor" to ".cctor" so as to be sorted at the top. +
    • +
    • + Running NCoverExplorer for first time ever will use a better starting form position. +
    • +
    • + Removed configuration option for "nesting properties" - default remains the same of "true". +
    • +
    • + Source code refactoring into separate assemblies to facilitate unit testing. +
    • +
    +

    +
    +

    v1.2 - Feb 1st 2006

    +

    First public release, bundled with TestDriven.Net from build 2.0.1341d.

    +

    The following new features were introduced:

    +
      +
    • + Block style highlighting option for both visited and unvisited code. +
    • +
    • + Satisfactory coverage threshold. +
    • +
    • + Nesting of properties as nodes are expanded. +
    • +
    • + Further speed improvements for initial file parsing. +
    • +
    +

    +
    +

    v1.1 - Jan 1st 2006

    +

    Speed improvements.

    +
    +

    v1.0 - Dec 17th 2005

    +

    First version created.

    + + diff --git a/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/license.txt b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/license.txt new file mode 100644 index 00000000..3f5442da --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NCover/libs/NCoverExplorer/license.txt @@ -0,0 +1,299 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + EXCEPTION + + 13. In addition, as a special exception, AlphaSierraPapa gives permission to +link the code of this program with the Microsoft .NET library (or with +modified versions of Microsoft .NET library that use the same license as the +Microsoft .NET library), and distribute linked combinations including the +two. As a second exception, AlphaSierraPapa gives permission to link the code +of this program with the DockPanel Suite (or with modified versions of +DockPanel Suite that use the same license as the DockPanel Suite), and +distribute linked combinations including the two. You must obey the GNU +General Public License in all respects for all of the code used other than +the Microsoft .NET library and the DockPanel Suite. +If you modify this file, you may extend this exception to your version of the +file, but you are not obliged to do so. If you do not wish to do so, delete +this exception statement from your version. + + + + END OF TERMS AND CONDITIONS + diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Gallio.NUnitAdapter248.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Gallio.NUnitAdapter248.dll new file mode 100644 index 00000000..2a4f4a5d Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Gallio.NUnitAdapter248.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Gallio.NUnitAdapter248.plugin b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Gallio.NUnitAdapter248.plugin new file mode 100644 index 00000000..a65fecdb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Gallio.NUnitAdapter248.plugin @@ -0,0 +1,92 @@ + + + + NUnit v2.4.8 Adapter Plugin + 3.1.0.0 + Provides support for running NUnit v2.4.8 tests. + plugin://Gallio.NUnitAdapter248/Resources/NUnit.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + v2.4.8 + + + + + + NUnit v2.4.8 + nunit.framework, Version=2.4.8.0-2.4.8.65535 + 2.4.8.0 + Assembly + plugin://Gallio.NUnitAdapter248/Resources/NUnit.ico + + + + + + NUnit v2.4.8 Assembly + NUnit v2.4.8 Test Assembly + plugin://Gallio.NUnitAdapter248/Resources/NUnit.ico + + + + diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Readme.txt b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Readme.txt new file mode 100644 index 00000000..6fabc3be --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Readme.txt @@ -0,0 +1,12 @@ +NUnit Adapter Plugin +==================== + +This plugin uses the NUnit test runner to adapt NUnit tests so that +they can run within Gallio and be manipulated by Gallio-based tools. + +The plugin assembly is deliberately NOT signed using a strong name. +You can replace the underlying test framework with newer versions as +long as they are binary compatible with the originally distributed version. + +However, it may be necessary to update the version numbers that +appear in the plugin files. \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Resources/NUnit.ico b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Resources/NUnit.ico new file mode 100644 index 00000000..13c4ff9d Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/Resources/NUnit.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/addins/NUnit Addins Readme.txt b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/addins/NUnit Addins Readme.txt new file mode 100644 index 00000000..63e9a2b9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/addins/NUnit Addins Readme.txt @@ -0,0 +1 @@ +Put your Addins in this folder so that Gallio can find them. \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/license.txt b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/license.txt new file mode 100644 index 00000000..4beb762c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/license.txt @@ -0,0 +1,15 @@ +Copyright © 2002-2007 Charlie Poole +Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov +Copyright © 2000-2002 Philip A. Craig + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required. + +Portions Copyright © 2002-2007 Charlie Poole or Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.dll new file mode 100644 index 00000000..a31edfdd Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.extensions.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.extensions.dll new file mode 100644 index 00000000..ca1ce335 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.extensions.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.interfaces.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.interfaces.dll new file mode 100644 index 00000000..2c48764c Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.core.interfaces.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.dll new file mode 100644 index 00000000..2a0a0aa3 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.dll.tdnet b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.dll.tdnet new file mode 100644 index 00000000..9d7c5454 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.dll.tdnet @@ -0,0 +1,6 @@ + + NUnit v{0}.{1}.{2} + ..\..\TDNet\Gallio.TDNetRunner.dll + Gallio.TDNetRunner.GallioResidentTestRunner + Resident + diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.extensions.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.extensions.dll new file mode 100644 index 00000000..91e05857 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.framework.extensions.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.util.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.util.dll new file mode 100644 index 00000000..8f51b278 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.4.8/nunit.util.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Gallio.NUnitAdapter25.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Gallio.NUnitAdapter25.dll new file mode 100644 index 00000000..acf8f694 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Gallio.NUnitAdapter25.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Gallio.NUnitAdapter25.plugin b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Gallio.NUnitAdapter25.plugin new file mode 100644 index 00000000..09007069 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Gallio.NUnitAdapter25.plugin @@ -0,0 +1,85 @@ + + + + NUnit v2.5 Adapter Plugin + 3.1.0.0 + Provides support for running NUnit v2.5 tests. + plugin://Gallio.NUnitAdapter25/Resources/NUnit.ico + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + v2.5 + + + + + + NUnit v2.5 + nunit.framework, Version=2.5.0.0-2.5.2.65535 + 2.5.2.9222 + Assembly + plugin://Gallio.NUnitAdapter25/Resources/NUnit.ico + + + + + + NUnit v2.5 Assembly + NUnit v2.5 Test Assembly + plugin://Gallio.NUnitAdapter25/Resources/NUnit.ico + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Readme.txt b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Readme.txt new file mode 100644 index 00000000..6fabc3be --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Readme.txt @@ -0,0 +1,12 @@ +NUnit Adapter Plugin +==================== + +This plugin uses the NUnit test runner to adapt NUnit tests so that +they can run within Gallio and be manipulated by Gallio-based tools. + +The plugin assembly is deliberately NOT signed using a strong name. +You can replace the underlying test framework with newer versions as +long as they are binary compatible with the originally distributed version. + +However, it may be necessary to update the version numbers that +appear in the plugin files. \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Resources/NUnit.ico b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Resources/NUnit.ico new file mode 100644 index 00000000..13c4ff9d Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/Resources/NUnit.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/addins/NUnit Addins Readme.txt b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/addins/NUnit Addins Readme.txt new file mode 100644 index 00000000..63e9a2b9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/addins/NUnit Addins Readme.txt @@ -0,0 +1 @@ +Put your Addins in this folder so that Gallio can find them. \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/license.txt b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/license.txt new file mode 100644 index 00000000..66a5ebf2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/license.txt @@ -0,0 +1,15 @@ +Copyright © 2002-2008 Charlie Poole +Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov +Copyright © 2000-2002 Philip A. Craig + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment (see the following) in the product documentation is required. + +Portions Copyright © 2002-2008 Charlie Poole or Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig + +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.core.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.core.dll new file mode 100644 index 00000000..6fd79cf1 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.core.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.core.interfaces.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.core.interfaces.dll new file mode 100644 index 00000000..2794827b Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.core.interfaces.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.dll new file mode 100644 index 00000000..2729ddf2 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.dll.tdnet b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.dll.tdnet new file mode 100644 index 00000000..9d7c5454 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.dll.tdnet @@ -0,0 +1,6 @@ + + NUnit v{0}.{1}.{2} + ..\..\TDNet\Gallio.TDNetRunner.dll + Gallio.TDNetRunner.GallioResidentTestRunner + Resident + diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.xml b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.xml new file mode 100644 index 00000000..db09d607 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.framework.xml @@ -0,0 +1,10088 @@ + + + + nunit.framework + + + + + TypeConstraint is the abstract base for constraints + that take a Type as their expected value. + + + + + The Constraint class is the base of all built-in constraints + within NUnit. It provides the operator overloads used to combine + constraints. + + + + + The IConstraintExpression interface is implemented by all + complete and resolvable constraints and expressions. + + + + + Return the top-level constraint for this expression + + + + + + Static UnsetObject used to detect derived constraints + failing to set the actual value. + + + + + The actual value being tested against a constraint + + + + + The display name of this Constraint for use by ToString() + + + + + Argument fields used by ToString(); + + + + + The builder holding this constraint + + + + + Construct a constraint with no arguments + + + + + Construct a constraint with one argument + + + + + Construct a constraint with two arguments + + + + + Sets the ConstraintBuilder holding this constraint + + + + + Write the failure message to the MessageWriter provided + as an argument. The default implementation simply passes + the constraint and the actual value to the writer, which + then displays the constraint description and the value. + + Constraints that need to provide additional details, + such as where the error occured can override this. + + The MessageWriter on which to display the message + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Test whether the constraint is satisfied by an + ActualValueDelegate that returns the value to be tested. + The default implementation simply evaluates the delegate + but derived classes may override it to provide for delayed + processing. + + An ActualValueDelegate + True for success, false for failure + + + + Test whether the constraint is satisfied by a given reference. + The default implementation simply dereferences the value but + derived classes may override it to provide for delayed processing. + + A reference to the value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Default override of ToString returns the constraint DisplayName + followed by any arguments within angle brackets. + + + + + + This operator creates a constraint that is satisfied only if both + argument constraints are satisfied. + + + + + This operator creates a constraint that is satisfied if either + of the argument constraints is satisfied. + + + + + This operator creates a constraint that is satisfied if the + argument constraint is not satisfied. + + + + + Returns a DelayedConstraint with the specified delay time. + + The delay in milliseconds. + + + + + Returns a DelayedConstraint with the specified delay time + and polling interval. + + The delay in milliseconds. + The interval at which to test the constraint. + + + + + The display name of this Constraint for use by ToString(). + The default value is the name of the constraint with + trailing "Constraint" removed. Derived classes may set + this to another name in their constructors. + + + + + Returns a ConstraintExpression by appending And + to the current constraint. + + + + + Returns a ConstraintExpression by appending And + to the current constraint. + + + + + Returns a ConstraintExpression by appending Or + to the current constraint. + + + + + Class used to detect any derived constraints + that fail to set the actual value in their + Matches override. + + + + + The expected Type used by the constraint + + + + + Construct a TypeConstraint for a given Type + + + + + + Write the actual value for a failing constraint test to a + MessageWriter. TypeConstraints override this method to write + the name of the type. + + The writer on which the actual value is displayed + + + + ExactTypeConstraint is used to test that an object + is of the exact type provided in the constructor + + + + + Construct an ExactTypeConstraint for a given Type + + The expected Type. + + + + Test that an object is of the exact type specified + + The actual value. + True if the tested object is of the exact type provided, otherwise false. + + + + Write the description of this constraint to a MessageWriter + + The MessageWriter to use + + + + InstanceOfTypeConstraint is used to test that an object + is of the same type provided or derived from it. + + + + + Construct an InstanceOfTypeConstraint for the type provided + + The expected Type + + + + Test whether an object is of the specified type or a derived type + + The object to be tested + True if the object is of the provided type or derives from it, otherwise false. + + + + Write a description of this constraint to a MessageWriter + + The MessageWriter to use + + + + AssignableFromConstraint is used to test that an object + can be assigned from a given Type. + + + + + Construct an AssignableFromConstraint for the type provided + + + + + + Test whether an object can be assigned from the specified type + + The object to be tested + True if the object can be assigned a value of the expected Type, otherwise false. + + + + Write a description of this constraint to a MessageWriter + + The MessageWriter to use + + + + AssignableToConstraint is used to test that an object + can be assigned to a given Type. + + + + + Construct an AssignableToConstraint for the type provided + + + + + + Test whether an object can be assigned to the specified type + + The object to be tested + True if the object can be assigned a value of the expected Type, otherwise false. + + + + Write a description of this constraint to a MessageWriter + + The MessageWriter to use + + + + ConstraintBuilder maintains the stacks that are used in + processing a ConstraintExpression. An OperatorStack + is used to hold operators that are waiting for their + operands to be reognized. a ConstraintStack holds + input constraints as well as the results of each + operator applied. + + + + + Initializes a new instance of the class. + + + + + Appends the specified operator to the expression by first + reducing the operator stack and then pushing the new + operator on the stack. + + The operator to push. + + + + Appends the specified constraint to the expresson by pushing + it on the constraint stack. + + The constraint to push. + + + + Sets the top operator right context. + + The right context. + + + + Reduces the operator stack until the topmost item + precedence is greater than or equal to the target precedence. + + The target precedence. + + + + Resolves this instance, returning a Constraint. If the builder + is not currently in a resolvable state, an exception is thrown. + + The resolved constraint + + + + Gets a value indicating whether this instance is resolvable. + + + true if this instance is resolvable; otherwise, false. + + + + + OperatorStack is a type-safe stack for holding ConstraintOperators + + + + + Initializes a new instance of the class. + + The builder. + + + + Pushes the specified operator onto the stack. + + The op. + + + + Pops the topmost operator from the stack. + + + + + + Gets a value indicating whether this is empty. + + true if empty; otherwise, false. + + + + Gets the topmost operator without modifying the stack. + + The top. + + + + ConstraintStack is a type-safe stack for holding Constraints + + + + + Initializes a new instance of the class. + + The builder. + + + + Pushes the specified constraint. As a side effect, + the constraint's builder field is set to the + ConstraintBuilder owning this stack. + + The constraint. + + + + Pops this topmost constrait from the stack. + As a side effect, the constraint's builder + field is set to null. + + + + + + Gets a value indicating whether this is empty. + + true if empty; otherwise, false. + + + + Gets the topmost constraint without modifying the stack. + + The topmost constraint + + + + ThrowsConstraint is used to test the exception thrown by + a delegate by applying a constraint to it. + + + + + Abstract base class used for prefixes + + + + + The base constraint + + + + + Construct given a base constraint + + + + + + Initializes a new instance of the class, + using a constraint to be applied to the exception. + + A constraint to apply to the caught exception. + + + + Executes the code of the delegate and captures any exception. + If a non-null base constraint was provided, it applies that + constraint to the exception. + + A delegate representing the code to be tested + True if an exception is thrown and the constraint succeeds, otherwise false + + + + Converts an ActualValueDelegate to a TestDelegate + before calling the primary overload. + + + + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation of this constraint + + + + + Get the actual exception thrown - used by Assert.Throws. + + + + + ThrowsNothingConstraint tests that a delegate does not + throw an exception. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True if no exception is thrown, otherwise false + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + CollectionConstraint is the abstract base class for + constraints that operate on collections. + + + + + Construct an empty CollectionConstraint + + + + + Construct a CollectionConstraint + + + + + + Determines whether the specified enumerable is empty. + + The enumerable. + + true if the specified enumerable is empty; otherwise, false. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Protected method to be implemented by derived classes + + + + + + + CollectionItemsEqualConstraint is the abstract base class for all + collection constraints that apply some notion of item equality + as a part of their operation. + + + + + Construct an empty CollectionConstraint + + + + + Construct a CollectionConstraint + + + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied Comparison object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Compares two collection members for equality + + + + + Return a new CollectionTally for use in making tests + + The collection to be included in the tally + + + + Flag the constraint to ignore case and return self. + + + + + CollectionTally counts (tallies) the number of + occurences of each object in one or more enumerations. + + + + + Construct a CollectionTally object from a comparer and a collection + + + + + Try to remove an object from the tally + + The object to remove + True if successful, false if the object was not found + + + + Try to remove a set of objects from the tally + + The objects to remove + True if successful, false if any object was not found + + + + The number of objects remaining in the tally + + + + + EmptyCollectionConstraint tests whether a collection is empty. + + + + + Check that the collection is empty + + + + + + + Write the constraint description to a MessageWriter + + + + + + UniqueItemsConstraint tests whether all the items in a + collection are unique. + + + + + Check that all items are unique. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + CollectionContainsConstraint is used to test whether a collection + contains an expected object as a member. + + + + + Construct a CollectionContainsConstraint + + + + + + Test whether the expected item is contained in the collection + + + + + + + Write a descripton of the constraint to a MessageWriter + + + + + + CollectionEquivalentCOnstraint is used to determine whether two + collections are equivalent. + + + + + Construct a CollectionEquivalentConstraint + + + + + + Test whether two collections are equivalent + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + CollectionSubsetConstraint is used to determine whether + one collection is a subset of another + + + + + Construct a CollectionSubsetConstraint + + The collection that the actual value is expected to be a subset of + + + + Test whether the actual collection is a subset of + the expected collection provided. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + CollectionOrderedConstraint is used to test whether a collection is ordered. + + + + + Construct a CollectionOrderedConstraint + + + + + Modifies the constraint to use an IComparer and returns self. + + + + + Modifies the constraint to use an IComparer<T> and returns self. + + + + + Modifies the constraint to use a Comparison<T> and returns self. + + + + + Modifies the constraint to test ordering by the value of + a specified property and returns self. + + + + + Test whether the collection is ordered + + + + + + + Write a description of the constraint to a MessageWriter + + + + + + Returns the string representation of the constraint. + + + + + + If used performs a reverse comparison + + + + + EmptyDirectoryConstraint is used to test that a directory is empty + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + SubDirectoryConstraint is used to test that one directory is a subdirectory of another. + + + + + Initializes a new instance of the class. + + The dir info. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Builds a list of DirectoryInfo objects, recursing where necessary + + directory to recurse + list of DirectoryInfo objects from the top level + + + + private method to determine whether a directory is within the path + + top-level directory to search + directory to search for + true if found, false if not + + + + Method to compare two DirectoryInfo objects + + first directory to compare + second directory to compare + true if equivalent, false if not + + + + PathConstraint serves as the abstract base of constraints + that operate on paths and provides several helper methods. + + + + + The expected path used in the constraint + + + + + Flag indicating whether a caseInsensitive comparison should be made + + + + + Construct a PathConstraint for a give expected path + + The expected path + + + + Returns the string representation of this constraint + + + + + Canonicalize the provided path + + + The path in standardized form + + + + Test whether two paths are the same + + The first path + The second path + + + + + Test whether one path is the same as or under another path + + The first path - supposed to be the parent path + The second path - supposed to be the child path + + + + + Modifies the current instance to be case-insensitve + and returns it. + + + + + Modifies the current instance to be case-sensitve + and returns it. + + + + + Summary description for SamePathConstraint. + + + + + Initializes a new instance of the class. + + The expected path + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + SamePathOrUnderConstraint tests that one path is under another + + + + + Initializes a new instance of the class. + + The expected path + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + PropertyExistsConstraint tests that a named property + exists on the object provided through Match. + + Originally, PropertyConstraint provided this feature + in addition to making optional tests on the vaue + of the property. The two constraints are now separate. + + + + + Initializes a new instance of the class. + + The name of the property. + + + + Test whether the property exists for a given object + + The object to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. + + The writer on which the actual value is displayed + + + + Returns the string representation of the constraint. + + + + + + PropertyConstraint extracts a named property and uses + its value as the actual value for a chained constraint. + + + + + Initializes a new instance of the class. + + The name. + The constraint to apply to the property. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation of the constraint. + + + + + + ConstraintExpression represents a compound constraint in the + process of being constructed from a series of syntactic elements. + + Individual elements are appended to the expression as they are + reognized. Once an actual Constraint is appended, the expression + returns a resolvable Constraint. + + + + + ConstraintExpressionBase is the abstract base class for the + generated ConstraintExpression class, which represents a + compound constraint in the process of being constructed + from a series of syntactic elements. + + NOTE: ConstraintExpressionBase is aware of some of its + derived classes, which is an apparent violation of + encapsulation. Ideally, these classes would be a + single class, but they must be separated in order to + allow parts to be generated under .NET 1.x and to + provide proper user feedback in syntactically + aware IDEs. + + + + + The ConstraintBuilder holding the elements recognized so far + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the + class passing in a ConstraintBuilder, which may be pre-populated. + + The builder. + + + + Returns a string representation of the expression as it + currently stands. This should only be used for testing, + since it has the side-effect of resolving the expression. + + + + + + Appends an operator to the expression and returns the + resulting expression itself. + + + + + Appends a self-resolving operator to the expression and + returns a new ResolvableConstraintExpression. + + + + + Appends a constraint to the expression and returns that + constraint, which is associated with the current state + of the expression being built. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the + class passing in a ConstraintBuilder, which may be pre-populated. + + The builder. + + + + Returns a new PropertyConstraintExpression, which will either + test for the existence of the named property on the object + being tested or apply any following constraint to that property. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns the constraint provided as an argument - used to allow custom + custom constraints to easily participate in the syntax. + + + + + Returns the constraint provided as an argument - used to allow custom + custom constraints to easily participate in the syntax. + + + + + Returns a constraint that tests two items for equality + + + + + Returns a constraint that tests that two references are the same object + + + + + Returns a constraint that tests whether the + actual value is greater than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a collection containing the same elements as the + collection supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a subset of the collection supplied as an argument. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new ContainsConstraint. This constraint + will, in turn, make use of the appropriate second-level + constraint, depending on the type of the actual argument. + This overload is only used if the item sought is a string, + since any other type implies that we are looking for a + collection member. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that tests whether the path provided + is the same as an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the actual value falls + within a specified range. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if at least one of them succeeds. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them fail. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Length property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Count property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Message property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the InnerException property of the object being tested. + + + + + With is currently a NOP - reserved for future use. + + + + + Returns a constraint that tests for null + + + + + Returns a constraint that tests for True + + + + + Returns a constraint that tests for False + + + + + Returns a constraint that tests for NaN + + + + + Returns a constraint that tests for empty + + + + + Returns a constraint that tests whether a collection + contains all unique items. + + + + + Returns a constraint that tests whether an object graph is serializable in binary format. + + + + + Returns a constraint that tests whether an object graph is serializable in xml format. + + + + + Returns a constraint that tests whether a collection is ordered + + + + + RangeConstraint tests whethe two values are within a + specified range. + + + + + Initializes a new instance of the class. + + From. + To. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Modifies the constraint to use an IComparer and returns self. + + + + + Modifies the constraint to use an IComparer<T> and returns self. + + + + + Modifies the constraint to use a Comparison<T> and returns self. + + + + + EqualConstraint is able to compare an actual value with the + expected value provided in its constructor. Two objects are + considered equal if both are null, or if both have the same + value. NUnit has special semantics for some object types. + + + + + If true, strings in error messages will be clipped + + + + + NUnitEqualityComparer used to test equality. + + + + + Initializes a new instance of the class. + + The expected value. + + + + Flag the constraint to use a tolerance when determining equality. + + Tolerance value to be used + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied Comparison object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Flag the constraint to use the supplied IEqualityComparer object. + + The IComparer object to use. + Self. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write a failure message. Overridden to provide custom + failure messages for EqualConstraint. + + The MessageWriter to write to + + + + Write description of this constraint + + The MessageWriter to write to + + + + Display the failure information for two collections that did not match. + + The MessageWriter on which to display + The expected collection. + The actual collection + The depth of this failure in a set of nested collections + + + + Displays a single line showing the types and sizes of the expected + and actual collections or arrays. If both are identical, the value is + only shown once. + + The MessageWriter on which to display + The expected collection or array + The actual collection or array + The indentation level for the message line + + + + Displays a single line showing the point in the expected and actual + arrays at which the comparison failed. If the arrays have different + structures or dimensions, both values are shown. + + The MessageWriter on which to display + The expected array + The actual array + Index of the failure point in the underlying collections + The indentation level for the message line + + + + Flag the constraint to ignore case and return self. + + + + + Flag the constraint to suppress string clipping + and return self. + + + + + Flag the constraint to compare arrays as collections + and return self. + + + + + Switches the .Within() modifier to interpret its tolerance as + a distance in representable values (see remarks). + + Self. + + Ulp stands for "unit in the last place" and describes the minimum + amount a given value can change. For any integers, an ulp is 1 whole + digit. For floating point values, the accuracy of which is better + for smaller numbers and worse for larger numbers, an ulp depends + on the size of the number. Using ulps for comparison of floating + point results instead of fixed tolerances is safer because it will + automatically compensate for the added inaccuracy of larger numbers. + + + + + Switches the .Within() modifier to interpret its tolerance as + a percentage that the actual values is allowed to deviate from + the expected value. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in days. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in hours. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in minutes. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in seconds. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in milliseconds. + + Self + + + + Causes the tolerance to be interpreted as a TimeSpan in clock ticks. + + Self + + + + NotConstraint negates the effect of some other constraint + + + + + Initializes a new instance of the class. + + The base constraint to be negated. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for if the base constraint fails, false if it succeeds + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a MessageWriter. + + The writer on which the actual value is displayed + + + + AllItemsConstraint applies another constraint to each + item in a collection, succeeding if they all succeed. + + + + + Construct an AllItemsConstraint on top of an existing constraint + + + + + + Apply the item constraint to each item in the collection, + failing if any item fails. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + SomeItemsConstraint applies another constraint to each + item in a collection, succeeding if any of them succeeds. + + + + + Construct a SomeItemsConstraint on top of an existing constraint + + + + + + Apply the item constraint to each item in the collection, + succeeding if any item succeeds. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + NoItemConstraint applies another constraint to each + item in a collection, failing if any of them succeeds. + + + + + Construct a SomeItemsConstraint on top of an existing constraint + + + + + + Apply the item constraint to each item in the collection, + failing if any item fails. + + + + + + + Write a description of this constraint to a MessageWriter + + + + + + ContainsConstraint tests a whether a string contains a substring + or a collection contains an object. It postpones the decision of + which test to use until the type of the actual argument is known. + This allows testing whether a string is contained in a collection + or as a substring of another string using the same syntax. + + + + + Initializes a new instance of the class. + + The expected. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Flag the constraint to ignore case and return self. + + + + + Static methods used in creating messages + + + + + Static string used when strings are clipped + + + + + Returns the representation of a type as used in NUnitLite. + This is the same as Type.ToString() except for arrays, + which are displayed with their declared sizes. + + + + + + + Converts any control characters in a string + to their escaped representation. + + The string to be converted + The converted string + + + + Return the a string representation for a set of indices into an array + + Array of indices for which a string is needed + + + + Get an array of indices representing the point in a collection or + array corresponding to a single int index into the collection. + + The collection to which the indices apply + Index in the collection + Array of indices + + + + Clip a string to a given length, starting at a particular offset, returning the clipped + string with ellipses representing the removed parts + + The string to be clipped + The maximum permitted length of the result string + The point at which to start clipping + The clipped string + + + + Clip the expected and actual strings in a coordinated fashion, + so that they may be displayed together. + + + + + + + + + Shows the position two strings start to differ. Comparison + starts at the start index. + + The expected string + The actual string + The index in the strings at which comparison should start + Boolean indicating whether case should be ignored + -1 if no mismatch found, or the index where mismatch found + + + + BasicConstraint is the abstract base for constraints that + perform a simple comparison to a constant value. + + + + + Initializes a new instance of the class. + + The expected. + The description. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + NullConstraint tests that the actual value is null + + + + + Initializes a new instance of the class. + + + + + TrueConstraint tests that the actual value is true + + + + + Initializes a new instance of the class. + + + + + FalseConstraint tests that the actual value is false + + + + + Initializes a new instance of the class. + + + + + NaNConstraint tests that the actual value is a double or float NaN + + + + + Test that the actual value is an NaN + + + + + + + Write the constraint description to a specified writer + + + + + + MessageWriter is the abstract base for classes that write + constraint descriptions and messages in some form. The + class has separate methods for writing various components + of a message, allowing implementations to tailor the + presentation as needed. + + + + + Construct a MessageWriter given a culture + + + + + Method to write single line message with optional args, usually + written to precede the general failure message. + + The message to be written + Any arguments used in formatting the message + + + + Method to write single line message with optional args, usually + written to precede the general failure message, at a givel + indentation level. + + The indentation level of the message + The message to be written + Any arguments used in formatting the message + + + + Display Expected and Actual lines for a constraint. This + is called by MessageWriter's default implementation of + WriteMessageTo and provides the generic two-line display. + + The constraint that failed + + + + Display Expected and Actual lines for given values. This + method may be called by constraints that need more control over + the display of actual and expected values than is provided + by the default implementation. + + The expected value + The actual value causing the failure + + + + Display Expected and Actual lines for given values, including + a tolerance value on the Expected line. + + The expected value + The actual value causing the failure + The tolerance within which the test was made + + + + Display the expected and actual string values on separate lines. + If the mismatch parameter is >=0, an additional line is displayed + line containing a caret that points to the mismatch point. + + The expected string value + The actual string value + The point at which the strings don't match or -1 + If true, case is ignored in locating the point where the strings differ + If true, the strings should be clipped to fit the line + + + + Writes the text for a connector. + + The connector. + + + + Writes the text for a predicate. + + The predicate. + + + + Writes the text for an expected value. + + The expected value. + + + + Writes the text for a modifier + + The modifier. + + + + Writes the text for an actual value. + + The actual value. + + + + Writes the text for a generalized value. + + The value. + + + + Writes the text for a collection value, + starting at a particular point, to a max length + + The collection containing elements to write. + The starting point of the elements to write + The maximum number of elements to write + + + + Abstract method to get the max line length + + + + + Modes in which the tolerance value for a comparison can + be interpreted. + + + + + The tolerance was created with a value, without specifying + how the value would be used. This is used to prevent setting + the mode more than once and is generally changed to Linear + upon execution of the test. + + + + + The tolerance is used as a numeric range within which + two compared values are considered to be equal. + + + + + Interprets the tolerance as the percentage by which + the two compared values my deviate from each other. + + + + + Compares two values based in their distance in + representable numbers. + + + + + The Tolerance class generalizes the notion of a tolerance + within which an equality test succeeds. Normally, it is + used with numeric types, but it can be used with any + type that supports taking a difference between two + objects and comparing that difference to a value. + + + + + Constructs a linear tolerance of a specdified amount + + + + + Constructs a tolerance given an amount and ToleranceMode + + + + + Tests that the current Tolerance is linear with a + numeric value, throwing an exception if it is not. + + + + + Returns an empty Tolerance object, equivalent to + specifying an exact match. + + + + + Gets the ToleranceMode for the current Tolerance + + + + + Gets the value of the current Tolerance instance. + + + + + Returns a new tolerance, using the current amount as a percentage. + + + + + Returns a new tolerance, using the current amount in Ulps. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of days. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of hours. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of minutes. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of seconds. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of milliseconds. + + + + + Returns a new tolerance with a TimeSpan as the amount, using + the current amount as a number of clock ticks. + + + + + Returns true if the current tolerance is empty. + + + + + The Numerics class contains common operations on numeric values. + + + + + Checks the type of the object, returning true if + the object is a numeric type. + + The object to check + true if the object is a numeric type + + + + Checks the type of the object, returning true if + the object is a floating point numeric type. + + The object to check + true if the object is a floating point numeric type + + + + Checks the type of the object, returning true if + the object is a fixed point numeric type. + + The object to check + true if the object is a fixed point numeric type + + + + Test two numeric values for equality, performing the usual numeric + conversions and using a provided or default tolerance. If the tolerance + provided is Empty, this method may set it to a default tolerance. + + The expected value + The actual value + A reference to the tolerance in effect + True if the values are equal + + + + Compare two numeric values, performing the usual numeric conversions. + + The expected value + The actual value + The relationship of the values to each other + + + + EmptyConstraint tests a whether a string or collection is empty, + postponing the decision about which test is applied until the + type of the actual argument is known. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + StringConstraint is the abstract base for constraints + that operate on strings. It supports the IgnoreCase + modifier for string operations. + + + + + The expected value + + + + + Indicates whether tests should be case-insensitive + + + + + Constructs a StringConstraint given an expected value + + The expected value + + + + Modify the constraint to ignore case in matching. + + + + + EmptyStringConstraint tests whether a string is empty. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + NullEmptyStringConstraint tests whether a string is either null or empty. + + + + + Constructs a new NullOrEmptyStringConstraint + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + SubstringConstraint can test whether a string contains + the expected substring. + + + + + Initializes a new instance of the class. + + The expected. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + StartsWithConstraint can test whether a string starts + with an expected substring. + + + + + Initializes a new instance of the class. + + The expected string + + + + Test whether the constraint is matched by the actual value. + This is a template method, which calls the IsMatch method + of the derived class. + + + + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + EndsWithConstraint can test whether a string ends + with an expected substring. + + + + + Initializes a new instance of the class. + + The expected string + + + + Test whether the constraint is matched by the actual value. + This is a template method, which calls the IsMatch method + of the derived class. + + + + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + RegexConstraint can test whether a string matches + the pattern provided. + + + + + Initializes a new instance of the class. + + The pattern. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Abstract base class for constraints that compare values to + determine if one is greater than, equal to or less than + the other. + + + + + The value against which a comparison is to be made + + + + + If true, less than returns success + + + + + if true, equal returns success + + + + + if true, greater than returns success + + + + + The predicate used as a part of the description + + + + + ComparisonAdapter to be used in making the comparison + + + + + Initializes a new instance of the class. + + The value against which to make a comparison. + if set to true less succeeds. + if set to true equal succeeds. + if set to true greater succeeds. + String used in describing the constraint. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Modifies the constraint to use an IComparer and returns self + + + + + Modifies the constraint to use an IComparer<T> and returns self + + + + + Modifies the constraint to use a Comparison<T> and returns self + + + + + Tests whether a value is greater than the value supplied to its constructor + + + + + Initializes a new instance of the class. + + The expected value. + + + + Tests whether a value is greater than or equal to the value supplied to its constructor + + + + + Initializes a new instance of the class. + + The expected value. + + + + Tests whether a value is less than the value supplied to its constructor + + + + + Initializes a new instance of the class. + + The expected value. + + + + Tests whether a value is less than or equal to the value supplied to its constructor + + + + + Initializes a new instance of the class. + + The expected value. + + + + SameAsConstraint tests whether an object is identical to + the object passed to its constructor + + + + + Initializes a new instance of the class. + + The expected object. + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + BinaryConstraint is the abstract base of all constraints + that combine two other constraints in some fashion. + + + + + The first constraint being combined + + + + + The second constraint being combined + + + + + Construct a BinaryConstraint from two other constraints + + The first constraint + The second constraint + + + + AndConstraint succeeds only if both members succeed. + + + + + Create an AndConstraint from two other constraints + + The first constraint + The second constraint + + + + Apply both member constraints to an actual value, succeeding + succeeding only if both of them succeed. + + The actual value + True if the constraints both succeeded + + + + Write a description for this contraint to a MessageWriter + + The MessageWriter to receive the description + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + OrConstraint succeeds if either member succeeds + + + + + Create an OrConstraint from two other constraints + + The first constraint + The second constraint + + + + Apply the member constraints to an actual value, succeeding + succeeding as soon as one of them succeeds. + + The actual value + True if either constraint succeeded + + + + Write a description for this contraint to a MessageWriter + + The MessageWriter to receive the description + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a new PropertyConstraintExpression, which will either + test for the existence of the named property on the object + being tested or apply any following constraint to that property. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a constraint that tests two items for equality + + + + + Returns a constraint that tests that two references are the same object + + + + + Returns a constraint that tests whether the + actual value is greater than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a collection containing the same elements as the + collection supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a subset of the collection supplied as an argument. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a new ContainsConstraint. This constraint + will, in turn, make use of the appropriate second-level + constraint, depending on the type of the actual argument. + This overload is only used if the item sought is a string, + since any other type implies that we are looking for a + collection member. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that fails if the actual + value matches the pattern supplied as an argument. + + + + + Returns a constraint that tests whether the path provided + is the same as an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the actual value falls + within a specified range. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if at least one of them succeeds. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them fail. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Length property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Count property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Message property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the InnerException property of the object being tested. + + + + + Returns a constraint that tests for null + + + + + Returns a constraint that tests for True + + + + + Returns a constraint that tests for False + + + + + Returns a constraint that tests for NaN + + + + + Returns a constraint that tests for empty + + + + + Returns a constraint that tests whether a collection + contains all unique items. + + + + + Returns a constraint that tests whether an object graph is serializable in binary format. + + + + + Returns a constraint that tests whether an object graph is serializable in xml format. + + + + + Returns a constraint that tests whether a collection is ordered + + + + + Applies a delay to the match so that a match can be evaluated in the future. + + + + + Creates a new DelayedConstraint + + The inner constraint two decorate + The time interval after which the match is performed + If the value of is less than 0 + + + + Creates a new DelayedConstraint + + The inner constraint two decorate + The time interval after which the match is performed + The time interval used for polling + If the value of is less than 0 + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for if the base constraint fails, false if it succeeds + + + + Test whether the constraint is satisfied by a delegate + + The delegate whose value is to be tested + True for if the base constraint fails, false if it succeeds + + + + Test whether the constraint is satisfied by a given reference. + Overridden to wait for the specified delay period before + calling the base constraint with the dereferenced value. + + A reference to the value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a MessageWriter. + + The writer on which the actual value is displayed + + + + Returns the string representation of the constraint. + + + + + NUnitComparer encapsulates NUnit's default behavior + in comparing two objects. + + + + + Compares two objects + + + + + + + + Returns the default NUnitComparer. + + + + + Delegate used to delay evaluation of the actual value + to be used in evaluating a constraint + + + + + NUnitEqualityComparer encapsulates NUnit's handling of + equality tests between objects. + + + + + If true, all string comparisons will ignore case + + + + + If true, arrays will be treated as collections, allowing + those of different dimensions to be compared + + + + + If non-zero, equality comparisons within the specified + tolerance will succeed. + + + + + Comparison object used in comparisons for some constraints. + + + + + Compares two objects for equality. + + + + + Helper method to compare two arrays + + + + + Method to compare two DirectoryInfo objects + + first directory to compare + second directory to compare + true if equivalent, false if not + + + + Returns the default NUnitEqualityComparer + + + + + Gets and sets a flag indicating whether case should + be ignored in determining equality. + + + + + Gets and sets a flag indicating that arrays should be + compared as collections, without regard to their shape. + + + + + Gets and sets an external comparer to be used to + test for equality. It is applied to members of + collections, in place of NUnit's own logic. + + + + + Gets and sets a tolerance used to compare objects of + certin types. + + + + + Gets the list of failure points for the last Match performed. + + + + + ComparisonAdapter class centralizes all comparisons of + values in NUnit, adapting to the use of any provided + IComparer, IComparer<T> or Comparison<T> + + + + + Returns a ComparisonAdapter that wraps an IComparer + + + + + Returns a ComparisonAdapter that wraps an IComparer<T> + + + + + Returns a ComparisonAdapter that wraps a Comparison<T> + + + + + Compares two objects + + + + + Gets the default ComparisonAdapter, which wraps an + NUnitComparer object. + + + + + Construct a ComparisonAdapter for an IComparer + + + + + Compares two objects + + + + + + + + Construct a default ComparisonAdapter + + + + + ComparisonAdapter<T> extends ComparisonAdapter and + allows use of an IComparer<T> or Comparison<T> + to actually perform the comparison. + + + + + Construct a ComparisonAdapter for an IComparer<T> + + + + + Compare a Type T to an object + + + + + Construct a ComparisonAdapter for a Comparison<T> + + + + + Compare a Type T to an object + + + + + The ConstraintOperator class is used internally by a + ConstraintBuilder to represent an operator that + modifies or combines constraints. + + Constraint operators use left and right precedence + values to determine whether the top operator on the + stack should be reduced before pushing a new operator. + + + + + The precedence value used when the operator + is about to be pushed to the stack. + + + + + The precedence value used when the operator + is on the top of the stack. + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + The syntax element preceding this operator + + + + + The syntax element folowing this operator + + + + + The precedence value used when the operator + is about to be pushed to the stack. + + + + + The precedence value used when the operator + is on the top of the stack. + + + + + PrefixOperator takes a single constraint and modifies + it's action in some way. + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + Returns the constraint created by applying this + prefix to another constraint. + + + + + + + Negates the test of the constraint it wraps. + + + + + Constructs a new NotOperator + + + + + Returns a NotConstraint applied to its argument. + + + + + Abstract base for operators that indicate how to + apply a constraint to items in a collection. + + + + + Constructs a CollectionOperator + + + + + Represents a constraint that succeeds if all the + members of a collection match a base constraint. + + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + they all succeed. + + + + + Represents a constraint that succeeds if any of the + members of a collection match a base constraint. + + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + any of them succeed. + + + + + Represents a constraint that succeeds if none of the + members of a collection match a base constraint. + + + + + Returns a constraint that will apply the argument + to the members of a collection, succeeding if + none of them succeed. + + + + + Represents a constraint that simply wraps the + constraint provided as an argument, without any + further functionality, but which modifes the + order of evaluation because of its precedence. + + + + + Constructor for the WithOperator + + + + + Returns a constraint that wraps its argument + + + + + Abstract base class for operators that are able to reduce to a + constraint whether or not another syntactic element follows. + + + + + Operator used to test for the presence of a named Property + on an object and optionally apply further tests to the + value of that property. + + + + + Constructs a PropOperator for a particular named property + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + Gets the name of the property to which the operator applies + + + + + Operator that tests for the presence of a particular attribute + on a type and optionally applies further tests to the attribute. + + + + + Construct an AttributeOperator for a particular Type + + The Type of attribute tested + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + Operator that tests that an exception is thrown and + optionally applies further tests to the exception. + + + + + Construct a ThrowsOperator + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + Abstract base class for all binary operators + + + + + Reduce produces a constraint from the operator and + any arguments. It takes the arguments from the constraint + stack and pushes the resulting constraint on it. + + + + + + Abstract method that produces a constraint by applying + the operator to its left and right constraint arguments. + + + + + Gets the left precedence of the operator + + + + + Gets the right precedence of the operator + + + + + Operator that requires both it's arguments to succeed + + + + + Construct an AndOperator + + + + + Apply the operator to produce an AndConstraint + + + + + Operator that requires at least one of it's arguments to succeed + + + + + Construct an OrOperator + + + + + Apply the operator to produce an OrConstraint + + + + + BinarySerializableConstraint tests whether + an object is serializable in binary format. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation + + + + + BinarySerializableConstraint tests whether + an object is serializable in binary format. + + + + + Test whether the constraint is satisfied by a given value + + The value to be tested + True for success, false for failure + + + + Write the constraint description to a MessageWriter + + The writer on which the description is displayed + + + + Write the actual value for a failing constraint test to a + MessageWriter. The default implementation simply writes + the raw value of actual, leaving it to the writer to + perform any formatting. + + The writer on which the actual value is displayed + + + + Returns the string representation of this constraint + + + + + ResolvableConstraintExpression is used to represent a compound + constraint being constructed at a point where the last operator + may either terminate the expression or may have additional + qualifying constraints added to it. + + It is used, for example, for a Property element or for + an Exception element, either of which may be optionally + followed by constraints that apply to the property or + exception. + + + + + Create a new instance of ResolvableConstraintExpression + + + + + Create a new instance of ResolvableConstraintExpression, + passing in a pre-populated ConstraintBuilder. + + + + + Resolve the current expression to a Constraint + + + + + Appends an And Operator to the expression + + + + + Appends an Or operator to the expression. + + + + + EqualityAdapter class handles all equality comparisons + that use an IEqualityComparer, IEqualityComparer<T> + or a ComparisonAdapter. + + + + + Compares two objects, returning true if they are equal + + + + + Returns an EqualityAdapter that wraps an IComparer. + + + + + Returns an EqualityAdapter that wraps an IEqualityComparer. + + + + + Returns an EqualityAdapter that wraps an IEqualityComparer<T>. + + + + + Returns an EqualityAdapter that wraps an IComparer<T>. + + + + + Returns an EqualityAdapter that wraps a Comparison<T>. + + + + + AttributeExistsConstraint tests for the presence of a + specified attribute on a Type. + + + + + Constructs an AttributeExistsConstraint for a specific attribute Type + + + + + + Tests whether the object provides the expected attribute. + + A Type, MethodInfo, or other ICustomAttributeProvider + True if the expected attribute is present, otherwise false + + + + Writes the description of the constraint to the specified writer + + + + + AttributeConstraint tests that a specified attribute is present + on a Type or other provider and that the value of the attribute + satisfies some other constraint. + + + + + Constructs an AttributeConstraint for a specified attriute + Type and base constraint. + + + + + + + Determines whether the Type or other provider has the + expected attribute and if its value matches the + additional constraint specified. + + + + + Writes a description of the attribute to the specified writer. + + + + + Writes the actual value supplied to the specified writer. + + + + + Returns a string representation of the constraint. + + + + Helper routines for working with floating point numbers + + + The floating point comparison code is based on this excellent article: + http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm + + + "ULP" means Unit in the Last Place and in the context of this library refers to + the distance between two adjacent floating point numbers. IEEE floating point + numbers can only represent a finite subset of natural numbers, with greater + accuracy for smaller numbers and lower accuracy for very large numbers. + + + If a comparison is allowed "2 ulps" of deviation, that means the values are + allowed to deviate by up to 2 adjacent floating point values, which might be + as low as 0.0000001 for small numbers or as high as 10.0 for large numbers. + + + + + Compares two floating point values for equality + First floating point value to be compared + Second floating point value t be compared + + Maximum number of representable floating point values that are allowed to + be between the left and the right floating point values + + True if both numbers are equal or close to being equal + + + Floating point values can only represent a finite subset of natural numbers. + For example, the values 2.00000000 and 2.00000024 can be stored in a float, + but nothing inbetween them. + + + This comparison will count how many possible floating point values are between + the left and the right number. If the number of possible values between both + numbers is less than or equal to maxUlps, then the numbers are considered as + being equal. + + + Implementation partially follows the code outlined here: + http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ + + + + + Compares two double precision floating point values for equality + First double precision floating point value to be compared + Second double precision floating point value t be compared + + Maximum number of representable double precision floating point values that are + allowed to be between the left and the right double precision floating point values + + True if both numbers are equal or close to being equal + + + Double precision floating point values can only represent a limited series of + natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004 + can be stored in a double, but nothing inbetween them. + + + This comparison will count how many possible double precision floating point + values are between the left and the right number. If the number of possible + values between both numbers is less than or equal to maxUlps, then the numbers + are considered as being equal. + + + Implementation partially follows the code outlined here: + http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/ + + + + + + Reinterprets the memory contents of a floating point value as an integer value + + + Floating point value whose memory contents to reinterpret + + + The memory contents of the floating point value interpreted as an integer + + + + + Reinterprets the memory contents of a double precision floating point + value as an integer value + + + Double precision floating point value whose memory contents to reinterpret + + + The memory contents of the double precision floating point value + interpreted as an integer + + + + + Reinterprets the memory contents of an integer as a floating point value + + Integer value whose memory contents to reinterpret + + The memory contents of the integer value interpreted as a floating point value + + + + + Reinterprets the memory contents of an integer value as a double precision + floating point value + + Integer whose memory contents to reinterpret + + The memory contents of the integer interpreted as a double precision + floating point value + + + + Union of a floating point variable and an integer + + + The union's value as a floating point variable + + + The union's value as an integer + + + The union's value as an unsigned integer + + + Union of a double precision floating point variable and a long + + + The union's value as a double precision floating point variable + + + The union's value as a long + + + The union's value as an unsigned long + + + + Predicate constraint wraps a Predicate in a constraint, + returning success if the predicate is true. + + + + + Construct a PredicateConstraint from a predicate + + + + + Determines whether the predicate succeeds when applied + to the actual value. + + + + + Writes the description to a MessageWriter + + + + + The TestCaseData class represents a set of arguments + and other parameter info to be used for a parameterized + test case. It provides a number of instance modifiers + for use in initializing the test case. + + Note: Instance modifiers are getters that return + the same instance after modifying it's state. + + + + + The ITestCaseData interface is implemented by a class + that is able to return complete testcases for use by + a parameterized test method. + + NOTE: This interface is used in both the framework + and the core, even though that results in two different + types. However, sharing the source code guarantees that + the various implementations will be compatible and that + the core is able to reflect successfully over the + framework implementations of ITestCaseData. + + + + + Gets the argument list to be provided to the test + + + + + Gets the expected result + + + + + Gets the expected exception Type + + + + + Gets the FullName of the expected exception + + + + + Gets the name to be used for the test + + + + + Gets the description of the test + + + + + Gets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets the ignore reason. + + The ignore reason. + + + + The argument list to be provided to the test + + + + + The expected result to be returned + + + + + The expected exception Type + + + + + The FullName of the expected exception + + + + + The name to be used for the test + + + + + The description of the test + + + + + A dictionary of properties, used to add information + to tests without requiring the class to change. + + + + + If true, indicates that the test case is to be ignored + + + + + The reason for ignoring a test case + + + + + Initializes a new instance of the class. + + The arguments. + + + + Initializes a new instance of the class. + + The argument. + + + + Initializes a new instance of the class. + + The first argument. + The second argument. + + + + Initializes a new instance of the class. + + The first argument. + The second argument. + The third argument. + + + + Sets the expected result for the test + + The expected result + A modified TestCaseData + + + + Sets the expected exception type for the test + + Type of the expected exception. + The modified TestCaseData instance + + + + Sets the expected exception type for the test + + FullName of the expected exception. + The modified TestCaseData instance + + + + Sets the name of the test case + + The modified TestCaseData instance + + + + Sets the description for the test case + being constructed. + + The description. + The modified TestCaseData instance. + + + + Applies a category to the test + + + + + + + Applies a named property to the test + + + + + + + + Applies a named property to the test + + + + + + + + Applies a named property to the test + + + + + + + + Ignores this TestCase. + + + + + + Ignores this TestCase, specifying the reason. + + The reason. + + + + + Gets the argument list to be provided to the test + + + + + Gets the expected result + + + + + Gets the expected exception Type + + + + + Gets the FullName of the expected exception + + + + + Gets the name to be used for the test + + + + + Gets the description of the test + + + + + Gets a value indicating whether this is ignored. + + true if ignored; otherwise, false. + + + + Gets the ignore reason. + + The ignore reason. + + + + Gets a list of categories associated with this test. + + + + + Gets the property dictionary for this test + + + + + FactoryAttribute indicates the source to be used to + provide test cases for a test method. + + + + + Construct with the name of the factory - for use with languages + that don't support params arrays. + + An array of the names of the factories that will provide data + + + + Construct with a Type and name - for use with languages + that don't support params arrays. + + The Type that will provide data + The name of the method, property or field that will provide data + + + + The name of a the method, property or fiend to be used as a source + + + + + A Type to be used as a source + + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a new PropertyConstraintExpression, which will either + test for the existence of the named property on the object + being tested or apply any following constraint to that property. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new AttributeConstraint checking for the + presence of a particular attribute on an object. + + + + + Returns a new CollectionContainsConstraint checking for the + presence of a particular object in the collection. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if at least one of them succeeds. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them fail. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Length property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Count property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the Message property of the object being tested. + + + + + Returns a new ConstraintExpression, which will apply the following + constraint to the InnerException property of the object being tested. + + + + + The List class is a helper class with properties and methods + that supply a number of constraints used with lists and collections. + + + + + List.Map returns a ListMapper, which can be used to map + the original collection to another collection. + + + + + + + Enumeration indicating how the expected message parameter is to be used + + + + Expect an exact match + + + Expect a message containing the parameter string + + + Match the regular expression provided as a parameter + + + Expect a message that starts with the parameter string + + + + ExpectedExceptionAttribute + + + + + + Constructor for a non-specific exception + + + + + Constructor for a given type of exception + + The type of the expected exception + + + + Constructor for a given exception name + + The full name of the expected exception + + + + Gets or sets the expected exception type + + + + + Gets or sets the full Type name of the expected exception + + + + + Gets or sets the expected message text + + + + + Gets or sets the user message displayed in case of failure + + + + + Gets or sets the type of match to be performed on the expected message + + + + + Gets the name of a method to be used as an exception handler + + + + + TestCaseAttribute is used to mark parameterized test cases + and provide them with their arguments. + + + + + Construct a TestCaseAttribute with a list of arguments. + This constructor is not CLS-Compliant + + + + + + Construct a TestCaseAttribute with a single argument + + + + + + Construct a TestCaseAttribute with a two arguments + + + + + + + Construct a TestCaseAttribute with a three arguments + + + + + + + + Gets the list of arguments to a test case + + + + + Gets or sets the expected result. + + The result. + + + + Gets or sets the expected exception. + + The expected exception. + + + + Gets or sets the name the expected exception. + + The expected name of the exception. + + + + Gets or sets the expected message of the expected exception + + The expected message of the exception. + + + + Gets or sets the type of match to be performed on the expected message + + + + + Gets or sets the description. + + The description. + + + + Gets or sets the name of the test. + + The name of the test. + + + + Gets or sets the ignored status of the test + + + + + Gets or sets the ignored status of the test + + + + + Gets the ignore reason. + + The ignore reason. + + + + Thrown when an assertion failed. + + + + + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + Thrown when a test executes inconclusively. + + + + + The error message that explains + the reason for the exception + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + Delegate used by tests that execute code and + capture any thrown exception. + + + + + The Assert class contains a collection of static methods that + implement the most common assertions used in NUnit. + + + + + We don't actually want any instances of this object, but some people + like to inherit from it to add other static methods. Hence, the + protected constructor disallows any instances of this object. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Helper for Assert.AreEqual(double expected, double actual, ...) + allowing code generation to work consistently. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Throws a with the message and arguments + that are passed in. This allows a test to be cut short, with a result + of success returned to NUnit. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws a with the message and arguments + that are passed in. This allows a test to be cut short, with a result + of success returned to NUnit. + + The message to initialize the with. + + + + Throws a with the message and arguments + that are passed in. This allows a test to be cut short, with a result + of success returned to NUnit. + + + + + Throws an with the message and arguments + that are passed in. This is used by the other Assert functions. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws an with the message that is + passed in. This is used by the other Assert functions. + + The message to initialize the with. + + + + Throws an . + This is used by the other Assert functions. + + + + + Throws an with the message and arguments + that are passed in. This causes the test to be reported as ignored. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws an with the message that is + passed in. This causes the test to be reported as ignored. + + The message to initialize the with. + + + + Throws an . + This causes the test to be reported as ignored. + + + + + Throws an with the message and arguments + that are passed in. This causes the test to be reported as inconclusive. + + The message to initialize the with. + Arguments to be used in formatting the message + + + + Throws an with the message that is + passed in. This causes the test to be reported as inconclusive. + + The message to initialize the with. + + + + Throws an . + This causes the test to be reported as Inconclusive. + + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + + + + Asserts that the code represented by a delegate throws an exception + that satisfies the constraint provided. + + A TestDelegate to be executed + A ThrowsConstraint used in the test + + + + Verifies that a delegate throws a particular exception when called. + + A constraint to be satisfied by the exception + A TestSnippet delegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + A constraint to be satisfied by the exception + A TestSnippet delegate + The message that will be displayed on failure + + + + Verifies that a delegate throws a particular exception when called. + + A constraint to be satisfied by the exception + A TestSnippet delegate + + + + Verifies that a delegate throws a particular exception when called. + + The exception Type expected + A TestSnippet delegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + The exception Type expected + A TestSnippet delegate + The message that will be displayed on failure + + + + Verifies that a delegate throws a particular exception when called. + + The exception Type expected + A TestSnippet delegate + + + + Verifies that a delegate throws a particular exception when called. + + Type of the expected exception + A TestSnippet delegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws a particular exception when called. + + Type of the expected exception + A TestSnippet delegate + The message that will be displayed on failure + + + + Verifies that a delegate throws a particular exception when called. + + Type of the expected exception + A TestSnippet delegate + + + + Verifies that a delegate throws an exception when called + and returns it. + + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws an exception when called + and returns it. + + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws an exception when called + and returns it. + + A TestDelegate + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + The message that will be displayed on failure + + + + Verifies that a delegate throws an exception of a certain Type + or one derived from it when called and returns it. + + The expected Exception Type + A TestDelegate + + + + Verifies that a delegate does not throw an exception + + A TestSnippet delegate + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Verifies that a delegate does not throw an exception. + + A TestSnippet delegate + The message that will be displayed on failure + + + + Verifies that a delegate does not throw an exception. + + A TestSnippet delegate + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + The message to display in case of failure + + + + Asserts that a condition is false. If the condition is true the method throws + an . + + The evaluated condition + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is not equal to null + If the object is null then an + is thrown. + + The object that is to be tested + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + The message to display in case of failure + + + + Verifies that the object that is passed in is equal to null + If the object is not null then an + is thrown. + + The object that is to be tested + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + The message to display in case of failure + + + + Verifies that the double that is passed in is an NaN value. + If the object is not NaN then an + is thrown. + + The value that is to be tested + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is empty - that is equal to string.Empty + + The string to be tested + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing ICollection + + + + Assert that a string is not empty - that is not equal to string.Empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is not empty - that is not equal to string.Empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is not empty - that is not equal to string.Empty + + The string to be tested + + + + Assert that an array, list or other collection is not empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that an array, list or other collection is not empty + + An array, list or other collection implementing ICollection + The message to display in case of failure + + + + Assert that an array, list or other collection is not empty + + An array, list or other collection implementing ICollection + + + + Assert that a string is either null or equal to string.Empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is either null or equal to string.Empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is either null or equal to string.Empty + + The string to be tested + + + + Assert that a string is not null or empty + + The string to be tested + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Assert that a string is not null or empty + + The string to be tested + The message to display in case of failure + + + + Assert that a string is not null or empty + + The string to be tested + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + The message to display in case of failure + + + + Asserts that an object may not be assigned a value of a given Type. + + The expected Type. + The object under examination + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + The message to display in case of failure + + + + Asserts that an object is not an instance of a given type. + + The expected Type + The object being examined + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are equal. If they are not, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + The message to display in case of failure + + + + Verifies that two doubles are equal considering a delta. If the + expected value is infinity then the delta value is ignored. If + they are not equal then an is + thrown. + + The expected value + The actual value + The maximum acceptable difference between the + the expected and the actual + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are not equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are not equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + + + + Verifies that two objects are equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are not equal an is thrown. + + The value that is expected + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + The message to display in case of failure + + + + Verifies that two values are not equal. If they are equal, then an + is thrown. + + The expected value + The actual value + + + + Verifies that two objects are not equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that two objects are not equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are equal an is thrown. + + The value that is expected + The actual value + The message to display in case of failure + + + + Verifies that two objects are not equal. Two objects are considered + equal if both are null, or if both have the same value. NUnit + has special semantics for some object types. + If they are equal an is thrown. + + The value that is expected + The actual value + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + + + + Asserts that two objects refer to the same object. If they + are not the same an is thrown. + + The expected object + The actual object + + + + Asserts that two objects do not refer to the same object. If they + are the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that two objects do not refer to the same object. If they + are the same an is thrown. + + The expected object + The actual object + The message to display in case of failure + + + + Asserts that two objects do not refer to the same object. If they + are the same an is thrown. + + The expected object + The actual object + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than the second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + The message to display in case of failure + + + + Verifies that the first value is greater than or equal tothe second + value. If it is not, then an + is thrown. + + The first value, expected to be greater + The second value, expected to be less + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + The message to display in case of failure + + + + Verifies that the first value is less than or equal to the second + value. If it is not, then an + is thrown. + + The first value, expected to be less + The second value, expected to be greater + + + + Asserts that an object is contained in a list. + + The expected object + The list to be examined + The message to display in case of failure + Array of objects to be used in formatting the message + + + + Asserts that an object is contained in a list. + + The expected object + The list to be examined + The message to display in case of failure + + + + Asserts that an object is contained in a list. + + The expected object + The list to be examined + + + + Gets the number of assertions executed so far and + resets the counter to zero. + + + + + RequiredAddinAttribute may be used to indicate the names of any addins + that must be present in order to run some or all of the tests in an + assembly. If the addin is not loaded, the entire assembly is marked + as NotRunnable. + + + + + Initializes a new instance of the class. + + The required addin. + + + + Gets the name of required addin. + + The required addin name. + + + + Marks a test to use a combinatorial join of any argument + data provided. Since this is the default, the attribute is + not needed. + + + + + PropertyAttribute is used to attach information to a test as a name/value pair.. + + + + + Construct a PropertyAttribute with a name and string value + + The name of the property + The property value + + + + Construct a PropertyAttribute with a name and int value + + The name of the property + The property value + + + + Construct a PropertyAttribute with a name and double value + + The name of the property + The property value + + + + Constructor for derived classes that set the + property dictionary directly. + + + + + Constructor for use by derived classes that use the + name of the type as the property name. Derived classes + must ensure that the Type of the property value is + a standard type supported by the BCL. Any custom + types will cause a serialization Exception when + in the client. + + + + + Gets the property dictionary for this attribute + + + + + Default constructor + + + + + Marks a test to use a combinatorial join of any argument + data provided. Since this is the default, the attribute is + not needed. + + + + + Default constructor + + + + + Marks a test to use a combinatorial join of any argument + data provided. Since this is the default, the attribute is + not needed. + + + + + Default constructor + + + + + Adding this attribute to a method within a + class makes the method callable from the NUnit test runner. There is a property + called Description which is optional which you can provide a more detailed test + description. This class cannot be inherited. + + + + [TestFixture] + public class Fixture + { + [Test] + public void MethodToTest() + {} + + [Test(Description = "more detailed description")] + publc void TestDescriptionMethod() + {} + } + + + + + + Descriptive text for this test + + + + + [TestFixture] + public class ExampleClass + {} + + + + + Default constructor + + + + + Construct with a object[] representing a set of arguments. + In .NET 2.0, the arguments may later be separated into + type arguments and constructor arguments. + + + + + + Descriptive text for this fixture + + + + + The arguments originally provided to the attribute + + + + + Gets or sets a value indicating whether this should be ignored. + + true if ignore; otherwise, false. + + + + Gets or sets the ignore reason. May set Ignored as a side effect. + + The ignore reason. + + + + Get or set the type arguments. If not set + explicitly, any leading arguments that are + Types are taken as type arguments. + + + + + A set of Assert methods operationg on one or more collections + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + IEnumerable containing objects to be considered + System.Type that all objects in collection must be instances of + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + IEnumerable containing objects to be considered + System.Type that all objects in collection must be instances of + The message that will be displayed on failure + + + + Asserts that all items contained in collection are of the type specified by expectedType. + + IEnumerable containing objects to be considered + System.Type that all objects in collection must be instances of + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that all items contained in collection are not equal to null. + + IEnumerable containing objects to be considered + + + + Asserts that all items contained in collection are not equal to null. + + IEnumerable containing objects to be considered + The message that will be displayed on failure + + + + Asserts that all items contained in collection are not equal to null. + + IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + IEnumerable of objects to be considered + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Ensures that every object contained in collection exists within the collection + once and only once. + + IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are exactly equal. The collections must have the same count, + and contain the exact same objects in the same order. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are not exactly equal. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + + + + Asserts that expected and actual are not exactly equal. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + + + + Asserts that expected and actual are not exactly equal. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are not exactly equal. + If comparer is not null then it will be used to compare the objects. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The IComparer to use in comparing objects from each IEnumerable + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that expected and actual are not equivalent. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + + + + Asserts that expected and actual are not equivalent. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + + + + Asserts that expected and actual are not equivalent. + + The first IEnumerable of objects to be considered + The second IEnumerable of objects to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that collection contains actual as an item. + + IEnumerable of objects to be considered + Object to be found within collection + + + + Asserts that collection contains actual as an item. + + IEnumerable of objects to be considered + Object to be found within collection + The message that will be displayed on failure + + + + Asserts that collection contains actual as an item. + + IEnumerable of objects to be considered + Object to be found within collection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that collection does not contain actual as an item. + + IEnumerable of objects to be considered + Object that cannot exist within collection + + + + Asserts that collection does not contain actual as an item. + + IEnumerable of objects to be considered + Object that cannot exist within collection + The message that will be displayed on failure + + + + Asserts that collection does not contain actual as an item. + + IEnumerable of objects to be considered + Object that cannot exist within collection + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that superset is not a subject of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + + + + Asserts that superset is not a subject of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + + + + Asserts that superset is not a subject of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that superset is a subset of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + + + + Asserts that superset is a subset of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + + + + Asserts that superset is a subset of subset. + + The IEnumerable superset to be considered + The IEnumerable subset to be considered + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing IEnumerable + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is empty + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + + + + Assert that an array,list or other collection is empty + + An array, list or other collection implementing IEnumerable + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + The message to be displayed on failure + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + A custom comparer to perform the comparisons + The message to be displayed on failure + Arguments to be used in formatting the message + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + A custom comparer to perform the comparisons + The message to be displayed on failure + + + + Assert that an array, list or other collection is ordered + + An array, list or other collection implementing IEnumerable + A custom comparer to perform the comparisons + + + + Abstract base class for attributes that apply to parameters + and supply data for the parameter. + + + + + Gets the data to be provided to the specified parameter + + + + + ValuesAttribute is used to provide literal arguments for + an individual parameter of a test. + + + + + The collection of data to be returned. Must + be set by any derived attribute classes. + + + + + Construct with one argument + + + + + + Construct with two arguments + + + + + + + Construct with three arguments + + + + + + + + Construct with an array of arguments + + + + + + Get the collection of values to be used as arguments + + + + + Thrown when an assertion failed. + + + + + The error message that explains + the reason for the exception + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + WUsed on a method, marks the test with a timeout value in milliseconds. + The test will be run in a separate thread and is cancelled if the timeout + is exceeded. Used on a method or assembly, sets the default timeout + for all contained test methods. + + + + + Construct a TimeoutAttribute given a time in milliseconds + + The timeout value in milliseconds + + + + Marks a test that must run in the STA, causing it + to run in a separate thread if necessary. + + On methods, you may also use STAThreadAttribute + to serve the same purpose. + + + + + Construct a RequiresSTAAttribute + + + + + Marks a test that must run in the MTA, causing it + to run in a separate thread if necessary. + + On methods, you may also use MTAThreadAttribute + to serve the same purpose. + + + + + Construct a RequiresMTAAttribute + + + + + Marks a test that must run on a separate thread. + + + + + Construct a RequiresThreadAttribute + + + + + Construct a RequiresThreadAttribute, specifying the apartment + + + + + AssertionHelper is an optional base class for user tests, + allowing the use of shorter names for constraints and + asserts and avoiding conflict with the definition of + , from which it inherits much of its + behavior, in certain mock object frameworks. + + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. Works + identically to + + A Constraint to be applied + The actual value to test + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. Works + identically to + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. Works + identically to + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an assertion exception on failure. + + A Constraint to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . Works Identically to + . + + The evaluated condition + The message to display if the condition is false + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . Works Identically to + . + + The evaluated condition + The message to display if the condition is false + + + + Asserts that a condition is true. If the condition is false the method throws + an . Works Identically to . + + The evaluated condition + + + + Asserts that the code represented by a delegate throws an exception + that satisfies the constraint provided. + + A TestDelegate to be executed + A ThrowsConstraint used in the test + + + + Returns a ListMapper based on a collection. + + The original collection + + + + + Attribute used to apply a category to a test + + + + + The name of the category + + + + + Construct attribute for a given category + + The name of the category + + + + Protected constructor uses the Type name as the name + of the category. + + + + + The name of the category + + + + + RandomAttribute is used to supply a set of random values + to a single parameter of a parameterized test. + + + + + Construct a set of doubles from 0.0 to 1.0, + specifying only the count. + + + + + + Construct a set of doubles from min to max + + + + + + + + Construct a set of ints from min to max + + + + + + + + Get the collection of values to be used as arguments + + + + + Attribute used to provide descriptive text about a + test case or fixture. + + + + + Construct the attribute + + Text describing the test + + + + Gets the test description + + + + + ExplicitAttribute marks a test or test fixture so that it will + only be run if explicitly executed from the gui or command line + or if it is included by use of a filter. The test will not be + run simply because an enclosing suite is run. + + + + + Default constructor + + + + + Constructor with a reason + + The reason test is marked explicit + + + + The reason test is marked explicit + + + + + Provides static methods to express the assumptions + that must be met for a test to give a meaningful + result. If an assumption is not met, the test + should produce an inconclusive result. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + An ActualValueDelegate returning the value to be tested + The message that will be displayed on failure + + + + Apply a constraint to an actual value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + An ActualValueDelegate returning the value to be tested + A Constraint expression to be applied + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + + + + Apply a constraint to a referenced value, succeeding if the constraint + is satisfied and throwing an InconclusiveException on failure. + + A Constraint expression to be applied + The actual value to test + The message that will be displayed on failure + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + Arguments to be used in formatting the message + + + + Asserts that a condition is true. If the condition is false the method throws + an . + + The evaluated condition + The message to display if the condition is false + + + + Asserts that a condition is true. If the condition is false the + method throws an . + + The evaluated condition + + + + Asserts that the code represented by a delegate throws an exception + that satisfies the constraint provided. + + A TestDelegate to be executed + A ThrowsConstraint used in the test + + + + GlobalSettings is a place for setting default values used + by the framework in performing asserts. + + + + + Default tolerance for floating point equality + + + + + Helper class with properties and methods that supply + a number of constraints used in Asserts. + + + + + Returns a constraint that tests two items for equality + + + + + Returns a constraint that tests that two references are the same object + + + + + Returns a constraint that tests whether the + actual value is greater than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is greater than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the + actual value is less than or equal to the suppled argument + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual + value is of the exact type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is of the type supplied as an argument or a derived type. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is assignable from the type supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a collection containing the same elements as the + collection supplied as an argument. + + + + + Returns a constraint that tests whether the actual value + is a subset of the collection supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that tests whether the path provided + is the same as an expected path after canonicalization. + + + + + Returns a constraint that tests whether the path provided + is the same path or under an expected path after canonicalization. + + + + + Returns a constraint that tests whether the actual value falls + within a specified range. + + + + + Returns a ConstraintExpression that negates any + following constraint. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Returns a constraint that tests for null + + + + + Returns a constraint that tests for True + + + + + Returns a constraint that tests for False + + + + + Returns a constraint that tests for NaN + + + + + Returns a constraint that tests for empty + + + + + Returns a constraint that tests whether a collection + contains all unique items. + + + + + Returns a constraint that tests whether an object graph is serializable in binary format. + + + + + Returns a constraint that tests whether an object graph is serializable in xml format. + + + + + Returns a constraint that tests whether a collection is ordered + + + + + Interface implemented by a user fixture in order to + validate any expected exceptions. It is only called + for test methods marked with the ExpectedException + attribute. + + + + + Method to handle an expected exception + + The exception to be handled + + + + Attribute used to mark a test that is to be ignored. + Ignored tests result in a warning message when the + tests are run. + + + + + Constructs the attribute without giving a reason + for ignoring the test. + + + + + Constructs the attribute giving a reason for ignoring the test + + The reason for ignoring the test + + + + The reason for ignoring a test + + + + + Thrown when an assertion failed. + + + + + + + The error message that explains + the reason for the exception + The exception that caused the + current exception + + + + Serialization Constructor + + + + + Abstract base for Attributes that are used to include tests + in the test run based on environmental settings. + + + + + Constructor with no included items specified, for use + with named property syntax. + + + + + Constructor taking one or more included items + + Comma-delimited list of included items + + + + Name of the item that is needed in order for + a test to run. Multiple itemss may be given, + separated by a comma. + + + + + Name of the item to be excluded. Multiple items + may be given, separated by a comma. + + + + + The reason for including or excluding the test + + + + + PlatformAttribute is used to mark a test fixture or an + individual method as applying to a particular platform only. + + + + + Constructor with no platforms specified, for use + with named property syntax. + + + + + Constructor taking one or more platforms + + Comma-deliminted list of platforms + + + + CultureAttribute is used to mark a test fixture or an + individual method as applying to a particular Culture only. + + + + + Constructor with no cultures specified, for use + with named property syntax. + + + + + Constructor taking one or more cultures + + Comma-deliminted list of cultures + + + + RangeAttribute is used to supply a range of values to an + individual parameter of a parameterized test. + + + + + Construct a range of ints using default step of 1 + + + + + + + Construct a range of ints specifying the step size + + + + + + + + Construct a range of longs + + + + + + + + Construct a range of doubles + + + + + + + + Construct a range of floats + + + + + + + + Summary description for SetCultureAttribute. + + + + + Construct given the name of a culture + + + + + + ValueSourceAttribute indicates the source to be used to + provide data for one parameter of a test method. + + + + + Construct with the name of the factory - for use with languages + that don't support params arrays. + + The name of the data source to be used + + + + Construct with a Type and name - for use with languages + that don't support params arrays. + + The Type that will provide data + The name of the method, property or field that will provide data + + + + The name of a the method, property or fiend to be used as a source + + + + + A Type to be used as a source + + + + + TextMessageWriter writes constraint descriptions and messages + in displayable form as a text stream. It tailors the display + of individual message components to form the standard message + format of NUnit assertion failure messages. + + + + + Prefix used for the expected value line of a message + + + + + Prefix used for the actual value line of a message + + + + + Length of a message prefix + + + + + Construct a TextMessageWriter + + + + + Construct a TextMessageWriter, specifying a user message + and optional formatting arguments. + + + + + + + Method to write single line message with optional args, usually + written to precede the general failure message, at a givel + indentation level. + + The indentation level of the message + The message to be written + Any arguments used in formatting the message + + + + Display Expected and Actual lines for a constraint. This + is called by MessageWriter's default implementation of + WriteMessageTo and provides the generic two-line display. + + The constraint that failed + + + + Display Expected and Actual lines for given values. This + method may be called by constraints that need more control over + the display of actual and expected values than is provided + by the default implementation. + + The expected value + The actual value causing the failure + + + + Display Expected and Actual lines for given values, including + a tolerance value on the expected line. + + The expected value + The actual value causing the failure + The tolerance within which the test was made + + + + Display the expected and actual string values on separate lines. + If the mismatch parameter is >=0, an additional line is displayed + line containing a caret that points to the mismatch point. + + The expected string value + The actual string value + The point at which the strings don't match or -1 + If true, case is ignored in string comparisons + If true, clip the strings to fit the max line length + + + + Writes the text for a connector. + + The connector. + + + + Writes the text for a predicate. + + The predicate. + + + + Write the text for a modifier. + + The modifier. + + + + Writes the text for an expected value. + + The expected value. + + + + Writes the text for an actual value. + + The actual value. + + + + Writes the text for a generalized value. + + The value. + + + + Writes the text for a collection value, + starting at a particular point, to a max length + + The collection containing elements to write. + The starting point of the elements to write + The maximum number of elements to write + + + + Write the generic 'Expected' line for a constraint + + The constraint that failed + + + + Write the generic 'Expected' line for a given value + + The expected value + + + + Write the generic 'Expected' line for a given value + and tolerance. + + The expected value + The tolerance within which the test was made + + + + Write the generic 'Actual' line for a constraint + + The constraint for which the actual value is to be written + + + + Write the generic 'Actual' line for a given value + + The actual value causing a failure + + + + Gets or sets the maximum line length for this writer + + + + + Basic Asserts on strings. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + + + + Asserts that a string is not found within another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string is found within another string. + + The expected string + The string to be examined + + + + Asserts that a string starts with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string starts with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string starts with another string. + + The expected string + The string to be examined + + + + Asserts that a string does not start with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string does not start with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string does not start with another string. + + The expected string + The string to be examined + + + + Asserts that a string ends with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string ends with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string ends with another string. + + The expected string + The string to be examined + + + + Asserts that a string does not end with another string. + + The expected string + The string to be examined + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string does not end with another string. + + The expected string + The string to be examined + The message to display in case of failure + + + + Asserts that a string does not end with another string. + + The expected string + The string to be examined + + + + Asserts that two strings are equal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that two strings are equal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + + + + Asserts that two strings are equal, without regard to case. + + The expected string + The actual string + + + + Asserts that two strings are not equal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that two strings are Notequal, without regard to case. + + The expected string + The actual string + The message to display in case of failure + + + + Asserts that two strings are not equal, without regard to case. + + The expected string + The actual string + + + + Asserts that a string matches an expected regular expression pattern. + + The regex pattern to be matched + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string matches an expected regular expression pattern. + + The regex pattern to be matched + The actual string + The message to display in case of failure + + + + Asserts that a string matches an expected regular expression pattern. + + The regex pattern to be matched + The actual string + + + + Asserts that a string does not match an expected regular expression pattern. + + The regex pattern to be used + The actual string + The message to display in case of failure + Arguments used in formatting the message + + + + Asserts that a string does not match an expected regular expression pattern. + + The regex pattern to be used + The actual string + The message to display in case of failure + + + + Asserts that a string does not match an expected regular expression pattern. + + The regex pattern to be used + The actual string + + + + Attribute used to mark a class that contains one-time SetUp + and/or TearDown methods that apply to all the tests in a + namespace or an assembly. + + + + + SetUpFixtureAttribute is used to identify a SetUpFixture + + + + + RepeatAttribute may be applied to test case in order + to run it multiple times. + + + + + Construct a RepeatAttribute + + The number of times to run the test + + + + Attribute used to mark a static (shared in VB) property + that returns a list of tests. + + + + + Attribute used to identify a method that is called + immediately after each test is run. The method is + guaranteed to be called, even if an exception is thrown. + + + + + The Iz class is a synonym for Is intended for use in VB, + which regards Is as a keyword. + + + + + Helper class with properties and methods that supply + constraints that operate on exceptions. + + + + + Creates a constraint specifying the exact type of exception expected + + + + + Creates a constraint specifying the exact type of exception expected + + + + + Creates a constraint specifying the type of exception expected + + + + + Creates a constraint specifying the type of exception expected + + + + + Creates a constraint specifying an expected exception + + + + + Creates a constraint specifying an exception with a given InnerException + + + + + Creates a constraint specifying an expected TargetInvocationException + + + + + Creates a constraint specifying an expected TargetInvocationException + + + + + Creates a constraint specifying an expected TargetInvocationException + + + + + Creates a constraint specifying that no exception is thrown + + + + + ListMapper is used to transform a collection used as an actual argument + producing another collection to be used in the assertion. + + + + + Construct a ListMapper based on a collection + + The collection to be transformed + + + + Produces a collection containing all the values of a property + + The collection of property values + + + + + Attribute used to identify a method that is + called before any tests in a fixture are run. + + + + + Attribute used to identify a method that is called after + all the tests in a fixture have run. The method is + guaranteed to be called, even if an exception is thrown. + + + + + Helper class with static methods used to supply constraints + that operate on strings. + + + + + Returns a constraint that succeeds if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value contains the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value starts with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that fails if the actual + value ends with the substring supplied as an argument. + + + + + Returns a constraint that succeeds if the actual + value matches the Regex pattern supplied as an argument. + + + + + Returns a constraint that fails if the actual + value matches the pattern supplied as an argument. + + + + + Returns a ConstraintExpression, which will apply + the following constraint to all members of a collection, + succeeding if all of them succeed. + + + + + Summary description for MaxTimeAttribute. + + + + + Construct a MaxTimeAttribute, given a time in milliseconds. + + The maximum elapsed time in milliseconds + + + + Summary description for SetUICultureAttribute. + + + + + Construct given the name of a culture + + + + + + Summary description for DirectoryAssert + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + We don't actually want any instances of this object, but some people + like to inherit from it to add other static methods. Hence, the + protected constructor disallows any instances of this object. + + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are not equal + + + + Verifies that two directories are equal. Two directories are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + The message to display if directories are not equal + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory containing the value that is expected + A directory containing the actual value + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are equal + Arguments to be used in formatting the message + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + The message to display if directories are equal + + + + Asserts that two directories are not equal. If they are equal + an is thrown. + + A directory path string containing the value that is expected + A directory path string containing the actual value + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is empty. If it is not empty + an is thrown. + + A directory to search + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + Arguments to be used in formatting the message + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + The message to display if directories are not equal + + + + Asserts that the directory is not empty. If it is empty + an is thrown. + + A directory to search + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path contains actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + Arguments to be used in formatting the message + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + The message to display if directory is not within the path + + + + Asserts that path does not contain actual as a subdirectory or + an is thrown. + + A directory to search + sub-directory asserted to exist under directory + + + + The SpecialValue enum is used to represent TestCase arguments + that cannot be used as arguments to an Attribute. + + + + + Null represents a null value, which cannot be used as an + argument to an attriute under .NET 1.x + + + + + Summary description for FileAssert. + + + + + The Equals method throws an AssertionException. This is done + to make sure there is no mistake by calling this function. + + + + + + + override the default ReferenceEquals to throw an AssertionException. This + implementation makes sure there is no mistake in calling this function + as part of Assert. + + + + + + + We don't actually want any instances of this object, but some people + like to inherit from it to add other static methods. Hence, the + protected constructor disallows any instances of this object. + + + + + Verifies that two Streams are equal. Two Streams are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The expected Stream + The actual Stream + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Verifies that two Streams are equal. Two Streams are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The expected Stream + The actual Stream + The message to display if objects are not equal + + + + Verifies that two Streams are equal. Two Streams are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The expected Stream + The actual Stream + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if objects are not equal + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + A file containing the value that is expected + A file containing the actual value + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if objects are not equal + + + + Verifies that two files are equal. Two files are considered + equal if both are null, or if both have the same value byte for byte. + If they are not equal an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + + + + Asserts that two Streams are not equal. If they are equal + an is thrown. + + The expected Stream + The actual Stream + The message to be displayed when the two Stream are the same. + Arguments to be used in formatting the message + + + + Asserts that two Streams are not equal. If they are equal + an is thrown. + + The expected Stream + The actual Stream + The message to be displayed when the Streams are the same. + + + + Asserts that two Streams are not equal. If they are equal + an is thrown. + + The expected Stream + The actual Stream + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + A file containing the value that is expected + A file containing the actual value + The message to display if objects are not equal + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + A file containing the value that is expected + A file containing the actual value + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if Streams are not equal + Arguments to be used in formatting the message + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + The message to display if objects are not equal + + + + Asserts that two files are not equal. If they are equal + an is thrown. + + The path to a file containing the value that is expected + The path to a file containing the actual value + + + + Adding this attribute to a method within a + class makes the method callable from the NUnit test runner. There is a property + called Description which is optional which you can provide a more detailed test + description. This class cannot be inherited. + + + + [TestFixture] + public class Fixture + { + [Test] + public void MethodToTest() + {} + + [Test(Description = "more detailed description")] + publc void TestDescriptionMethod() + {} + } + + + + + + Randomizer returns a set of random values in a repeatable + way, to allow re-running of tests if necessary. + + + + + Get a randomizer for a particular member, returning + one that has already been created if it exists. + This ensures that the same values are generated + each time the tests are reloaded. + + + + + Get a randomizer for a particular parameter, returning + one that has already been created if it exists. + This ensures that the same values are generated + each time the tests are reloaded. + + + + + Construct a randomizer using a random seed + + + + + Construct a randomizer using a specified seed + + + + + Return an array of random doubles between 0.0 and 1.0. + + + + + + + Return an array of random doubles with values in a specified range. + + + + + Return an array of random ints with values in a specified range. + + + + + Get a random seed for use in creating a randomizer. + + + + + Used to mark a field for use as a datapoint when executing a theory + within the same fixture that requires an argument of the field's Type. + + + + + Used to mark an array as containing a set of datapoints to be used + executing a theory within the same fixture that requires an argument + of the Type of the array elements. + + + + diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.mocks.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.mocks.dll new file mode 100644 index 00000000..558f4756 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.mocks.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.util.dll b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.util.dll new file mode 100644 index 00000000..71ca49bc Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/NUnit/v2.5/nunit.util.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/Gallio.RSpecAdapter.dll b/lib/Gallio_3.1.397.0/bin/RSpec/Gallio.RSpecAdapter.dll new file mode 100644 index 00000000..d528b0ed Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/RSpec/Gallio.RSpecAdapter.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/Gallio.RSpecAdapter.plugin b/lib/Gallio_3.1.397.0/bin/RSpec/Gallio.RSpecAdapter.plugin new file mode 100644 index 00000000..4e851ddc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/Gallio.RSpecAdapter.plugin @@ -0,0 +1,248 @@ + + + + RSpec Adapter Plugin + 3.1.0.0 + Provides support for running RSpec tests. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RSpecSource + RubySource + An RSpec source file. + .*_spec\.rb + + + + + + RSpec + RSpecSource + + + + + + RSpec File + An RSpec file. + plugin://Gallio/Resources/Assembly.ico + + + + + + RSpec Example Group + An RSpec example group. + plugin://Gallio/Resources/Fixture.ico + + + + + + RSpec Example + An RSpec example. + plugin://Gallio/Resources/Test.ico + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/Scripts/driver.rb b/lib/Gallio_3.1.397.0/bin/RSpec/Scripts/driver.rb new file mode 100644 index 00000000..b449a646 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/Scripts/driver.rb @@ -0,0 +1,400 @@ +# driver.rb +# +# Runs RSpec tests. +# +# This script receives inputs from Gallio in the form of a dictionary called ScriptParameters. +# See the class comments on DLRTestDriver for more information about these parameters. +# + +require 'gallio' +require 'spec' +require 'spec/runner/formatter/base_formatter' +require 'shellwords' + +module Gallio + module RSpecAdapter + + class Driver + def initialize(parameters) + @verb = parameters['Verb'] + @test_package = parameters['TestPackage'] + @test_exploration_options = parameters['TestExplorationOptions'] + @text_execution_options = parameters['TestExecutionOptions'] + @message_sink = ::Gallio::Wrappers::MessageSink.new(parameters['MessageSink']) + @progress_monitor = ::Gallio::Wrappers::ProgressMonitor.new(parameters['ProgressMonitor']) + @logger = ::Gallio::Wrappers::Logger.new(parameters['Logger']) + end + + def go + @logger.debug('RSpec adapter started.') + + case @verb + when 'Explore' + explore + + when 'Run' + run + end + + ensure + @logger.debug('RSpec adapter finished.') + end + + private + + def explore + explore_or_run(true) + end + + def run + explore_or_run(false) + end + + def explore_or_run(exploring) + @progress_monitor.begin_task(exploring ? "Exploring RSpec tests." : "Running RSpec tests.", 1) + + options = create_options(exploring) + options.formatters << Formatter.new(options, @message_sink, @progress_monitor) + + ::Spec::Runner.use options + ::Spec::Runner.run + + @progress_monitor.done + end + + def create_options(exploring) + options_str = @test_package.Properties.GetValue('RSpecOptions') || '' + @logger.debug("RSpec options: '#{options_str}'") + + options_array = ::Shellwords::shellwords(options_str) + options_array << '--dry-run' if exploring + options_array << '--format' << 'silent' + @test_package.Files.each do |file| + options_array << file.FullName + dirName = file.Directory.FullName + $: << dirName if $:.index(dirName) == nil + end + + workaround_option_parser_use_of_argument_zero + parser = ::Spec::Runner::OptionParser.new($stderr, $stdout) + parser.parse(options_array) + + parser.options + end + + # HACK: Work around some bad code in OptionParser.spec_command? where it + # tries to read $0. Unfortunately $0 is nil here. + def workaround_option_parser_use_of_argument_zero + $0 = '' + end + + # + # The Formatter listens for events from the RSpec test runner and generates + # messages for Gallio. The implementation is a little bit complicated because + # we have to rederive the file list and nested example group structure based + # on flattened events. + # + # In some places we call ToString() on an existing string or on some other + # object that is implicitly convertible to strings. This is a workaround for + # an error 'incompatible character encodings: utf-8 (KCODE) and Windows-1252' + # that can appear when mixing literal strings with computed values. + # + class Formatter < ::Spec::Runner::Formatter::BaseFormatter + def initialize(options, message_sink, progress_monitor) + @options = options + @message_sink = message_sink + @progress_monitor = progress_monitor + + test_context_tracker = ::Gallio::Wrappers::Runtime.Resolve(::Gallio::Model::Contexts::ITestContextTracker) + @test_context_manager = ::Gallio::Model::Contexts::ObservableTestContextManager.new(test_context_tracker, message_sink.inner) + @test_stack = [] + @test_context_stack = [] + @work_per_example = 1 + @example_group_depth = 0 + @current_file_path = nil + end + + def start(example_count) + #puts "start" + @work_per_example = 1.0 / example_count if example_count > 1 + + # Push the root onto the stack. + internal_root_started + end + + def example_group_started(example_group_proxy) + #puts "example_group_started" + + # Pop all deeper example groups and siblings off the stack. + while @example_group_depth >= example_group_proxy.nested_descriptions.length + internal_example_group_finished + end + + # Check whether we are working on a new file. + if @example_group_depth == 0 + path, line = parse_location(example_group_proxy.location) + if path != @current_file_path + internal_file_finished if @current_file_path != nil + @current_file_path = path + internal_file_started(path) if path != nil + end + end + + # Push this group onto the stack. + internal_example_group_started(example_group_proxy) + end + + def example_started(example_proxy) + #puts "example_started" + + internal_example_started(example_proxy) + end + + def example_passed(example_proxy) + #puts "example_passed" + + internal_example_finished(::Gallio::Model::TestOutcome.Passed) do |example_test_context| + end + end + + def example_failed(example_proxy, counter, failure) + #puts "example_failed" + + internal_example_finished(::Gallio::Model::TestOutcome.Failed) do |example_test_context| + example_test_context.LogWriter.Failures.BeginSection(failure.header) + example_test_context.LogWriter.Failures.Write(failure.exception.message) unless failure.exception.nil? + example_test_context.LogWriter.Failures.Write(format_backtrace(failure.exception.backtrace)) unless failure.exception.nil? + example_test_context.LogWriter.Failures.End() + end + end + + def example_pending(example_proxy, message, deprecated_pending_location=nil) + #puts "example_pending" + + internal_example_finished(::Gallio::Model::TestOutcome.Pending) do |example_test_context| + example_test_context.AddMetadata(::Gallio::Model::MetadataKeys.PendingReason, message) + example_test_context.LogWriter.Warnings.BeginSection("Pending") + example_test_context.LogWriter.Warnings.Write(message) + example_test_context.LogWriter.Warnings.End() + end + end + + def start_dump + #puts "start_dump" + + # Pop all example groups off the stack. + while @example_group_depth > 0 do + internal_example_group_finished + end + + # Pop off the current file if there is one + if @current_file_path != nil + internal_file_finished + @current_file_path = nil + end + + # Pop the root off the stack. + if @test_stack.length > 0 + internal_root_finished + end + end + + def close + #puts "close" + end + + private + + def internal_root_started + root_test = create_root_test + @test_stack.push(root_test) + + notify_test_discovered(root_test) + + return if dry_run? + + root_test_context = start_test_step(root_test) + @test_context_stack.push(root_test_context) + end + + def internal_root_finished + @test_stack.pop() + + return if dry_run? + + root_test_context = @test_context_stack.pop() + finish_test_step(root_test_context) + end + + def internal_file_started(file_path) + @progress_monitor.set_status("Running file: #{file_path}.") + + file_name = ::System::IO::Path.GetFileNameWithoutExtension(file_path) + file_test = create_test(file_name) + file_test.Kind = "RSpec File" + file_test.Metadata.Add(::Gallio::Model::MetadataKeys.File, file_path) + @test_stack.last.AddChild(file_test) + @test_stack.push(file_test) + + notify_test_discovered(file_test) + + return if dry_run? + + file_test_context = start_test_step(file_test) + @test_context_stack.push(file_test_context) + end + + def internal_file_finished + @test_stack.pop() + + return if dry_run? + + file_test_context = @test_context_stack.pop() + finish_test_step(file_test_context) + end + + def internal_example_group_started(example_group_proxy) + description = example_group_proxy.nested_descriptions.last.ToString() + @progress_monitor.set_status("Running example group: #{description}.") + + example_group_test = create_test(description) + example_group_test.Kind = "RSpec Example Group" + @test_stack.last.AddChild(example_group_test) + @test_stack.push(example_group_test) + @example_group_depth += 1 + + notify_test_discovered(example_group_test, example_group_proxy.location) + + return if dry_run? + + example_group_test_context = start_test_step(example_group_test) + @test_context_stack.push(example_group_test_context) + end + + def internal_example_group_finished + @example_group_depth -= 1 + @test_stack.pop() + + return if dry_run? + + example_group_test_context = @test_context_stack.pop() + finish_test_step(example_group_test_context) + end + + def internal_example_started(example_proxy) + description = example_proxy.description.ToString() + @progress_monitor.set_status("Running example: #{description}.") + + example_test = create_test(description) + example_test.Kind = "RSpec Example" + example_test.IsTestCase = true + @test_stack.last.AddChild(example_test) + @test_stack.push(example_test) + + notify_test_discovered(example_test, example_proxy.location) + + return if dry_run? + + example_test_context = start_test_step(example_test) + @test_context_stack.push(example_test_context) + end + + def internal_example_finished(outcome, &blk) + @progress_monitor.worked(@work_per_example) + @test_stack.pop() + + return if dry_run? + + example_test_context = @test_context_stack.pop() + set_outcome(example_test_context, outcome) + blk.call(example_test_context) + finish_test_step(example_test_context) + end + + def set_outcome(test_context, outcome) + test_context.SetInterimOutcome(outcome) + end + + def start_test_step(test) + if @test_context_stack.length == 0 + test_step = create_test_step(test) + test_context = @test_context_manager.StartStep(test_step) + else + test_step = create_test_step(test, @test_context_stack.last.TestStep) + test_context = @test_context_stack.last.StartChildStep(test_step) + end + + test_context + end + + def finish_test_step(test_context) + outcome = test_context.Outcome + test_context.FinishStep(outcome, nil) + + parent_test_context = test_context.Parent + if parent_test_context != nil + if outcome.Status != ::Gallio::Model::TestStatus.Inconclusive + parent_outcome = parent_test_context.Outcome.CombineWith(outcome).Generalize() + parent_test_context.SetInterimOutcome(parent_outcome) + end + end + end + + def format_backtrace(backtrace) + return "" if backtrace.nil? + backtrace.map { |line| backtrace_line(line) }.join("\n") + end + + def backtrace_line(line) + line.sub(/\A([^:]+:\d+)$/, '\\1:') + end + + def dry_run? + @options.dry_run? + end + + def create_root_test + ::Gallio::Model::Tree::RootTest.new + end + + def create_test(name) + ::Gallio::Model::Tree::Test.new(name, nil) + end + + def create_test_step(test, parent_test_step = nil) + ::Gallio::Model::Tree::TestStep.new(test, parent_test_step) + end + + def notify_test_discovered(test, location = nil) + message = ::Gallio::Model::Messages::Exploration::TestDiscoveredMessage.new + message.ParentTestId = test.Parent.Id if test.Parent + message.Test = ::Gallio::Model::Schema::TestData.new(test) + + path, line = parse_location(location) + if path != nil + message.Test.CodeLocation = ::Gallio::Common::Reflection::CodeLocation.new(path, line, 0) + end + + @message_sink.publish(message) + end + + def parse_location(location) + if (location != nil) + matches = /^(.*):([0-9]+)$/.match(location) + if matches != nil + [matches[1].ToString(), matches[2].to_i] + else + [location.ToString(), 0] + end + else + [nil, 0] + end + end + end + end + end +end + +# Run. + +::Gallio::RSpecAdapter::Driver.new(ScriptParameters).go diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/History.rdoc b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/History.rdoc new file mode 100644 index 00000000..95f9c424 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/History.rdoc @@ -0,0 +1,1438 @@ +=== Version 1.2.7 / 2009-06-22 + +* enhancments + * added support for fakes using obj.stub(:method) { # implementation } + * allow subject { self } (Jarmo Pertman). Closes #816. + * friendly error message when a matcher returns nil on a failure message + * add ruby_cmd option to SpecTask (Rick DeNatale). Closes #823. + * also added missing specs for SpecTask - thanks Rick! + * add support for generating matchers with fluent interfaces with the + Matcher DSL + +* bug fixes + * NegativeOperatorMatcher now returns false (Wesley Beary). Closes #812. + * derive MockExpectationError from Exception rather than StandardError + (Kerry Buckley). Closes #830. + * fix bug where multi-line failure messages weren't getting picked up by + autotest (Jarmo Pertman). Closes #832. + * --line_number now works for it { should xxx } format (assist from Fred + Lee) + * warn instead of raise when there is no description supplied for an + example. Closes #840. + +=== Version 1.2.6 / 2009-04-30 + +* bug fixes + * gem actually built with spec executable + +=== Version 1.2.5 / 2009-04-29 + +* enhancements + + * name argument to mock/stub is now optional (closes #782) + * you can do mock(:foo => "woo", :bar => "car") + * expect { this_block }.to change{this.expression}.from(old_value).to(new_value) + * expect { this_block }.to raise_error + * better failiure messages for equal matcher (James Byrne). Closes #804. + * add stub_chain method + * also alias_method :stub, :stub!, so you can stub with less bang + * added options to example_group_proxy + +* bug fixes + + * ensure correct handling of ordered message expectations with duplicate + expectations (NigelThorne). Closes #793. + * get matcher backwards compat working w/ ruby 19 + * don't define instance_exec unless it is not defined + * was doing a version check, but turns out that didn't cover alternative + implementations like JRuby + * fix bug where in some circumstances, loading lib/spec/interop/test.rb + raised an error (tsechingho). Closes #803. + * make sure specs only run against spec server when using drb (patch from Chuck Grindel). Closes #797. + * remove deprecation warning in example_pending when using FailingExamplesFormatter. Closes #794. + * Access explicit subject from nested groups of arbitrary depth. Closes #756. + +=== Version 1.2.4 / 2009-04-13 + +* bug fix + + * just one - update the manifest + +=== Version 1.2.3 / 2009-04-13 + +* deprecations + + * BaseFormatter#add_example_group (use #example_group_started instead) + * ExampleGroupProxy#backtrace (use #location instead) + * ExampleProxy#backtrace (use #location instead) + * BaseFormatter#example_pending now expects two arguments. The third + argument is deprecated. + * ExampleGroupProxy#filtered_description. This was only used in one place + internally, and was a confusing solution to the problem. If you've got a + custom formatter that uses it, you can just use + ExampleGroupProxy#description and modify it directly. + * predicate_matchers (use the new Matcher DSL instead) + * Spec::Matchers.create (use Spec::Matchers.define instead) + +* enhancements + + * support for specifying single examples with colon syntax. Closes #712. + (Ben Mabey) + * you can now say "spec some_spec.rb:12" in addition to "spec some_spec.rb + --line 12" + * run specs locally with --drb if no drb server is running. Closes #780. + * still prints "No server running" to stderr + +* bug fixes + + * support expectations on DelegateClass (Clifford T. Matthews). Closes #48. + * Fixed match_array blows up if elements can't be sorted (Jeff Dean). Closes #779. + +=== Version 1.2.2 / 2009-03-22 + +Bug-fix release (fixes regression introduced in 1.2.1) + +* bug fixes + + * fixed bug in which spec_parser raised an error for custom example group + base classes + +=== Version 1.2.1 / 2009-03-22 + +This is a bug-fix release, recommended for anybody who has already upgraded to +rspec-1.2.0. + +See Upgrade.rdoc for information about upgrading to rspec-1.2.1 + +* enhancements + + * matchers, including the new DSL, easily added to your test/unit tests + * added support for 0 to n args in matcher DSL + * restored loading rubygems when necessary + * if you really don't want to use rubygems, you + can set an NO_RUBYGEMS environment + variable, and RSpec won't force it on you. + * added -u/--debugger option (Rick DeNatale) #262. + * just add "debugger" anywhere in your code and run spec path/to/code --debugger + * rename ExampleDescription to ExampleProxy + * pass ExampleProxy to example_started(). Closes #738, #743 + * thanks to Tobias Grimm (Eclipse) fort the patch and Roman Chernyatchik + (JetBrains, RubyMine) for the assist + +* bug fixes + + * subject (implicit or explicit) is now properly inherited by nested groups. Closes #744. + +=== Version 1.2.0 / 2009-03-15 + +* warnings: + + * If you use the ruby command to run specs instead of the spec command, you'll + need to require 'spec/autorun' or they won't run. This won't affect you if + you use the spec command or the Spec::Rake::SpecTask that ships with RSpec. + + * require 'spec/test/unit' to invoke test/unit interop if you're using + RSpec's core (this is handled implicitly with spec-rails) + + * setup and teardown are gone - use before and after instead + + * you can still use setup and teardown if you're using + Test::Unit::TestCase as the base ExampleGroup class (which is implicit + in rspec-rails) + + * The matcher protocol has been improved. The old protocol is still + supported, so as long as you're not monkey patching rspec's built-in + matchers, or using extension libraries that do, this should not affect + you. If you run into trouble, you'll just need to change: + + failure_message => failure_message_for_should + negative_failure_message => failure_message_for_should_not + + * All references to rubygems have been removed from within rspec's code. + + * NOTE that they have been restored in 1.2.1, above + + * See http://gist.github.com/54177 for rationale and suggestions on + alternative approaches to loading rubygems + +* deprecations + + * BaseTextFormatter#colourize - use colorize_failure instead. + * BaseTextFormatter#magenta - use red instead. + +* enhancements + + * cleaner integration with with heckle-1.4.2 + * allow registering example groups with a path-like key (Pat Maddox) + * start DRb service at "druby://localhost:0" (Hongli Lai) - See http://redmine.ruby-lang.org/issues/show/496 + * consistent reporting of errors as failures + * added spec/test/unit as more intuitive path to loading test/unit interop lib + * added explicit autorun feature for running specs with ruby command + * added handling for does_not_match? for matchers that want to know the context in which they were called + * lots of ruby 1.9.1 compatibility fixes from Chad Humprhies + * improved feedback from be_kind_of/be_a_kind_of/be_instance_of/be_an_instance_of (Jakub Šťastný) + * added --format silent (l) option, which is now the default when running --heckle (Bob Aman) + * sexy new custom matcher creation (Corey Haines & David Chelimsky - initial concept by Yehuda Katz) + * improved matcher protocol - old one is still supported, but new one is cleaner and prefered + +* bug fixes + + * support delegating operator matchers to subject with should_not + * all arguments are included if --drb is specified in spec.opts (Neil Buckley). Closes #671. + * added --autospec option hack (used internally) to get --color to work when using --drb and autospec. + * Fixed mock framework failure message bug in which similar calls were excluded from the output + * cryptic error message on change.rb when the from value is wrong (Michael Murray). Closes #706. + +=== Version 1.1.12 / 2009-01-11 + +WARNING: there was a stub/mock bug in 1.1.11 that allowed a structure that was +not intended: + + obj.stub!(:msg) + obj.msg + obj.should_receive(:msg) + +That would pass in 1.1.11, but should not have been allowed to, since the +message is received before the expectation is set. This was reported (#637) +and fixed for release 1.1.12, but may cause unexpected failures if you had +examples set up as above. + +WARNING: mock.should_receive(:msg).with(an_instance_of(klass)) now correctly uses instance_of? instead of kind_of?. This may break some existing code examples, but the fix is to just use kind_of instead of an_instance_of + +* 3 deprecations + + * deprecated ExampleMethods#implementation_backtrace - use ExampleMethods#backtrace instead + * deprecated ExampleGroupMethods#example_group_backtrace - use ExampleGroupMethods#backtrace instead + * deprecated Spec::Example::BehaviourRunner class (likely that nobody is using this) + +* 6 major enhancements + + * it { should matcher } - support for implicit receiver of #should (Joe Ferris of thoughtbot) + * subject { ... } - works in conjunction with implicit receiver of #should + * wrap_expectation (for wrapping multiple expectations and/or t/u assertions) + * added array.should =~ [1,2,3] # passes if array contains exactly the same elements in any order (Jeff Dean and Pat Maddox) + * hash_including mock argument matcher can now accept just keys, key/value pairs, or both (David Krmpotic) + * added hash_not_including mock argument matcher (David Krmpotic). Closes #634. + +* 9 minor enhancements + + * should throw_symbol accepts an optional argument: should throw_symbol(:sym, arg) + * fixed --line for jruby (Zach Moazeni) + * assorted small changes to support Ruby 1.9 (got a way to go) + * removed all instances of class << self - I do know who I am + * SpecParser can't handle backtrace paths with colons (John-Mason P. Shackelford). Closes #505. + * html formatter (and subsequently the textmate formatter) header fills in completely when running a single example + * config.include now accepts an array of types (config.include(Helpers, :type => [:view, :controller])) + * added be_a and be_an expectation matchers + * added instance_of and kind_of mock argument matchers + +* 9 bug fixes + + * fixed bug where {:a => 1, :b => 2}.should include(:a, :b) failed (Yossef Mendelssohn) + * only try to load Test::Unit if Test::Unit is defined (not just Test) + * Allow stubs on parent and child classes simultaneously (Jim Lindley). Fixes #600. + * BaseTextFormatter will now create the directory in a WHERE string (Adam Anderson). Fixes #616. + * Removed incorrect -S flag on autospec commands. Added explicit spec command for ruby to run, guarantee running rspec (raggi). Closes #507. + * Check whether test/unit has really been loaded before calling a method it defines (Brian Donovan). Closes #503. + * Fix spec_path for shared groups (Zach Dennis). Closes #615. + * stubbed message expectation not verified if it has been called *before* the expectation (Matthias Hennemeyer). Closes #637. + * stubs calculate return value by executing block passed to #and_return (hint from Aisha Fenton). Closes #642. + +=== Version 1.1.11 / 2008-10-24 + +* 1 major enhancement + + * eliminate ALL gem dependencies (as they were causing trouble for people on different platforms/environments) + +=== Version 1.1.10 / 2008-10-24 + +* 1 minor enhancement + + * hash.should include(:key => 'value') #when you don't care about the whole hash + +* 2 bug fixes + + * fix --help output (had inaccurate info about 'nested' formatter) + * eliminate spicycode-rcov dev dependency for rubygems < 1.3 + +=== Version 1.1.9 / 2008-10-20 + +WARNING: This release removes implicit inclusion of modules in example groups. +This means that if you have 'describe MyModule do', MyModule will not be +included in the group. + +* 2 major enhancements + + * Add extend to configuration (thanks to advice from Chad Fowler) + * Modules are no longer implicitly included in example groups + +* 4 minor enhancements + + * mingw indicates windows too (thanks to Luis Lavena for the tip) + * improved output for partial mock expecation failures + * it_should_behave_like now accepts n names of shared groups + * eliminated redundant inclusion/extension of ExampleGroupMethods + +* 6 bug fixes + + * spec command with no arguments prints help + * fixed typo in help. Fixes #73. + * fixed bug where should_receive..and_yield after similar stub added the args_to_yield to the stub's original args_to_yield (Pat Maddox) + * fixed bug where rspec-autotest (autospec) was loading non-spec files in spec directory. Fixes #559. + * fixed bug where should_not_receive was reporting twice + * fixed bug where rspec tries to run examples just because it is required (even if there are no examples loaded). Fixes #575. + +=== Version 1.1.8 / 2008-10-03 + +* 2 bug fixes + + * restore colorized output in linux and windows w/ autotest (Tim Pope). Fixes #413. + * autospec no longer hangs on windows. Fixes #554. + +=== Version 1.1.7 / 2008-10-02 + +* no changes since 1.1.6, but releasing rspec-1.1.7 to align versions with rspec-rails-1.1.7 + +=== Version 1.1.6 / 2008-10-02 + +* 2 bug fixes + + * fixed bug where negative message expectations following stubs resulted in false (negative) positives (Mathias Meyer). Closes #548. + * fixed bug where Not Yet Implemented examples report incorrect caller (Scott Taylor). Closes #547. + +* 1 minor enhancement + + * removed deprecated mock argument constraint symbols + +=== Version 1.1.5 / 2008-09-28 + +IMPORTANT: use the new 'autospec' command instead of 'autotest'. We changed +the way autotest discovers rspec so the autotest executable won't +automatically load rspec anymore. This allows rspec to live side by side other +spec frameworks without always co-opting autotest through autotest's discovery +mechanism. + +ALSO IMPORTANT: $rspec_options is gone. If you were using this for anything +(like your own runners), use Spec::Runner.options instead. + +ADDITIONALLY IMPORTANT: If you have any custom formatters, you'll need to +modify #example_pending to accept three arguments instead of just two. See the +rdoc for Spec::Runner::Formatter::BaseFormatter#example_pending for more +information. + +* Consider MinGW as valid RUBY_PLATFORM for --colour option. (patch from Luis Lavena). Closes #406. +* Added additional characters to be escaped in step strings (patch from Jake Cahoon). Closes #417. +* Disable color codes on STDOUT when STDOUT.tty? is false (patch from Tim Pope). Closes #413. +* mock(:null_object=>true) plays nice with HTML (patch from Gerrit Kaiser). Closes #230. +* a step definition with no block is treated as pending +* make sure consolidate_failures only grabs _spec files. Closes #369 +* Simplifying ExampleGroupMethods#registration_backtrace. (From Wilson Bilkovich - http://metaclass.org/2008/6/7/calling-in-the-dark) +* Use 127.0.0.1 instead of localhost for drb (thanks Ola Bini) +* html story formatter correctly colors story/scenario red if step fails (Patch from Joseph Wilk). Closes #300 +* plain text story formatter correctly colors story/scenario red if step fails (Patch from Joseph Wilk). Closes #439 +* quiet deprecation warning on inflector - patch from RSL. Closes #430 +* added autospec executable +* added configurable messages to simple_matcher +* should and should_not return true on success +* use hoe for build/release +* bye, bye translator +* autotest/rspec uses ruby command instead of spec command (no need for spec command unless loading directories) +* Avoid 'invalid option -O' in autotest (patch from Jonathan del Strother). Closes #486. +* Fix: Unimplemented step with new line throws error (patch from Ben Mabey). Closes #494. +* Only use color codes on tty; override for autospec (patch from Tim Pope). Closes #413. +* Warn when setting mock expectations on nil (patch from Ben Mabey). Closes #521. +* Support argument constraints as values in the hash_including contstraint. Thanks to Pirkka Hartikainen for failing code examples and the fix. Buttons up #501. +* mock(:null_object=>true) plays nice with HTML (patch from Gerrit Kaiser) +* Consider MinGW as valid RUBY_PLATFORM for --colour option. (patch from Luis Lavena). Closes #406. +* Add 2nd arg to respond_to? to align w/ core Ruby rdoc: http://www.ruby-doc.org/core/classes/Object.html#M000604 +* quiet backtrace tweaker filters individual lines out of multiline (ala Rails) error messages (Pat Maddox) +* added ability to stub multiple methods in one stub! call (Pat Maddox) +* story progress bar formatter and more colourful summaries from the plain text story formatter (Joseph Wilk) +* Avoid ruby invocation errors when autotesting (Jonathan del Strother) +* added mock('foo').as_null_object +* add file and line number to pending_example for formatters (Scott Taylor) +* return last stubbed value for mock expectation with no explicit return (Pat Maddox) +* Fixed bug when should_receive(:foo).any_number_of_times is called after similar stub (Pat Maddox) +* Warning messages now issued when expectations are set on nil (Ben Mabey) + +=== Version 1.1.4 + +Maintenance release. + +Note: we've removed the metaclass method from Object. There were some +generated specs that used it, and they will now break. Just replace the +metaclass call with (class << self; self; end) and all will be well. + +* added hash_including mock argument matcher. Closes #332 (patch from Rick DeNatale) +* pending steps print out yellow in stories (patch from Kyle Hargraves) +* Deprecation warnings for specs that assume auto-inclusion of modules. Closes #326 (patch from Scott Taylor) +* mock.should_not_receive(:anything) fails fast (once again) +* Patch from Antti Tarvainen to stop files from being loaded repeatedly when running heckle. Closes #333. +* Fixed bug in which session object in example was not the same instance used in the controller. Closes #331. +* Applied patch from Antti Tarvainen to fix bug where heckle runs rspec runs heckle runs rspec etc. Closes #280. +* Applied patch from Zach Dennis to merge :steps functionality to :steps_for. Closes #324. +* Applied patch from Ryan Davis to add eval of block passed to raise_error matcher. Closes #321. +* alias :context :describe in example_group_methods. Closes #312. +* Applied patch from Ben Mabey to make the Story runner exit with a non-0 exit code on failing stories. Closes #228. +* Applied patch from Coda Hale to get the :red hook called in autotest. Closes #279. +* Applied patch from Patrick Ritchie to support --drb in spec.opts. Closes #274, #293. +* Moved metaclass method from Object to an internal module which gets included where it is needed. +* Applied patch from Dayo Esho: and_yield clobbers return value from block. Closes #217. +* Applied patch from Bob Cotton: ExampleGroupFactory.default resets previously registered types. Closes #222. +* Applied patch from Mike Williams to support the lib directory in rails apps with the Textmate Alternate File command. Closes #276. +* ExampleGroupMethods#xspecify aliases #xit +* A SharedExampleGroup can be created within another ExampleGroup. +* Applied patch from Bob Cotton: Nested ExampleGroups do not have a spec_path. Closes #224. +* Add before_suite and after_suite callbacks to ExampleGroupMethods and Options. Closes #210. +* The after(:suite) callback lambda is passed a boolean representing whether the suite passed or failed +* Added NestedTextFormatter. Closes #366. +* decoupled mock framework from global extensions used by rspec - supports use of flexmock or mocha w/ rails +* Applied patch from Roman Chernyatchik to allow the user to pass in the ruby version into spectask. Closes #325, #370 + +=== Version 1.1.3 + +Maintenance release. +Notice to autotest users: you must also upgrade to ZenTest-3.9.0. + +* Tightened up exceptions list in autotest/rails_spec. Closes #264. +* Applied patch from Ryan Davis for ZenTest-3.9.0 compatibility +* Applied patch from Kero to add step_upcoming to story listeners. Closes #253. +* Fixed bug where the wrong named error was not always caught by "should raise_error" +* Applied patch from Luis Lavena: No coloured output on Windows due missing RUBYOPT. Closes #244. +* Applied patch from Craig Demyanovich to add support for "should_not render_template" to rspec_on_rails. Closes #241. +* Added --pattern (-p for short) option to control what files get loaded. Defaults to '**/*_spec.rb' +* Exit with non-0 exit code if examples *or tests* (in test/unit interop mode) fail. Closes #203. +* Moved at_exit hook to a method in Spec::Runner which only runs if specs get loaded. Closes #242. +* Applied patch from kakutani ensuring that base_view_path gets cleared after each view example. Closes #235. +* More tweaks to regexp step names +* Fixed focused specs in nested ExampleGroups. Closes #225. + +=== Version 1.1.2 + +Minor bug fixes/enhancements. +Notice to autotest users: you must also upgrade to ZenTest-3.8.0. + +* RSpec's Autotest subclasses compatible with ZenTest-3.8.0 (thanks to Ryan Davis for making it easier on Autotest subs). +* Applied patch from idl to add spec/lib to rake stats. Closes #226. +* calling setup_fixtures and teardown_fixtures for Rails >= r8570. Closes #219. +* Applied patch from Josh Knowles using ActiveSupport's Inflector (when available) to make 'should have' read a bit better. Closes #197. +* Fixed regression in 1.1 that caused failing examples to fail to generate their own names. Closes #209. +* Applied doc patch from Jens Krämer for capturing content_for +* Applied patch from Alexander Lang to clean up story steps after each story. Closes #198. +* Applied patch from Josh Knowles to support 'string_or_response.should have_text(...)'. Closes #193. +* Applied patch from Ian Dees to quiet the Story Runner backtrace. Closes #183. +* Complete support for defining steps with regexp 'names'. + +=== Version 1.1.1 + +Bug fix release. + +* Fix regression in 1.1.0 that caused transactions to not get rolled back between examples. +* Applied patch from Bob Cotton to reintroduce ExampleGroup.description_options. Closes LH[#186] + +=== Version 1.1.0 + +The "tell me a story and go nest yourself" release. + +* Applied patch from Mike Vincent to handle generators rails > 2.0.1. Closes LH[#181] +* Formatter.pending signature changed so it gets passed an ExampleGroup instance instead of the name ( LH[#180]) +* Fixed LH[#180] Spec::Rails::Example::ModelExampleGroup and friends show up in rspec/rails output +* Spec::Rails no longer loads ActiveRecord extensions if it's disabled in config/boot.rb +* Applied LH[#178] small annoyances running specs with warnings enabled (Patch from Mikko Lehtonen) +* Tighter integration with Rails fixtures. Take advantage of fixture caching to get performance improvements (Thanks to Pat Maddox, Nick Kallen, Jonathan Barnes, and Curtis) + +=== Version 1.1.0-RC1 + +Textmate Bundle users - this release adds a new RSpec bundle that highlights describe, it, before and after and +provides navigation to descriptions and examples (rather than classes and methods). When you first install this, +it is going to try to hijack all of your .rb files. All you need to do is open a .rb file that does not end with +'spec.rb' and change the bundle selection from RSpec to Ruby. TextMate will do the right thing from then on. + +Shortcuts for tab-activated snippets all follow the TextMate convention of 2 or 3 letters of the first word, followed by the first letter of each subsequent word. So "should have_at_least" would be triggered by shhal. + +We reduced the scope for running spec directories, files, a single file or individual spec in TextMate to source.ruby.rspec. This allowed us to restore the standard Ruby shortcuts: + +CMD-R runs all the specs in one file +CMD-SHIFT-R runs an individual spec +CMD-OPT-R runs any files or directories selected in the TextMate drawer + +rspec_on_rails users - don't forget to run script/generate rspec + +* Added shared_examples_for method, which you can (should) use instead of describe Foo, :shared => true +* Applied LH[#168] Fix describe Object, "description contains a # in it" (Patch from Martin Emde) +* Applied LH[#15] Reverse loading of ActionView::Base helper modules (Patch from Mark Van Holstyn) +* Applied LH[#149] Update contribute page to point towards lighthouse (Patch from Josh Knowles) +* Applied LH[#142] verify_rcov fails with latest rcov (Patch from Kyle Hargraves) +* Applied LH[#10] Allow stubs to yield and return values (Patch from Pat Maddox) +* Fixed LH[#139] version.rb in trunk missing svn last changed number +* Applied LH[#14] Adding support for by_at_least/by_at_most in Change matcher (Patch from Saimon Moore) +* Applied LH[#12] Fix for TM when switching to alternate file (Patch from Trevor Squires) +* Applied LH[#133] ExampleMatcher should match against before(:all) (Patch from Bob Cotton) +* Applied LH[#134] Only load spec inside spec_helper.rb (Patch from Mark Van Holstyn) +* RSpec now bails immediately if there are examples with identical names. +* Applied LH[#132] Plain Text stories should support Given and Given: (Patch from Jarkko Laine) +* Applied patch from Pat Maddox: Story Mediator - the glue that binds the plain text story parser with the rest of the system +* Applied LH[#16] Have SimpleMatchers expose their description for specdocs (Patch from Bryan Helmkamp) +* Stories now support --colour +* Changed the DSL modules to Example (i.e. Spec::Example instead of Spec::DSL) +* Applied [#15608] Story problem if parenthesis used in Given, When, Then or And (Patch from Sinclair Bain) +* Applied [#15659] GivenScenario fails when it is a RailsStory (Patch from Nathan Sutton) +* Fixed [#15639] rcov exclusion configuration. (Spec::Rails projects can configure rcov with spec/rcov.opts) +* The rdoc formatter (--format rdoc) is gone. It was buggy and noone was using it. +* Changed Spec::DSL::Behaviour to Spec::DSL::ExampleGroup +* Changed Spec::DSL::SharedBehaviour to Spec::DSL::SharedExampleGroup +* Applied [#14023] Small optimization for heavily proxied objects. (Patch from Ian Leitch) +* Applied [#13943] ProfileFormatter (Top 10 slowest examples) (Patch from Ian Leitch) +* Fixed [#15232] heckle is not working correctly in trunk (as of r2801) +* Applied [#14399] Show pending reasons in HTML report (Patch from Bryan Helmkamp) +* Discovered fixed: [#10263] mock "leak" when setting an expectation in a block passed to mock#should_receive +* Fixed [#14671] Spec::DSL::ExampleRunner gives "NO NAME because of --dry-run" for every example for 'rake spec:doc' +* Fixed [#14543] rspec_scaffold broken with Rails 2.0 +* Removed Patch [#10577] Rails with Oracle breaks 0.9.2 - was no longer necessary since we moved describe to the Main object (instead of Object) +* Fixed [#14527] specs run twice on rails 1.2.4 and rspec/rspec_on_rails trunk +* Applied [#14043] Change output ordering to show pending before errors (Patch from Mike Mangino) +* Applied [#14095] Don't have ./script/generate rspec create previous_failures.txt (Patch from Bryan Helmkamp) +* Applied [#14254] Improved error handling for Object#should and Object#should_not (Patch from Antti Tarvainen) +* Applied [#14186] Remove dead code from message_expecation.rb (Patch from Antti Tarvainen) +* Applied [#14183] Tiny improvement on mock_spec.rb (Patch from Antti Tarvainen) +* Applied [#14208] Fix to Mock#method_missing raising NameErrors instead of MockExpectationErrors (Patch from Antti Tarvainen) +* Applied [#14255] Fixed examples in mock_spec.rb and shared_behaviour_spec.rb (Patch from Antti Tarvainen) +* Applied [#14362] partially mocking objects that define == can blow up (Patch from Pat Maddox) +* test_ methods with an arity of 0 defined in a describe block or Example object will be run as an Example, providing a seamless transition from Test::Unit +* Removed BehaviourRunner +* Fixed [#13969] Spec Failures on Trunk w/ Autotest +* Applied [#14156] False positives with should_not (Patch from Antti Tarvainen) +* Applied [#14170] route_for and params_from internal specs fixed (Patch from Antti Tarvainen) +* Fixed [#14166] Cannot build trunk +* Applied [#14142] Fix for bug #11602: Nested #have_tag specifications fails on the wrong line number (Patch from Antti Tarvainen) +* Removed warn_if_no_files argument and feature +* Steps (Given/When/Then) with no blocks are treated as pending +* Applied [#13913] Scenario should treat no code block as pending (Patch from Evan Light) +* Fixed [#13370] Weird mock expectation error (Patch from Mike Mangino) +* Applied [#13952] Fix for performance regression introduced in r2096 (Patch from Ian Leitch) +* Applied [#13881] Dynamically include Helpers that are included on ActionView::Base (Patch from Brandon Keepers) +* Applied [#13833] ActionView::Helpers::JavaScriptMacrosHelper removed after 1.2.3 (Patch from Yurii Rashkovskii) +* Applied [#13814] RSpec on Rails w/ fixture-scenarios (Patch from Shintaro Kakutani) +* Add ability to define Example subclass instead of using describe +* Applied Patch from James Edward Gray II to improve syntax highlighting in TextMate +* Fixed [#13579] NoMethodError not raised for missing helper methods +* Fixed [#13713] form helper method 'select' can not be called when calling custom helper methods from specs +* Example subclasses Test::Unit::TestCase +* Added stub_everything method to create a stub that will return itself for any message it doesn't understand +* Added stories directory with stories/all.rb and stories/helper.rb when you script/generate rspec +* Applied [#13554] Add "And" so you can say Given... And... When... Then... And... +* Applied [#11254] RSpec syntax coloring and function pop-up integration in TextMate (Patch from Wincent Colaiuta) +* Applied [#13143] ActionView::Helpers::RecordIdentificationHelper should be included if present (Patch from Jay Levitt) +* Applied [#13567] patch to allow stubs to yield consecutive values (Patch from Rupert Voelcker) +* Applied [#13559] reverse version of route_for (Patch from Rupert Voelcker) +* Added [#13532] /lib specs should get base EvalContext +* Applied [#13451] Add a null_object option to mock_model (Patch from James Deville) +* Applied [#11919] Making non-implemented specs easy in textmate (Patch from Scott Taylor) +* Applied [#13274] ThrowSymbol recognized a NameError triggered by Kernel#method_missing as a thrown Symbol +* Applied [#12722] the alternate file command does not work in rails views due to scope (Patch from Carl Porth) +* Behaviour is now a Module that is used by Example class methods and SharedBehaviour +* Added ExampleDefinition +* Added story runner framework based on rbehave [#12628] +* Applied [#13336] Helper directory incorrect for rake stats in statsetup task (Patch from Curtis Miller) +* Applied [#13339] Add the ability for spec_parser to parse describes with :behaviour_type set (Patch from Will Leinweber and Dav Yaginuma) +* Fixed [#13271] incorrect behaviour with expect_render and stub_render +* Applied [#13129] Fix failing specs in spec_distributed (Patch from Bob Cotton) +* Applied [#13118] Rinda support for Spec::Distributed (Patch from Bob Cotton) +* Removed BehaviourEval +* Removed Behaviour#inherit +* Moved implementation of install_dependencies to example_rails_app +* Renamed RSPEC_DEPS to VENDOR_DEPS +* Added Example#not_implemented? +* You can now stub!(:msg).with(specific args) +* describe("A", Hash, "with one element") will generate description "A Hash with one element" (Tip from Ola Bini) +* Applied [#13016] [DOC] Point out that view specs render, well, a view (Patch from Jay Levitt) +* Applied [#13078] Develop rspec with autotest (Patch from Scott Taylor) +* Fixed [#13065] Named routes throw a NoMethodError in Helper specs (Patches from James Deville and Mike Mangino) +* Added (back) the verbose attribute in Spec::Rake::SpecTask +* Changed documentation to point at the new http svn URL, which is more accessible. + +=== Version 1.0.8 + +Another bugfix release - this time to resolve the version mismatch + +=== Version 1.0.7 + +Quick bugfix release to ensure that you don't have to have the rspec gem installed +in order to use autotest with rspec_on_rails. + +* Fixed [#13015] autotest gives failure in 'spec_command' after upgrade 1.0.5 to 1.0.6 + +=== Version 1.0.6 + +The "holy cow, batman, it's been a long time since we released and there are a ton of bug +fixes, patches and even new features" release. + +Warning: Spec::Rails users: In fixing 11508, we've removed the raise_controller_errors method. As long as you +follow the upgrade instructions and run 'script/generate rspec' you'll be fine, but if you skip this +step you need to manually go into spec_helper.rb and remove the call to that method (if present - it +might not be if you haven't upgraded in a while). + +Warning: Implementors of custom formatters. Formatters will now be sent an Example object instead of just a +String for #example_started, #example_passed and #example_failed. In certain scenarios +(Spec::Ui with Spec::Distributed), the formatter must ask the Example for its sequence number instead of +keeping track of a sequence number internal to the formatter. Most of you shouldn't need to upgrade +your formatters though - the Example#to_s method returns the example name/description, so you should be +able to use the passed Example instance as if it were a String. + +* Applied [#12986] Autotest Specs + Refactoring (Patch from Scott Tayler) +* Added a #close method to formatters, which allows them to gracefully close streams. +* Applied [#12935] Remove requirement that mocha must be installed as a gem when used as mocking framework. (Patch from Ryan Kinderman). +* Fixed [#12893] RSpec's Autotest should work with rspec's trunk +* Fixed [#12865] Partial mock error when object has an @options instance var +* Applied [#12701] Allow checking of content captured with content_for in view specs (Patch from Jens Kr�mer) +* Applied [#12817] Cannot include same shared behaviour when required with absolute paths (Patch from Ian Leitch) +* Applied [#12719] rspec_on_rails should not include pagination helper (Patch from Matthijs Langenberg) +* Fixed [#12714] helper spec not finding rails core helpers +* Applied [#12611] should_not redirect_to implementation (Patch from Yurii Rashkovskii) +* Applied [#12682] Not correctly aliasing original 'stub!' and 'should_receive' methods for ApplicationController (Patch from Matthijs Langenberg) +* Disabled controller.should_receive(:render) and controller.stub!(:render). Use expect_render or stub_render instead. +* Applied [#12484] Allow a Behaviour's Description to flow through to the Formatter (Patch from Bob Cotton) +* Fixed [#12448] The spec:plugins rake task from rspec_on_rails should ignore specs from the rspec_on_rails plugin +* Applied [#12300] rr integration (patch from Kyle Hargraves) +* Implemented [#12284] mock_with :rr (integration with RR mock framework: http://rubyforge.org/projects/pivotalrb/) +* Applied [#12237] (tiny) added full path to mate in switch_command (Patch from Carl Porth) +* Formatters will now be sent an Example object instead of just a String for certain methods +* All Spec::Rake::SpecTask attributes can now be procs, which allows for lazy evaluation. +* Changed the Spec::Ui interfaces slightly. See examples. +* Applied [#12174] mishandling of paths with spaces in spec_mate switch_command (Patch from Carl Porth) +* Implemented [#8315] File "Go to..." functionality +* Applied [#11917] Cleaner Spec::Ui error for failed Selenium connection (Patch from Ian Dees) +* Applied [#11888] rspec_on_rails spews out warnings when assert_select is used with an XML response (Patch from Ian Leitch) +* Applied [#12010] Nicer failure message formatting (Patch from Wincent Colaiuta) +* Applied [#12156] smooth open mate patch (Patch from Ienaga Eiji) +* Applied [#10577] Rails with Oracle breaks 0.9.2. (Patch from Sinclair Bain) +* Fixed [#12079] auto-generated example name incomplete: should have 1 error on ....] +* Applied [#12066] Docfix for mocks/mocks.page (Patch from Kyle Hargraves) +* Fixed [#11891] script/generate rspec_controller fails to create appropriate views (from templates) on edge rails +* Applied [#11921] Adds the correct controller_name from derived_controller_name() to the ViewExampleGroupController (Patch from Eloy Duran) +* Fixed [#11903] config.include with behaviour_type 'hash' does not work +* Examples without blocks and pending is now reported with a P instead of a * +* Pending blocks that now pass are rendered blue +* New behaviour for after: If an after block raises an error, the other ones will still run instead of bailing at the first. +* Made it possible to run spec from RSpec.tmbundle with --drb against a Rails spec_server. +* Applied [#11868] Add ability for pending to optionally hold a failing block and to fail when it passes (Patch from Bob Cotton) +* Fixed [#11843] watir_behaviour missing from spec_ui gem +* Added 'switch between source and spec file' command in Spec::Mate (based on code from Ruy Asan) +* Applied [#11509] Documentation - RSpec requires hpricot +* Applied [#11807] Daemonize spec_server and rake tasks to manage them. (patch from Kyosuke MOROHASHI) +* Added pending(message) method +* Fixed [#11777] should render_template doesn't check paths correctly +* Fixed [#11749] Use of 'rescue => e' does not catch all exceptions +* Fixed [#11793] should raise_error('with a message') does not work correctly +* Fixed [#11774] Mocks should respond to :kind_of? in the same way they respond to :is_a? +* Fixed [#11508] Exceptions are not raised for Controller Specs (removed experimental raise_controller_errors) +* Applied [#11615] Partial mock methods give ambiguous failures when given a method name as a String (Patch from Jay Phillips) +* Fixed [#11545] Rspec doesn't handle should_receive on ActiveRecord associations (Patch from Ian White) +* Fixed [#11514] configuration.use_transactional_fixtures is ALWAYS true, regardless of assignment +* Improved generated RESTful controller examples to cover both successful and unsuccessful POST and PUT +* Changed TextMate snippets for controllers to pass controller class names to #describe rather than controller_name. +* Changed TextMate snippets for mocks to use no_args() and any_args() instead of the deprecated Symbols. +* Applied [#11500] Documentation: no rails integration specs in 1.0 +* Renamed SpecMate's shortcuts for running all examples and focused examples to avoid conflicts (CMD-d and CMD-i) +* Added a TextMate snippet for custom matchers, lifted from Geoffrey Grosenbach's RSpec peepcode show. +* The translator translates mock constraints to the new matchers that were introduced in 1.0.4 +* Documented environment variables for Spec::Rake::SpecTask. Renamed SPECOPTS and RCOVOPTS to SPEC_OPTS and RCOV_OPTS. +* Fixed [#10534] Windows: undefined method 'controller_name' + +=== Version 1.0.5 +Bug fixes. Autotest plugin tweaks. + +* Fixed [#11378] fix to 10814 broke drb (re-opened #10814) +* Fixed [#11223] Unable to access flash from rails helper specs +* Fixed [#11337] autotest runs specs redundantly +* Fixed [#11258] windows: autotest won't run +* Applied [#11253] Tweaks to autotest file mappings (Patch from Wincent Colaiuta) +* Applied [#11252] Should be able to re-load file containing shared behaviours without raising an exception (Patch from Wincent Colaiuta) +* Fixed [#11247] standalone autotest doesn't work because of unneeded autotest.rb +* Applied [#11221] Autotest support does not work w/o Rails Gem installed (Patch from Josh Knowles) + +=== Version 1.0.4 +The getting ready for JRuby release. + +* Fixed [#11181] behaviour_type scoping of config.before(:each) is not working +* added mock argument constraint matchers (anything(), boolean(), an_instance_of(Type)) which work with rspec or mocha +* added mock argument constraint matchers (any_args(), no_args()) which only work with rspec +* deprecated rspec's symbol mock argument constraint matchers (:any_args, :no_args, :anything, :boolean, :numeric, :string) +* Added tarball of rspec_on_rails to the release build to support folks working behind a firewall that blocks svn access. +* Fixed [#11137] rspec incorrectly handles flash after resetting the session +* Fixed [#11143] Views code for ActionController::Base#render broke between 1.0.0 and 1.0.3 on Rails Edge r6731 +* Added raise_controller_errors for controller examples in Spec::Rails + +=== Version 1.0.3 +Bug fixes. + +* Fixed [#11104] Website uses old specify notation +* Applied [#11101] StringHelpers.starts_with?(prefix) assumes a string parameter for _prefix_ +* Removed 'rescue nil' which was hiding errors in controller examples. +* Fixed [#11075] controller specs fail when using mocha without integrated_views +* Fixed problem with redirect_to failing incorrectly against edge rails. +* Fixed [#11082] RspecResourceGenerator should be RspecScaffoldGenerator +* Fixed [#10959] Focused Examples do not work for Behaviour defined with constant with modules + +=== Version 1.0.2 +This is just to align the version numbers in rspec and rspec_on_rails. + +=== Version 1.0.1 +This is a maintenance release with mostly cleaning up, and one minor enhancement - +Modules are automatically included when described directly. + +* Renamed Spec::Rails' rspec_resource generator to rspec_scaffold. +* Removed Spec::Rails' be_feed matcher since it's based on assert_select_feed which is not part of Rails (despite that docs for assert_select_encoded says it is). +* describe(SomeModule) will include that module in the examples. Like for Spec::Rails helpers, but now also in core. +* Header in HTML report will be yellow instead of red if there is one failed example +* Applied [#10951] Odd instance variable name in rspec_model template (patch from Kyle Hargraves) +* Improved integration with autotest (Patches from Ryan Davis and David Goodland) +* Some small fixes to make all specs run on JRuby. + +=== Version 1.0.0 +The stake in the ground release. This represents a commitment to the API as it is. No significant +backwards compatibility changes in the API are expected after this release. + +* Fixed [#10923] have_text matcher does not support should_not +* Fixed [#10673] should > and should >= broken +* Applied [#10921] Allow verify_rcov to accept greater than threshold coverage %'s via configuration +* Applied [#10920] Added support for not implemented examples (Patch from Chad Humphries and Ken Barker) +* Patch to allow not implemented examples. This works by not providing a block to the example. (Patch from Chad Humphries, Ken Barker) +* Yanked support for Rails 1.1.6 in Spec::Rails +* RSpec.tmbundle uses CMD-SHIFT-R to run focused examples now. +* Spec::Rails now bundles a spec:rcov task by default (suggestion from Kurt Schrader) +* Fixed [#10814] Runner loads shared code, test cases require them again +* Fixed [#10753] Global before and after +* Fixed [#10774] Allow before and after to be specified in config II +* Refactored Spec::Ui examples to use new global before and after blocks. +* Added instructions about how to get Selenium working with Spec::Ui (spec_ui/examples/selenium/README.txt) +* Fixed [#10805] selenium.rb missing from gem? +* Added rdocs explaining how to deal with errors in Rails' controller actions +* Applied [#10770] Finer grained includes. +* Fixed [#10747] Helper methods defined in shared specs are not visible when shared spec is used +* Fixed [#10748] Shared descriptions in separate files causes 'already exists' error +* Applied [#10698] Running with --drb executes specs twice (patch from Ruy Asan) +* Fixed [#10871] 0.9.4 - Focussed spec runner fails to run specs in descriptions with type and string when there is no leading space in the string + +=== Version 0.9.4 +This release introduces massive improvements to Spec::Ui - the user interface functional testing +extension to RSpec. There are also some minor bug fixes to the RSpec core. + +* Massive improvements to Spec::Ui. Complete support for all Watir's ie.xxx(how, what) methods. Inline screenshots and HTML. +* Reactivated --timeout, which had mysteriously been deactivated in a recent release. +* Fixed [#10669] Kernel#describe override does not cover Kernel#context +* Applied [#10636] Added spec for OptionParser in Runner (Patch from Scott Taylor) +* Added [#10516] should_include should be able to accept multiple items +* Applied [#10631] redirect_to matcher doesn't respect request.host (Patch from Tim Lucas) +* Each formatter now flushes their own IO. This is to avoid buffering of output. +* Fixed [#10670] IVarProxy#delete raises exception when instance variable does not exist + +=== Version 0.9.3 +This is a bugfix release. + +* Fixed [#10594] Failing Custom Matcher show NAME NOT GENERATED description +* describe(SomeType, "#message") will not add a space: "SomeType#message" (likewise for '.') +* describe(SomeType, "message") will have a decription with a space: "SomeType message" +* Applied [#10566] prepend_before and prepend_after callbacks +* Applied [#10567] Call setup and teardown using before and after callbacks + +=== Version 0.9.2 +This is a quick maintenance release. + +* Added some website love +* Fixed [#10542] reverse predicate matcher syntax +* Added a spec:translate Rake task to make 0.9 translation easier with Spec:Rails +* Better translation of should_redirect_to +* Fixed --colour support for Windows. This is a regression that was introduced in 0.9.1 +* Applied [#10460] Make SpecRunner easier to instantiate without using commandline args + +=== Version 0.9.1 + +This release introduces #describe and #it (aliased as #context and #specify for +backwards compatibility). This allows you to express specs like this: + + describe SomeClass do # Creates a Behaviour + it "should do something" do # Creates an Example + end + end + +The command line features four new options that give you more control over what specs +are being run and in what order. This can be used to verify that your specs are +independent (by running in opposite order with --reverse). It can also be used to cut +down feedback time by running the most recently modified specs first (--loadby mtime --reverse). + +Further, --example replaces the old --spec option, and it can now take a file name of +spec names as an alternative to just a spec name. The --format failing_examples:file.txt +option allows you to output an --example compatible file, which makes it possible to only +rerun the specs that failed in the last run. Spec::Rails uses all of these four options +by default to optimise your RSpec experience. + +There is now a simple configuration model. For Spec::Rails, you do something like this: + + Spec::Runner.configure do |config| + config.use_transactional_fixtures = true + config.use_instantiated_fixtures = false + config.fixture_path = RAILS_ROOT + '/spec/fixtures' + end + +You can now use mocha or flexmock with RSpec if you prefer either to +RSpec's own mock framework. Just put this: + + Spec::Runner.configure do |config| + config.mock_with :mocha + end + +or this: + + Spec::Runner.configure do |config| + config.mock_with :flexmock + end + +in a file that is loaded before your specs. You can also +configure included modules and predicate_matchers: + + Spec::Runner.configure do |config| + config.include SomeModule + config.predicate_matchers[:does_something?] = :do_something + end + +See Spec::DSL::Behaviour for more on predicate_matchers + +* Sugar FREE! +* Added [10434 ] Please Make -s synonymous with -e for autotest compat. This is temporary until autotest uses -e instead of -s. +* Fixed [#10133] custom predicate matchers +* Applied [#10473] Add should exist (new matcher) - Patch from Bret Pettichord +* Added another formatter: failing_behaviours. Writes the names of the failing behaviours for use with --example. +* Applied [#10315] Patch to fix pre_commit bug 10313 - pre_commit_rails: doesn't always build correctly (Patch from Antii Tarvainen) +* Applied [#10245] Patch to HTML escape the behavior name when using HTML Formatter (Patch from Josh Knowles) +* Applied [#10410] redirect_to does not behave consistently with regards to query string parameter ordering (Patch from Nicholas Evans) +* Applied [#9605] Patch for ER 9472, shared behaviour (Patch by Bob Cotton) +* The '--format rdoc' option no longer causes a dry-run by default. --dry-run must be used explicitly. +* It's possible to specify the output file in the --format option (See explanation in --help) +* Several --format options may be specified to output several formats in one run. +* The --out option is gone. Use --format html:path/to/my.html instead (or similar). +* Spec::Runner::Formatter::BaseTextFormatter#initialize only takes one argument - an IO. dry_run and color are setters. +* Made Spec::Ui *much* easier to install. It will be released separately. Check out trunk/spec_ui/examples +* HTML reports now include a syntax highlighted snippet of the source code where the spec failed (needs the syntax gem) +* Added [#10262] Better Helper testing of Erb evaluation block helpers +* Added [#9735] support flexmock (thanks to Jim Weirich for his modifications to flexmock to support this) +* Spec::Rails controller specs will no longer let mock exception ripple through to the response. +* Fixed [#9260] IvarProxy does not act like a hash. +* Applied [#9458] The rspec_scaffold generator does not take into account class nesting (Patch from Steve Tendon) +* Applied [#9132] Rakefile spec:doc can fail without preparing database (Patch from Steve Ross) +* Applied [#9678] Custom runner command line switch, and multi-threaded runner (Patch from Bob Cotton) +* Applied [#9926] Rakefile - RSPEC_DEPS constant as an Array of Hashes instead of an Array of Arrays (Patch from Scott Taylor) +* Applied [#9925] Changed ".rhtml" to "template" in REST spec generator (Patch from Scott Taylor) +* Applied [#9852] Patch for RSpec's Website using Webgen 0.4.2 (Patch from Scott Taylor) +* Fixed [#6523] Run rspec on rails without a db +* Fixed [#9295] rake spec should run anything in the spec directory (not just rspec's standard dirs) +* Added [#9786] infer controller and helper names from the described type +* Fixed [#7795] form_tag renders action='/view_spec' in view specs +* Fixed [#9767] rspec_on_rails should not define rescue_action on controllers +* Fixed [#9421] --line doesn't work with behaviours that use class names +* Fixed [#9760] rspec generators incompatible with changes to edge rails +* Added [#9786] infer controller and helper names from the described type +* Applied a simplified version of [#9282] Change to allow running specs from textmate with rspec installed as a rails plugin (and no rspec gem installed) +* Applied [#9700] Make Spec::DSL::Example#name public / Add a --timeout switch. A great way to prevent specs from getting slow. +* In Rails, script/generate rspec will generate a spec.opts file that optimises faster/more efficient running of specs. +* Added [#9522] support using rspec's expectations with test/unit +* Moved rspec_on_rails up to the project root, simplifying the download url +* Fixed [#8103] RSpec not installing spec script correctly. +* The --spec option is replaced by the --example option. +* The --loadby option no longer supports a file argument. Use --example file_name instead. +* The --example option can now take a file name as an argument. The file should contain example names. +* Internal classes are named Behaviour/Example (rather than Context/Specification). +* You can now use mocha by saying config.mock_with :mocha in a spec_helper +* before_context_eval is replaced by before_eval. +* Applied [#9509] allow spaced options in spec.opts +* Applied [#9510] Added File for Ruby 1.8.6 +* Applied [#9511] Clarification to README file in spec/ +* Moved all of the Spec::Rails specs down to the plugins directory - now you can run the specs after you install. +* Updated RSpec.tmbundle to the 0.9 syntax and replaced context/specify with describe/it. +* Applied [#9232] ActionController::Base#render is sometimes protected (patch from Dan Manges) +* Added --reverse option, allowing contexts/specs to be run in reverse order. +* Added --loadby option, allowing better control over load order for spec files. mtime and file.txt supported. +* Implemented [#8696] --order option (see --reverse and --loadby) +* Added describe/it as aliases for context/specify - suggestion from Dan North. +* Applied [#7637] [PATCH] add skip-migration option to rspec_scaffold generator +* Added [#9167] string.should have_tag +* Changed script/rails_spec_server to script/spec_server and added script/spec (w/ path to vendor/plugins/rspec) +* Fixed [#8897] Error when mixing controller spec with/without integrated views and using template system other than rhtml +* Updated sample app specs to 0.9 syntax +* Updated generated specs to 0.9 syntax +* Applied [#8994] trunk: generated names for be_ specs (Multiple patches from Yurii Rashkovskii) +* Applied [#9983]: Allow before and after to be called in BehaviourEval. This is useful for shared examples. + +=== Version 0.8.2 + +Replaced assert_select fork with an assert_select wrapper for have_tag. This means that "should have_rjs" no longer supports :hide or :effect, but you can still use should_have_rjs for those. + +=== Version 0.8.1 + +Quick "in house" bug-fix + +=== Version 0.8.0 + +This release introduces a new approach to handling expectations using Expression Matchers. + +See Upgrade[http://rspec.rubyforge.org/upgrade.html], Spec::Expectations, Spec::Matchers and RELEASE-PLAN for more info. + +This release also improves the spec command line by adding DRb support and making it possible to +store command line options in a file. This means a more flexible RSpec experience with Rails, +Rake and editor plugins like TextMate. + +It also sports myriad new features, bug fixes, patches and general goodness: + +* Fixed [#8928] rspec_on_rails 0.8.0-RC1 controller tests make double call to setup_with_fixtures +* Fixed [#8925] Documentation bug in 0.8.0RC1 rspec website +* Applied [#8132] [PATCH] RSpec breaks "rake db:sessions:create" in a rails project that has the rspec_on_rails plugin (Patch from Erik Kastner) +* Fixed [#8789] --line and --spec not working when the context has parenhesis in the name +* Added [#8783] auto generate spec names from last expectation +* --heckle now fails if the heckled class or module is not found. +* Fixed [#8771] Spec::Mocks::BaseExpectation#with converts hash params to array of arrays with #collect +* Fixed [#8750] should[_not]_include backwards compatibility between 0.8.0-RC1 and 0.7.5.1 broken +* Fixed [#8646] Context Runner does not report on Non standard exceptions and return a 0 return code +* RSpec on Rails' spec_helper.rb will only force RAILS_ENV to test if it was not specified on the command line. +* Fixed [#5485] proc#should_raise and proc#should_not_raise output +* Added [#8484] should_receive with blocks +* Applied [#8218] heckle_runner.rb doesn't work with heckle >= 1.2.0 (Patch from Michal Kwiatkowski) +* Fixed [#8240] Cryptic error message when no controller_name +* Applied [#7461] [PATCH] Contexts don't call Module::included when they include a module +* Removed unintended block of test/unit assertions in rspec_on_rails - they should all, in theory, now be accessible +* Added mock_model method to RSpec on Rails, which stubs common methods. Based on http://metaclass.org/2006/12/22/making-a-mockery-of-activerecord +* Fixed [#8165] Partial Mock Errors when respond_to? is true but the method is not in the object +* Fixed [#7611] Partial Mocks override Subclass methods +* Fixed [#8302] Strange side effect when mocking a class method +* Applied [#8316] to_param should return a stringified key in resource generator's controller spec (Patch from Chris Anderson) +* Applied [#8216] shortcut for creating object stub +* Applied [#8008] Correct generated specs for view when calling resource generator (Patch from Jonathan Tron) +* Fixed [#7754] Command-R fails to run spec in TextMate (added instruction from Luke Redpath to the website) +* Fixed [#7826] RSpect.tmbundle web page out of date. +* RSpec on Rails specs are now running against RoR 1.2.1 and 1.2.2 +* rspec_scaffold now generates specs for views +* In a Rails app, RSpec core is only loaded when RAILS_ENV==test (init.rb) +* Added support for target.should arbitrary_expectation_handler and target.should_not arbitrary_expectation_handler +* Fixed [#7533] Spec suite fails and the process exits with a code 0 +* Fixed [#7565] Subsequent stub! calls for method fail to override the first call to method +* Applied [#7524] Incorrect Documentation for 'pattern' in Rake task (patch from Stephen Duncan) +* Fixed [#7409] default fixtures do not appear to run. +* Fixed [#7507] "render..and return" doesn't return +* Fixed [#7509] rcov/rspec incorrectly includes boot.rb (Patch from Courtenay) +* Fixed [#7506] unnecessary complex output on failure of response.should be_redirect +* Applied [#6098] Make scaffold_resource generator. Based on code from Pat Maddox. +* The drbspec command is gone. Use spec --drb instead. +* The drb option is gone from the Rake task. Pass --drb to spec_opts instead. +* New -X/--drb option for running specs against a server like spec/rails' script/rails_spec_server +* New -O/--options and -G/--generate flags for file-based options (handy for spec/rails) +* Applied [#7339] Turn off caching in HTML reports +* Applied [#7419] "c option for colorizing output does not work with rails_spec" (Patch from Shintaro Kakutani) +* Applied [#7406] [PATCH] 0.7.5 rspec_on_rails loads fixtures into development database (Patch from Wilson Bilkovich) +* Applied [#7387] Allow stubs to return consecutive values (Patch from Pat Maddox) +* Applied [#7393] Fix for rake task (Patch from Pat Maddox) +* Reinstated support for response.should_render (in addition to controller.should_render) + +=== Version 0.7.5.1 + +Bug fix release to allow downloads of rspec gem using rubygems 0.9.1. + +=== Version 0.7.5 +This release adds support for Heckle - Seattle'rb's code mutation tool. +There are also several bug fixes to the RSpec core and the RSpec on Rails plugin. + +* Removed svn:externals on rails versions and plugins +* Applied [#7345] Adding context_setup and context_teardown, with specs and 100% rcov +* Applied [#7320] [PATCH] Allow XHR requests in controller specs to render RJS templates +* Applied [#7319] Migration code uses drop_column when it should use remove_column (patch from Pat Maddox) +* Added support for Heckle +* Applied [#7282] dump results even if spec is interrupted (patch from Kouhei Sutou) +* Applied [#7277] model.should_have(n).errors_on(:attribute) (patch from Wilson Bilkovich) +* Applied [#7270] RSpec render_partial colliding with simply_helpful (patch from David Goodlad) +* Added [#7250] stubs should support throwing +* Added [#7249] stubs should support yielding +* Fixed [#6760] fatal error when accessing nested finders in rspec +* Fixed [#7179] script/generate rspec_scaffold generates incorrect helper name +* Added preliminary support for assert_select (response.should_have) +* Fixed [#6971] and_yield does not work when the arity is -1 +* Fixed [#6898] Can we separate rspec from the plugins? +* Added [#7025] should_change should accept a block +* Applied [#6989] partials with locals (patch from Micah Martin) +* Applied [#7023] Typo in team.page + +=== Version 0.7.4 + +This release features a complete redesign of the reports generated with --format html. +As usual there are many bug fixes - mostly related to spec/rails. + +* Applied [#7010] Fixes :spacer_template does not work w/ view spec (patch from Shintaro Kakutani) +* Applied [#6798] ensure two ':' in the first backtrace line for Emacs's 'next-error' command (patch from Kouhei Sutou) +* Added Much nicer reports to generated website +* Much nicer reports with --format --html (patch from Luke Redpath) +* Applied [#6959] Calls to render and redirect in controllers should return true +* Fixed [#6981] helper method is not available in partial template. +* Added [#6978] mock should tell you the expected and actual args when receiving the right message with the wrong args +* Added the possibility to tweak the output of the HtmlFormatter (by overriding extra_failure_content). +* Fixed [#6936] View specs don't include ApplicationHelper by default +* Fixed [#6903] Rendering a partial in a view makes the view spec blow up +* Added callback library from Brian Takita +* Added [#6925] support controller.should_render :action_name +* Fixed [#6884] intermittent errors related to method binding +* Fixed [#6870] rspec on edge rails spec:controller fixture loading fails +* Using obj.inspect for all messages +* Improved performance by getting rid of instance_exec (instance_eval is good enough because we never need to pass it args) + +=== Version 0.7.3 + +Almost normal bug fix/new feature release. + +A couple of things you need to change in your rails specs: +# spec_helper.rb is a little different (see http://rspec.rubyforge.org/upgrade.html) +# use controller.should_render before OR after the action (controller.should_have_rendered is deprecated) + +* Applied [#6577] messy mock backtrace when frozen to edge rails (patch from Jay Levitt) +* Fixed [#6674] rspec_on_rails fails on @session deprecation warning +* Fixed [#6780] routing() was failing...fix included - works for 1.1.6 and edge (1.2) +* Fixed [#6835] bad message with arbitrary predicate +* Added [#6731] Partial templates rendered +* Fixed [#6713] helper methods not rendered in view tests? +* Fixed [#6707] cannot run controller / helper tests via rails_spec or spec only works with rake +* Applied [#6417] lambda {...}.should_change(receiver, :message) (patch from Wilson Bilkovich) +* Eliminated dependency on ZenTest +* Fixed [#6650] Reserved characters in the TextMate bundle break svn on Win32 +* Fixed [#6643] script/generate rspec_controller: invalid symbol generation for 'controller_name' for *modularized* controllers +* The script/rails_spec command has been moved to bin/drbspec in RSpec core (installed by the gem) + +=== Version 0.7.2 + +This release introduces a brand new RSpec bundle for TextMate, plus some small bugfixes. + +* Packaged RSpec.tmbundle.tgz as part of the distro +* Fixed [#6593] Add moving progress bar to HtmlFormatter using Javascript +* Applied [#6265] should_raise should accept an Exception object +* Fixed [#6616] Can't run Rails specs with RSpec.tmbundle +* Fixed [#6411] Can't run Rails specs with ruby +* Added [#6589] New -l --line option. This is useful for IDE/editor runners/extensions. +* Fixed [#6615] controller.should_render_rjs should support :partial => 'path/to/template' + +=== Version 0.7.1 + +Bug fixes and a couple o' new features. + +* Fixed [#6575] Parse error in aliasing the partial mock original method (patch by Brian Takita) +* Fixed [#6277] debris left by stubbing (trunk) [submitted by dastels] (fixed by fix to [#6575]) +* Fixed [#6575] Parse error in aliasing the partial mock original method +* Fixed [#6555] should_have_tag does not match documentation +* Fixed [#6567] SyntaxError should not stop entire run +* Fixed [#6558] integrated views look for template even when redirected +* Fixed [#6547] response.should be_redirect broken in 0.7.0 +* Applied [#6471] Easy way to spec routes +* Applied [#6587] Rspec on Rails displays "Spec::Rails::ContextFactory" as context name +* Applied [#6514] Document has trivial typos. +* Added [#6560] controller.session should be available before the action +* Added support for should_have_rjs :visual_effect +* Different printing and colours for unmet expectations (red) and other exceptions (magenta) +* Simplified method_missing on mock_methods to make it less invasive on partial mocks. + +=== Version 0.7.0 + +This is the "Grow up and eat your own dog food release". RSpec is now used on itself and +we're no longer using Test::Unit to test it. Although, we are still extending Test::Unit +for the rails plugin (indirectly - through ZenTest) + +IMPORTANT NOTE: THIS RELEASE IS NOT 100% BACKWARDS COMPATIBLE TO 0.6.x + +There are a few changes that will require that you change your existing specs. + +RSpec now handles equality exactly like ruby does: + +# actual.should_equal(expected) will pass if actual.equal?(expected) returns true +# actual.should eql(expected) will pass if actual.eql?(expected) returns true +# actual.should == expected will pass if actual == expected) returns true + +At the high level, eql? implies equivalence, while equal? implies object identity. For more +information on how ruby deals w/ equality, you should do this: + +ri equal? + +or look at this: + +http://www.ruby-doc.org/core/classes/Object.html#M001057 + +Also, we left in should_be as a synonym for should_equal, so the only specs that should break are the +ones using should_equal (which used to use == instead of .equal?). + +Lastly, should_be used to handle true and false differently from any other values. We've removed +this special handling, so now actual.should_be true will fail for any value other than true (it +used to pass for any non-nil, non-false value), and actual.should_be false will fail for any +value other than false (it used to pass for nil or false). + +Here's what you'll need to do to update your specs: +# search for "should_equal" and replace with "should_eql" +# run specs + +If any specs still fail, they are probably related to should be_true or should_be_false using +non-boolean values. Those you'll just have to inspect manually and adjust appropriately (sorry!). + +-------------------------------------------------- +Specifying multiple return values in mocks now works like this: + +mock.should_receive(:message).and_return(1,2,3) + +It used to work like this: + +mock.should_receive(:message).and_return([1,2,3]) + +but we decided that was counter intuitive and otherwise lame. + +Here's what you'll need to do to update your specs: +# search for "and_return([" +# get rid of the "[" and "]" + +-------------------------------------------------- +RSpec on Rails now supports the following (thanks to ZenTest upon which it is built): + +# Separate specs for models, views, controllers and helpers +# Controller specs are completely decoupled from the views by default (though you can tell them to couple themselves if you prefer) +# View specs are completely decoupled from app-specific controllers + +See http://rspec.rubyforge.org/documentation/rails/index.html for more information +-------------------------------------------------- +As usual, there are also other new features and bug fixes: + +* Added lots of documentation on mocks/stubs and the rails plugin. +* Added support for assigns[key] syntax for controller specs (to align w/ pre-existing syntax for view specs) +* Added support for controller.should_redirect_to +* RSpec on Rails automatically checks whether it's compatible with the installed RSpec +* Applied [#6393] rspec_on_rails uses deprecated '@response' instead of the accessor +* RSpec now has 100% spec coverage(!) +* Added support for stubbing and partial mocking +* Progress (....F..F.) is now coloured. Tweaked patch from KAKUTANI Shintaro. +* Backtrace now excludes the rcov runner (/usr/local/bin/rcov) +* Fixed [#5539] predicates do not work w/ rails +* Added [#6091] support for Regexp matching messages sent to should_raise +* Added [#6333] support for Regexp matching in mock arguments +* Applied [#6283] refactoring of diff support to allow selectable formats and custom differs +* Fixed [#5564] "ruby spec_file.rb" doesn't work the same way as "spec spec_file.rb" +* Fixed [#6056] Multiple output of failing-spec notice +* Fixed [#6233] Colours in specdoc +* Applied [#6207] Allows --diff option to diff target and expected's #inspect output (Patch by Lachie Cox) +* Fixed [#6203] Failure messages are misleading - consider using inspect. +* Added [#6334] subject.should_have_xyz will try to call subject.has_xyz? - use this for hash.should_have_key(key) +* Fixed [#6017] Rake task should ignore empty or non-existent spec-dirs + +=== Version 0.6.4 + +In addition to a number of bug fixes and patches, this release begins to formalize the support for +RSpec on Rails. + +* Added Christopher Petrilli's TextMate bundle to vendor/textmate/RSpec.tmbundle +* Fixed [#5909], once again supporting multi_word_predicates +* Applied [#5873] - response.should_have_rjs (initial patch from Jake Howerton, based on ARTS by Kevin Clark) +* Added generation of view specs for rspec_on_rails +* Applied [#5815] active_record_subclass.should_have(3).records +* Added support in "rake stats" for view specs (in spec/views) +* Applied [#5801] QuickRef.pdf should say RSpec, not rSpec +* Applied [#5728] rails_spec_runner fails on Windows (Patch from Lindsay Evans). +* Applied [#5708] RSpec Rails plugin rspec_controller generator makes specs that do not parse. +* Cleaned up RSpec on Rails so it doesn't pollute as much during bootstrapping. +* Added support for response.should_have_tag and response.should_not_have_tag (works just like assert_tag in rails) +* Added new -c, --colour, --color option for colourful (red/green) output. Inspired from Pat Eyler's Redgreen gem. +* Added examples for Watir and Selenium under the gem's vendor directory. +* Renamed rails_spec_runner to rails_spec_server (as referred to in the docs) +* Added support for trying a plural for arbitrary predicates. E.g. Album.should_exist(:name => "Hey Jude") will call Album.exists?(:name => "Hey Jude") +* Added support for should_have to work with methods taking args returning a collection. E.g. @dave.should_have(3).albums_i_have_that_this_guy_doesnt(@aslak) +* Added [#5570] should_not_receive(:msg).with(:specific, "args") +* Applied [#5065] to support using define_method rather than method_missing to capture expected messages on mocks. Thanks to Eero Saynatkari for the tip that made it work. +* Restructured directories and Modules in order to separate rspec into three distinct Modules: Spec::Expectations, Spec::Runner and Spec::Mocks. This will allow us to more easily integrate other mock frameworks and/or allow test/unit users to take advantage of the expectation API. +* Applied [#5620] support any boolean method and arbitrary comparisons (5.should_be < 6) (Patch from Mike Williams) + +=== Version 0.6.3 + +This release fixes some minor bugs related to RSpec on Rails +Note that if you upgrade a rails app with this version of the rspec_on_rails plugin +you should remove your lib/tasks/rspec.rake if it exists. + +* Backtraces from drb (and other standard ruby libraries) are now stripped from backtraces. +* Applied [#5557] Put rspec.rake into the task directory of the RSpec on Rails plugin (Patch from Daniel Siemssen) +* Applied [#5556] rails_spec_server loads environment.rb twice (Patch from Daniel Siemssen) + +=== Version 0.6.2 +This release fixes a couple of regressions with the rake task that were introduced in the previous version (0.6.1) + +* Fixed [#5518] ruby -w: warnings in 0.6.1 +* Applied [#5525] fix rake task path to spec tool for gem-installed rspec (patch from Riley Lynch) +* Fixed a teensey regression with the rake task - introduced in 0.6.1. The spec command is now quoted so it works on windows. + +=== Version 0.6.1 +This is the "fix the most annoying bugs release" of RSpec. There are 9 bugfixes this time. +Things that may break backwards compatibility: +1) Spec::Rake::SpecTask no longer has the options attribute. Use ruby_opts, spec_opts and rcov_opts instead. + +* Fixed [#4891] RCOV task failing on windows +* Fixed [#4896] Shouldn't modify user's $LOAD_PATH (Tip from Gavin Sinclair) +* Fixed [#5369] ruby -w: warnings in RSpec 0.5.16 (Tip from Suraj Kurapati) +* Applied [#5141] ExampleMatcher doesn't escape strings before matching (Patch from Nikolai Weibull). +* Fixed [#5224] Move 'require diff-lcs' from test_helper.rb to diff_test.rb (Tip from Chris Roos) +* Applied [#5449] Rake stats for specs (Patch from Nick Sieger) +* Applied [#5468, #5058] Fix spec runner to correctly run controller specs (Patch from Daniel Siemssen) +* Applied fixes to rails_spec_server to improve its ability to run several times. (Patch from Daniel Siemssen) +* Changed RCov::VerifyTask to fail if the coverage is above the threshold. This is to ensure it gets bumped when coverage improves. + +=== Version 0.6.0 +This release makes an official commitment to underscore_syntax (with no more support for dot.syntax) + +* Fixed bug (5292) that caused mock argument matching to fail +* Converted ALL tests to use underscore syntax +* Fixed all remaining problems with underscores revealed by converting all the tests to underscores +* Enhanced sugar to support combinations of methods (i.e. once.and_return) +* Simplified helper structure taking advantage of dot/underscore combos (i.e. should.be.an_instance_of, which can be expressed as should be_an_instance_of) +* Added support for at_most in mocks +* Added support for should_not_receive(:msg) (will be removing should_receive(:msg).never some time soon) +* Added support for should_have_exactly(5).items_in_collection + +=== Version 0.5.16 +This release improves Rails support and test2spec translation. + +* Fixed underscore problems that occurred when RSpec was used in Rails +* Simplified the Rails support by packaging it as a plugin instead of a generator gem. +* Fixed [#5063] 'rspec_on_rails' require line in spec_helper.rb +* Added pre_commit rake task to reduce risk of regressions. Useful for RSpec developers and patchers. +* Added failure_message to RSpec Rake task +* test2spec now defines converted helper methods outside of the setup block (bug #5057). + +=== Version 0.5.15 +This release removes a prematurely added feature that shouldn't have been added. + +* Removed support for differences that was added in 0.5.14. The functionality is not aligned with RSpec's vision. + +=== Version 0.5.14 +This release introduces better ways to extend specs, improves some of the core API and +a experimental support for faster rails specs. + +* Added proc methods for specifying differences (increments and decrements). See difference_test.rb +* Methods can now be defined alongside specs. This obsoletes the need for defining methods in setup. (Patch #5002 from Brian Takita) +* Sugar (underscores) now works correctly with should be_a_kind_of and should be_an_instance_of +* Added support for include and inherit in contexts. (Patch #4971 from Brian Takita) +* Added rails_spec and rails_spec_server for faster specs on rails (still buggy - help needed) +* Fixed bug that caused should_render to break if given a :symbol (in Rails) +* Added support for comparing exception message in should_raise and should_not_raise + +=== Version 0.5.13 +This release fixes some subtle bugs in the mock API. + +* Use fully-qualified class name of Exceptions in failure message. Easier to debug that way. +* Fixed a bug that caused mocks to yield a one-element array (rather than the element) when one yield arg specified. +* Mocks not raise AmbiguousReturnError if an explicit return is used at the same time as an expectation block. +* Blocks passed to yielding mocks can now raise without causing mock verification to fail. + +=== Version 0.5.12 +This release adds diff support for failure messages, a HTML formatter plus some other +minor enhancements. + +* Added HTML formatter. +* Added fail_on_error option to spectask. +* Added support for diffing, using the diff-lcs Rubygem (#2648). +* Remove RSpec on Rails files from backtrace (#4694). +* All of RSpec's own tests run successfully after translation with test2spec. +* Added --verbose mode for test2spec - useful for debugging when classes fail to translate. +* Output of various formatters is now flushed - to get more continuous output. + +=== Version 0.5.11 +This release makes test2spec usable with Rails (with some manual steps). +See http://rspec.rubyforge.org/tools/rails.html for more details + +* test2spec now correctly translates bodies of helper methods (non- test_*, setup and teardown ones). +* Added more documentation about how to get test2spec to work with Rails. + +=== Version 0.5.10 +This version features a second rewrite of test2spec - hopefully better than the previous one. + +* Improved test2spec's internals. It now transforms the syntax tree before writing out the code. + +=== Version 0.5.9 +This release improves test2spec by allowing more control over the output + +* Added --template option to test2spec, which allows for custom output driven by ERB +* Added --quiet option to test2spec +* Removed unnecessary dependency on RubyToC + +=== Version 0.5.8 +This release features a new Test::Unit to RSpec translation tool. +Also note that the RubyGem of the previous release (0.5.7) was corrupt. +We're close to being able to translate all of RSpec's own Test::Unit +tests and have them run successfully! + +* Updated test2spec documentation. +* Replaced old test2rspec with a new test2spec, which is based on ParseTree and RubyInline. + +=== Version 0.5.7 +This release changes examples and documentation to recommend underscores rather than dots, +and addresses some bugfixes and changes to the spec commandline. + +* spec DIR now works correctly, recursing down and slurping all *.rb files +* All documentation and examples are now using '_' instead of '.' +* Custom external formatters can now be specified via --require and --format. + +=== Version 0.5.6 +This release fixes a bug in the Rails controller generator + +* The controller generator did not write correct source code (missing 'do'). Fixed. + +=== Version 0.5.5 +This release adds initial support for Ruby on Rails in the rspec_generator gem. + +* [Rails] Reorganised Lachie's original code to be a generator packaged as a gem rather than a plugin. +* [Rails] Imported code from http://lachie.info/svn/projects/rails_plugins/rspec_on_rails (Written by Lachie Cox) +* Remove stack trace lines from TextMate's Ruby bundle +* Better error message from spectask when no spec files are found. + +=== Version 0.5.4 +The "the tutorial is ahead of the gem" release + +* Support for running a single spec with --spec +* Exitcode is now 1 unless all specs pass, in which case it's 0. +* -v, --version now both mean the same thing +* For what was verbose output (-v), use --format specdoc or -f s +* --format rdoc always runs in dry-run mode +* Removed --doc and added --format and --dry-run +* Refactored towards more pluggable formatters +* Use webgen's execute tag when generating website (more accurate) +* Fixed incorrect quoting of spec_opts in SpecTask +* Added patch to enable underscored shoulds like 1.should_equal(1) - patch from Rich Kilmer +* Removed most inherited instance method from Mock, making more methods mockable. +* Made the RCovVerify task part of the standard toolset. +* Documented Rake task and how to use it with Rcov +* Implemented tags for website (hooking into ERB, RedCloth and syntax) +* RSpec Rake task now takes spec_opts and out params so it can be used for doc generation +* RCov integration for RSpec Rake task (#4058) +* Group all results instead of printing them several times (#4057) +* Mocks can now yield +* Various improvements to error reporting (including #4191) +* backtrace excludes rspec code - use -b to include it +* split examples into examples (passing) and failing_examples + +=== Version 0.5.3 +The "hurry up, CoR is in two days" release. + +* Don't run rcov by default +* Make separate task for running tests with RCov +* Added Rake task to fail build if coverage drops below a certain threshold +* Even more failure output cleanup (simplification) +* Added duck_type constraint for mocks + +=== Version 0.5.2 +This release has minor improvements to the commandline and fixes some gem warnings + +* Readded README to avoid RDoc warnings +* Added --version switch to commandline +* More changes to the mock API + +=== Version 0.5.1 +This release is the first release of RSpec with a new website. It will look better soon. + +* Added initial documentation for API +* Added website based on webgen +* Modified test task to use rcov +* Deleted unused code (thanks, rcov!) +* Various changes to the mock API, +* Various improvements to failure reporting + +=== Version 0.5.0 +This release introduces a new API and obsolesces previous versions. + +* Moved source code to separate subfolders +* Added new DSL runner based on instance_exec +* Added spike for testdox/rdoc generation +* merge Astels' and Chelimsky's work on ShouldHelper +* this would be 0.5.0 if I updated the documentation +* it breaks all of your existing specifications. We're not sorry. + +=== Version 0.3.2 + +The "srbaker is an idiot" release. + +* also forgot to update the path to the actual Subversion repository +* this should be it + +=== Version 0.3.1 + +This is just 0.3.0, but with the TUTORIAL added to the documentation list. + +* forgot to include TUTORIAL in the documentation + +=== Version 0.3.0 + +It's been a while since last release, lots of new stuff is available. For instance: + +* improvements to the runners +* addition of should_raise expectation (thanks to Brian Takita) +* some documentation improvements +* RSpec usable as a DSL + +=== Version 0.2.0 + +This release provides a tutorial for new users wishing to get started with +RSpec, and many improvements. + +* improved reporting in the spec runner output +* update the examples to the new mock api +* added TUTORIAL, a getting started document for new users of RSpec + +=== Version 0.1.7 + +This release improves installation and documentation, mock integration and error reporting. + +* Comparison errors now print the class name too. +* Mocks now take an optional +options+ parameter to specify behaviour. +* Removed __expects in favour of should_receive +* Added line number reporting in mock error messages for unreceived message expectations. +* Added should_match and should_not_match. +* Added a +mock+ method to Spec::Context which will create mocks that autoverify (no need to call __verify). +* Mocks now require names in the constructor to ensure sensible error messages. +* Made 'spec' executable and updated usage instructions in README accordingly. +* Made more parts of the Spec::Context API private to avoid accidental usage. +* Added more RDoc to Spec::Context. + +=== Version 0.1.6 + +More should methods. + +* Added should_match and should_not_match. + +=== Version 0.1.5 + +Included examples and tests in gem. + +=== Version 0.1.4 + +More tests on block based Mock expectations. + +=== Version 0.1.3 + +Improved mocking: + +* block based Mock expectations. + +=== Version 0.1.2 + +This release adds some improvements to the mock API and minor syntax improvements + +* Added Mock.should_expect for a more consistent DSL. +* Added MockExpectation.and_returns for a better DSL. +* Made Mock behave as a null object after a call to Mock.ignore_missing +* Internal syntax improvements. +* Improved exception trace by adding exception class name to error message. +* Renamed some tests for better consistency. + +=== Version 0.1.1 + +This release adds some shoulds and improves error reporting + +* Added should be_same_as and should_not be_same_as. +* Improved error reporting for comparison expectations. + +=== Version 0.1.0 + +This is the first preview release of RSpec, a Behaviour-Driven Development library for Ruby + +* Added Rake script with tasks for gems, rdoc etc. +* Added an XForge task to make release go easier. diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/License.txt b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/License.txt new file mode 100644 index 00000000..52c061f8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/License.txt @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2005-2009 The RSpec Development Team + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Manifest.txt b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Manifest.txt new file mode 100644 index 00000000..9659ba11 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Manifest.txt @@ -0,0 +1,372 @@ +.document +History.rdoc +License.txt +Manifest.txt +README.rdoc +Rakefile +Ruby1.9.rdoc +TODO.txt +Upgrade.rdoc +bin/autospec +bin/spec +cucumber.yml +examples/failing/README.txt +examples/failing/diffing_spec.rb +examples/failing/failing_implicit_docstrings_example.rb +examples/failing/failure_in_after.rb +examples/failing/failure_in_before.rb +examples/failing/mocking_example.rb +examples/failing/mocking_with_flexmock.rb +examples/failing/mocking_with_mocha.rb +examples/failing/mocking_with_rr.rb +examples/failing/partial_mock_example.rb +examples/failing/pending_example.rb +examples/failing/predicate_example.rb +examples/failing/raising_example.rb +examples/failing/spec_helper.rb +examples/failing/syntax_error_example.rb +examples/failing/team_spec.rb +examples/failing/timeout_behaviour.rb +examples/passing/custom_formatter.rb +examples/passing/custom_matchers.rb +examples/passing/dynamic_spec.rb +examples/passing/file_accessor.rb +examples/passing/file_accessor_spec.rb +examples/passing/filtered_formatter.rb +examples/passing/filtered_formatter_example.rb +examples/passing/greeter_spec.rb +examples/passing/helper_method_example.rb +examples/passing/implicit_docstrings_example.rb +examples/passing/io_processor.rb +examples/passing/io_processor_spec.rb +examples/passing/mocking_example.rb +examples/passing/multi_threaded_example_group_runner.rb +examples/passing/nested_classes_example.rb +examples/passing/options_example.rb +examples/passing/options_formatter.rb +examples/passing/partial_mock_example.rb +examples/passing/pending_example.rb +examples/passing/predicate_example.rb +examples/passing/shared_example_group_example.rb +examples/passing/shared_stack_examples.rb +examples/passing/simple_matcher_example.rb +examples/passing/spec_helper.rb +examples/passing/stack.rb +examples/passing/stack_spec.rb +examples/passing/stack_spec_with_nested_example_groups.rb +examples/passing/stubbing_example.rb +examples/passing/yielding_example.rb +examples/ruby1.9.compatibility/access_to_constants_spec.rb +features/before_and_after_blocks/before_and_after_blocks.feature +features/command_line/line_number_option.feature +features/command_line/line_number_option_with_example_with_no_name.feature +features/example_groups/example_group_with_should_methods.feature +features/example_groups/implicit_docstrings.feature +features/example_groups/nested_groups.feature +features/expectations/expect_change.feature +features/expectations/expect_error.feature +features/extensions/custom_example_group.feature +features/formatters/custom_formatter.feature +features/heckle/heckle.feature +features/interop/examples_and_tests_together.feature +features/interop/rspec_output.feature +features/interop/test_but_not_test_unit.feature +features/interop/test_case_with_should_methods.feature +features/matchers/define_diffable_matcher.feature +features/matchers/define_matcher.feature +features/matchers/define_matcher_outside_rspec.feature +features/mock_framework_integration/use_flexmock.feature +features/mock_framework_integration/use_mocha.feature +features/mock_framework_integration/use_rr.feature +features/mocks/mix_stubs_and_mocks.feature +features/mocks/stub_implementation.feature +features/pending/pending_examples.feature +features/runner/specify_line_number.feature +features/step_definitions/running_rspec_steps.rb +features/subject/explicit_subject.feature +features/subject/implicit_subject.feature +features/support/env.rb +features/support/matchers/smart_match.rb +init.rb +lib/autotest/discover.rb +lib/autotest/rspec.rb +lib/spec.rb +lib/spec/adapters/mock_frameworks/flexmock.rb +lib/spec/adapters/mock_frameworks/mocha.rb +lib/spec/adapters/mock_frameworks/rr.rb +lib/spec/adapters/mock_frameworks/rspec.rb +lib/spec/autorun.rb +lib/spec/deprecation.rb +lib/spec/dsl.rb +lib/spec/dsl/main.rb +lib/spec/example.rb +lib/spec/example/args_and_options.rb +lib/spec/example/before_and_after_hooks.rb +lib/spec/example/errors.rb +lib/spec/example/example_group.rb +lib/spec/example/example_group_factory.rb +lib/spec/example/example_group_hierarchy.rb +lib/spec/example/example_group_methods.rb +lib/spec/example/example_group_proxy.rb +lib/spec/example/example_matcher.rb +lib/spec/example/example_methods.rb +lib/spec/example/example_proxy.rb +lib/spec/example/module_reopening_fix.rb +lib/spec/example/pending.rb +lib/spec/example/predicate_matchers.rb +lib/spec/example/shared_example_group.rb +lib/spec/example/subject.rb +lib/spec/expectations.rb +lib/spec/expectations/errors.rb +lib/spec/expectations/extensions.rb +lib/spec/expectations/extensions/kernel.rb +lib/spec/expectations/fail_with.rb +lib/spec/expectations/handler.rb +lib/spec/interop/test.rb +lib/spec/interop/test/unit/autorunner.rb +lib/spec/interop/test/unit/testcase.rb +lib/spec/interop/test/unit/testresult.rb +lib/spec/interop/test/unit/testsuite_adapter.rb +lib/spec/interop/test/unit/ui/console/testrunner.rb +lib/spec/matchers.rb +lib/spec/matchers/be.rb +lib/spec/matchers/be_close.rb +lib/spec/matchers/be_instance_of.rb +lib/spec/matchers/be_kind_of.rb +lib/spec/matchers/change.rb +lib/spec/matchers/compatibility.rb +lib/spec/matchers/dsl.rb +lib/spec/matchers/eql.rb +lib/spec/matchers/equal.rb +lib/spec/matchers/errors.rb +lib/spec/matchers/exist.rb +lib/spec/matchers/extensions/instance_exec.rb +lib/spec/matchers/generated_descriptions.rb +lib/spec/matchers/has.rb +lib/spec/matchers/have.rb +lib/spec/matchers/include.rb +lib/spec/matchers/match.rb +lib/spec/matchers/match_array.rb +lib/spec/matchers/matcher.rb +lib/spec/matchers/method_missing.rb +lib/spec/matchers/operator_matcher.rb +lib/spec/matchers/pretty.rb +lib/spec/matchers/raise_error.rb +lib/spec/matchers/respond_to.rb +lib/spec/matchers/satisfy.rb +lib/spec/matchers/simple_matcher.rb +lib/spec/matchers/throw_symbol.rb +lib/spec/matchers/wrap_expectation.rb +lib/spec/mocks.rb +lib/spec/mocks/argument_expectation.rb +lib/spec/mocks/argument_matchers.rb +lib/spec/mocks/error_generator.rb +lib/spec/mocks/errors.rb +lib/spec/mocks/extensions.rb +lib/spec/mocks/extensions/object.rb +lib/spec/mocks/framework.rb +lib/spec/mocks/message_expectation.rb +lib/spec/mocks/methods.rb +lib/spec/mocks/mock.rb +lib/spec/mocks/order_group.rb +lib/spec/mocks/proxy.rb +lib/spec/mocks/space.rb +lib/spec/mocks/spec_methods.rb +lib/spec/rake/spectask.rb +lib/spec/rake/verify_rcov.rb +lib/spec/ruby.rb +lib/spec/runner.rb +lib/spec/runner/backtrace_tweaker.rb +lib/spec/runner/class_and_arguments_parser.rb +lib/spec/runner/command_line.rb +lib/spec/runner/configuration.rb +lib/spec/runner/differs/default.rb +lib/spec/runner/differs/load-diff-lcs.rb +lib/spec/runner/drb_command_line.rb +lib/spec/runner/example_group_runner.rb +lib/spec/runner/extensions/kernel.rb +lib/spec/runner/formatter/base_formatter.rb +lib/spec/runner/formatter/base_text_formatter.rb +lib/spec/runner/formatter/failing_example_groups_formatter.rb +lib/spec/runner/formatter/failing_examples_formatter.rb +lib/spec/runner/formatter/html_formatter.rb +lib/spec/runner/formatter/nested_text_formatter.rb +lib/spec/runner/formatter/no_op_method_missing.rb +lib/spec/runner/formatter/profile_formatter.rb +lib/spec/runner/formatter/progress_bar_formatter.rb +lib/spec/runner/formatter/silent_formatter.rb +lib/spec/runner/formatter/snippet_extractor.rb +lib/spec/runner/formatter/specdoc_formatter.rb +lib/spec/runner/formatter/text_mate_formatter.rb +lib/spec/runner/heckle_runner.rb +lib/spec/runner/heckle_runner_unsupported.rb +lib/spec/runner/line_number_query.rb +lib/spec/runner/option_parser.rb +lib/spec/runner/options.rb +lib/spec/runner/reporter.rb +lib/spec/test/unit.rb +lib/spec/version.rb +resources/helpers/cmdline.rb +resources/rake/examples.rake +resources/rake/examples_with_rcov.rake +resources/rake/failing_examples_with_html.rake +resources/rake/verify_rcov.rake +spec/README.jruby +spec/autotest/autotest_helper.rb +spec/autotest/autotest_matchers.rb +spec/autotest/discover_spec.rb +spec/autotest/failed_results_re_spec.rb +spec/autotest/rspec_spec.rb +spec/rspec_suite.rb +spec/ruby_forker.rb +spec/spec.opts +spec/spec/dsl/main_spec.rb +spec/spec/example/example_group_class_definition_spec.rb +spec/spec/example/example_group_factory_spec.rb +spec/spec/example/example_group_methods_spec.rb +spec/spec/example/example_group_proxy_spec.rb +spec/spec/example/example_group_spec.rb +spec/spec/example/example_matcher_spec.rb +spec/spec/example/example_methods_spec.rb +spec/spec/example/example_proxy_spec.rb +spec/spec/example/helper_method_spec.rb +spec/spec/example/nested_example_group_spec.rb +spec/spec/example/pending_module_spec.rb +spec/spec/example/predicate_matcher_spec.rb +spec/spec/example/shared_example_group_spec.rb +spec/spec/example/subclassing_example_group_spec.rb +spec/spec/example/subject_spec.rb +spec/spec/expectations/differs/default_spec.rb +spec/spec/expectations/extensions/object_spec.rb +spec/spec/expectations/fail_with_spec.rb +spec/spec/expectations/handler_spec.rb +spec/spec/expectations/wrap_expectation_spec.rb +spec/spec/interop/test/unit/resources/spec_that_fails.rb +spec/spec/interop/test/unit/resources/spec_that_passes.rb +spec/spec/interop/test/unit/resources/spec_with_errors.rb +spec/spec/interop/test/unit/resources/spec_with_options_hash.rb +spec/spec/interop/test/unit/resources/test_case_that_fails.rb +spec/spec/interop/test/unit/resources/test_case_that_passes.rb +spec/spec/interop/test/unit/resources/test_case_with_errors.rb +spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb +spec/spec/interop/test/unit/spec_spec.rb +spec/spec/interop/test/unit/test_unit_spec_helper.rb +spec/spec/interop/test/unit/testcase_spec.rb +spec/spec/interop/test/unit/testsuite_adapter_spec.rb +spec/spec/matchers/be_close_spec.rb +spec/spec/matchers/be_instance_of_spec.rb +spec/spec/matchers/be_kind_of_spec.rb +spec/spec/matchers/be_spec.rb +spec/spec/matchers/change_spec.rb +spec/spec/matchers/compatibility_spec.rb +spec/spec/matchers/description_generation_spec.rb +spec/spec/matchers/dsl_spec.rb +spec/spec/matchers/eql_spec.rb +spec/spec/matchers/equal_spec.rb +spec/spec/matchers/exist_spec.rb +spec/spec/matchers/has_spec.rb +spec/spec/matchers/have_spec.rb +spec/spec/matchers/include_spec.rb +spec/spec/matchers/match_array_spec.rb +spec/spec/matchers/match_spec.rb +spec/spec/matchers/matcher_methods_spec.rb +spec/spec/matchers/matcher_spec.rb +spec/spec/matchers/matchers_spec.rb +spec/spec/matchers/operator_matcher_spec.rb +spec/spec/matchers/raise_error_spec.rb +spec/spec/matchers/respond_to_spec.rb +spec/spec/matchers/satisfy_spec.rb +spec/spec/matchers/simple_matcher_spec.rb +spec/spec/matchers/throw_symbol_spec.rb +spec/spec/mocks/any_number_of_times_spec.rb +spec/spec/mocks/argument_expectation_spec.rb +spec/spec/mocks/at_least_spec.rb +spec/spec/mocks/at_most_spec.rb +spec/spec/mocks/bug_report_10260_spec.rb +spec/spec/mocks/bug_report_10263_spec.rb +spec/spec/mocks/bug_report_11545_spec.rb +spec/spec/mocks/bug_report_15719_spec.rb +spec/spec/mocks/bug_report_496_spec.rb +spec/spec/mocks/bug_report_600_spec.rb +spec/spec/mocks/bug_report_7611_spec.rb +spec/spec/mocks/bug_report_7805_spec.rb +spec/spec/mocks/bug_report_8165_spec.rb +spec/spec/mocks/bug_report_8302_spec.rb +spec/spec/mocks/bug_report_830_spec.rb +spec/spec/mocks/failing_argument_matchers_spec.rb +spec/spec/mocks/hash_including_matcher_spec.rb +spec/spec/mocks/hash_not_including_matcher_spec.rb +spec/spec/mocks/mock_ordering_spec.rb +spec/spec/mocks/mock_space_spec.rb +spec/spec/mocks/mock_spec.rb +spec/spec/mocks/multiple_return_value_spec.rb +spec/spec/mocks/nil_expectation_warning_spec.rb +spec/spec/mocks/null_object_mock_spec.rb +spec/spec/mocks/once_counts_spec.rb +spec/spec/mocks/options_hash_spec.rb +spec/spec/mocks/partial_mock_spec.rb +spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +spec/spec/mocks/passing_argument_matchers_spec.rb +spec/spec/mocks/precise_counts_spec.rb +spec/spec/mocks/record_messages_spec.rb +spec/spec/mocks/stub_chain_spec.rb +spec/spec/mocks/stub_implementation_spec.rb +spec/spec/mocks/stub_spec.rb +spec/spec/mocks/stubbed_message_expectations_spec.rb +spec/spec/mocks/twice_counts_spec.rb +spec/spec/package/bin_spec_spec.rb +spec/spec/rake/spectask_spec.rb +spec/spec/runner/class_and_argument_parser_spec.rb +spec/spec/runner/command_line_spec.rb +spec/spec/runner/configuration_spec.rb +spec/spec/runner/drb_command_line_spec.rb +spec/spec/runner/empty_file.txt +spec/spec/runner/example_group_runner_spec.rb +spec/spec/runner/examples.txt +spec/spec/runner/failed.txt +spec/spec/runner/formatter/base_formatter_spec.rb +spec/spec/runner/formatter/base_text_formatter_spec.rb +spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +spec/spec/runner/formatter/failing_examples_formatter_spec.rb +spec/spec/runner/formatter/html_formatted-1.8.4.html +spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html +spec/spec/runner/formatter/html_formatted-1.8.5.html +spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html +spec/spec/runner/formatter/html_formatted-1.8.6.html +spec/spec/runner/formatter/html_formatted-1.8.7.html +spec/spec/runner/formatter/html_formatted-1.9.1.html +spec/spec/runner/formatter/html_formatter_spec.rb +spec/spec/runner/formatter/nested_text_formatter_spec.rb +spec/spec/runner/formatter/profile_formatter_spec.rb +spec/spec/runner/formatter/progress_bar_formatter_spec.rb +spec/spec/runner/formatter/snippet_extractor_spec.rb +spec/spec/runner/formatter/specdoc_formatter_spec.rb +spec/spec/runner/formatter/text_mate_formatted-1.8.4.html +spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +spec/spec/runner/formatter/text_mate_formatter_spec.rb +spec/spec/runner/heckle_runner_spec.rb +spec/spec/runner/heckler_spec.rb +spec/spec/runner/line_number_query/line_number_query_fixture.rb +spec/spec/runner/line_number_query_spec.rb +spec/spec/runner/noisy_backtrace_tweaker_spec.rb +spec/spec/runner/option_parser_spec.rb +spec/spec/runner/options_spec.rb +spec/spec/runner/output_one_time_fixture.rb +spec/spec/runner/output_one_time_fixture_runner.rb +spec/spec/runner/output_one_time_spec.rb +spec/spec/runner/quiet_backtrace_tweaker_spec.rb +spec/spec/runner/reporter_spec.rb +spec/spec/runner/resources/a_bar.rb +spec/spec/runner/resources/a_foo.rb +spec/spec/runner/resources/a_spec.rb +spec/spec/runner/resources/custom_example_group_runner.rb +spec/spec/runner/resources/utf8_encoded.rb +spec/spec/runner/spec.opts +spec/spec/runner/spec_drb.opts +spec/spec/runner/spec_spaced.opts +spec/spec/runner_spec.rb +spec/spec/spec_classes.rb +spec/spec_helper.rb +spec/support/macros.rb diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/README.rdoc b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/README.rdoc new file mode 100644 index 00000000..3174497a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/README.rdoc @@ -0,0 +1,55 @@ += RSpec + +* http://rspec.info +* http://rubyforge.org/projects/rspec +* http://github.com/dchelimsky/rspec/wikis +* mailto:rspec-users@rubyforge.org +* mailto:rspec-devel@rubyforge.org + +== DESCRIPTION: + +RSpec is a Behaviour Driven Development framework for writing executable code +examples. + +== FEATURES: + +* Spec::Example provides a framework for organizing executable code examples +* Spec::Expectations adds #should and #should_not to every object +* Spec::Matchers provides Expression Matchers for use with #should and #should_not +* Spec::Mocks is a full featured mock object/stubbing library + +== SYNOPSIS: + + describe Account do + context "transfering money" do + it "deposits transfer amount to the other account" do + source = Account.new(50, :USD) + target = mock('target account') + target.should_receive(:deposit).with(Money.new(5, :USD)) + source.transfer(5, :USD).to(target) + end + + it "reduces its balance by the transfer amount" do + source = Account.new(50, :USD) + target = stub('target account') + source.transfer(5, :USD).to(target) + source.balance.should == Money.new(45, :USD) + end + end + end + + $ spec spec/account_spec.rb --format nested + Account + transfering money + deposits transfer amount to the other account + reduces its balance by the transfer amount + + 2 examples, 0 failures + +== INSTALL: + + [sudo] gem install rspec + + or + + clone, build, install - See http://wiki.github.com/dchelimsky/rspec \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Ruby1.9.rdoc b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Ruby1.9.rdoc new file mode 100644 index 00000000..7313d43c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Ruby1.9.rdoc @@ -0,0 +1,32 @@ += RSpec and Ruby 1.9 + +Currently, RSpec (core) is mostly compatible with Ruby 1.9.1. There are still +outstanding issues, some of which we plan to address and some we don't. + +== Test::Unit + +RSpec/Test::Unit interop will run with the test-unit-1.2.3 gem, but you must install it. + +== Class Variables + +Due to changes in scoping rules, class variables within example groups are not +supported in Ruby 1.9. + + describe "a class variable" do + @@class_variable = "a class variable" + + it "can access class variables in examples in Ruby 1.8" do + with_ruby 1.8 do + @@class_variable.should == "a class variable" + end + end + + it "can NOT access class variables in examples in Ruby 1.9" do + with_ruby 1.9 do + lambda do + @@class_variable.should == "a class variable" + end.should raise_error(NameError) + end + end + end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/TODO.txt b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/TODO.txt new file mode 100644 index 00000000..fc59a25b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/TODO.txt @@ -0,0 +1,17 @@ +== Refactoring + +** global predictate matchers should be stored in run_options +* eliminate dependency on global options and configuration +** the only place they should exist is in the Runner, which should manage them + +== Future + +* do SOMETHING with the website +* separate the underlying framework from the DSL + * be able to do everything with classes and methods +* tweak raise_error rdoc to show only one arg + +== rspec-2.0 + +* rename top level namespace to Rspec and commands to 'rspec' and 'autorspec' + * continue to support Spec 'spec' and 'autospec' as aliases for a reasonable time diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Upgrade.rdoc b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Upgrade.rdoc new file mode 100644 index 00000000..27d5c9c9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/Upgrade.rdoc @@ -0,0 +1,150 @@ += Upgrade to rspec-1.2.3-1.2.7 + +== What's Changed + +=== Matcher DSL + +Use Spec::Matchers.define instead of Spec::Matchers.create (which is now +deprecated). + +=== Explicit Predicate Matchers are deprecated + +With the addition of the new Matcher DSL the old, confusing, and +almost-nobody-uses-it explicit predicate matcher functionality's days are now +numbered. + +If you're not familiar with this feature, don't worry about it. If you have anything +that looks like this: + + predicate_matchers[:swim] = :can_swim? + +Or this + + config.predicate_matchers[:swim] = :can_swim? + +Change it to this: + + Spec::Matchers.define :swim do + match do |potential_swimmer| + potential_swimmer.can_swim? + end + end + +== Custom Formatters + +If you have an custom formatter, the add_example_group method has +been changed to example_group_started, and kept as an alias so your +formatters will still work. Though not yet, add_example_group will be +deprecated in a future minor release, and removed in a future major release, +so we recommend you make this change now. + += Upgrade to rspec-1.2.2 + +== What's Changed + +=== require 'rubygems' unless ENV['NO_RUBYGEMS'] + +After minor public outcry and confusion, we restored necessary references to +rubygems in rspec. If you use a different mechanism for managing gems, just +set a NO_RUBYGEMS environment variable (to any non-nil value). + +=== Proxies and locations + +This is probably only interesting to you if you use custom formatters. + +Formatters now receive Spec::Example::ExampleGroupProxy and +Spec::Example::ExampleGroup objects with cohesive APIs for reporting. See the +RDoc for those classes and Spec::Runner::Formatter::BaseFormatter for more +information. + +== What's new + +=== The new matcher DSL works with test/unit (without the rest of rspec) + +We'll be separating this out to its own gem for rspec 2.0, but for now, just install +rspec >= 1.2.1 and add the following to your test_helper file: + + require 'spec/expectations' + class Test::Unit::TestCase + include Spec::Matchers + end + +This will add should() and should_not() to your objects, make all of +rspec's built-in matchers available to your tests, INCLUDING rspec's DSL for +creating matchers (see below, under Upgrade to rspec-1.2.0) + +=== debugger + +If you have ruby-debug installed, you can set a breakpoint by adding debugger() +in your code: + + # some code ..... + debugger + # some more code .... + +... and using the --debugger or -u command line option. + + spec path/to/file.rb --debugger + += Upgrade to rspec-1.2.0 + +== What's Changed + +=== WARNINGS + +* If you use the ruby command to run specs instead of the spec command, you'll + need to require 'spec/autorun' or they won't run. This won't affect you if + you use the spec command or the Spec::Rake::SpecTask that ships with RSpec. + +* require 'spec/test/unit' to invoke test/unit interop if you're using + RSpec's core (this is handled implicitly with spec-rails) + +* setup and teardown are gone - use before and after instead + + * you can still use setup and teardown if you're using + Test::Unit::TestCase as the base ExampleGroup class (which is implicit + in rspec-rails) + +* The matcher protocol has been improved. The old protocol is still supported, + but we added support for two new methods that speak a bit more clearly: + + failure_message => failure_message_for_should + negative_failure_message => failure_message_for_should_not + +* All references to rubygems have been removed from within rspec's code. + + * See http://gist.github.com/54177 for rationale and suggestions on + alternative approaches to loading rubygems + +== What's New + +=== Ruby 1.9 + +RSpec now works with Ruby 1.9.1. See http://wiki.github.com/dchelimsky/rspec/ruby-191 +for useful information. + +=== Improved heckle integration + +RSpec works with heckle again! Gotta use heckle >= 1.4.2 for this to work +though, and it only works with ruby-1.8.6 and 1.8.7 (heckle doesn't support +1.9.1 yet). + + [sudo] gem install heckle --version ">=1.4.2" + spec spec/game/mastermind.rb --heckle Game::Mastermind + +=== New Matcher DSL + +We've added a new DSL for generating custom matchers very simply and cleanly. +We'll still support the simple_matcher method, so never fear if you're using +that, but we recommend that you start developing your new matchers with this +new syntax. + + Spec::Matchers.create :be_a_multiple_of do |smaller| + match do |bigger| + bigger % smaller == 0 + end + end + + 9.should be_a_multiple_of(3) + +See features/matchers/define_matcher.feature for more examples diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/README.txt b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/README.txt new file mode 100644 index 00000000..38c667d9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/README.txt @@ -0,0 +1,7 @@ +"Why have failing examples?", you might ask. + +They allow us to see failure messages. RSpec wants to provide meaningful and helpful failure messages. The failures in this directory not only provide you a way of seeing the failure messages, but they provide RSpec's own specs a way of describing what they should look like and ensuring they stay correct. + +To see the types of messages you can expect, stand in this directory and run: + +../bin/spec ./*.rb \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/diffing_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/diffing_spec.rb new file mode 100644 index 00000000..85e13e8c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/diffing_spec.rb @@ -0,0 +1,36 @@ +describe "Running specs with --diff" do + it "should print diff of different strings" do + uk = <<-EOF +RSpec is a +behaviour driven development +framework for Ruby +EOF + usa = <<-EOF +RSpec is a +behavior driven development +framework for Ruby +EOF + usa.should == uk + end + + class Animal + def initialize(name,species) + @name,@species = name,species + end + + def inspect + <<-EOA + + EOA + end + end + + it "should print diff of different objects' pretty representation" do + expected = Animal.new "bob", "giraffe" + actual = Animal.new "bob", "tortoise" + expected.should eql(actual) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failing_implicit_docstrings_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failing_implicit_docstrings_example.rb new file mode 100644 index 00000000..0795a21c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failing_implicit_docstrings_example.rb @@ -0,0 +1,19 @@ +require File.dirname(__FILE__) + '/spec_helper' + +# Run spec w/ -fs to see the output of this file + +describe "Failing examples with no descriptions" do + + # description is auto-generated as "should equal(5)" based on the last #should + it do + 3.should equal(2) + 5.should equal(5) + end + + it { 3.should be > 5 } + + it { ["a"].should include("b") } + + it { [1,2,3].should_not respond_to(:size) } + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failure_in_after.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failure_in_after.rb new file mode 100644 index 00000000..a47338ae --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failure_in_after.rb @@ -0,0 +1,10 @@ +describe "This example" do + + it "should be listed as failing in after" do + end + + after(:each) do + NonExistentClass.new + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failure_in_before.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failure_in_before.rb new file mode 100644 index 00000000..b0826604 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/failure_in_before.rb @@ -0,0 +1,10 @@ +describe "This example" do + + before(:each) do + NonExistentClass.new + end + + it "should be listed as failing in each" do + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_example.rb new file mode 100644 index 00000000..caf2db03 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_example.rb @@ -0,0 +1,40 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "Mocker" do + + it "should be able to call mock()" do + mock = mock("poke me") + mock.should_receive(:poke) + mock.poke + end + + it "should fail when expected message not received" do + mock = mock("poke me") + mock.should_receive(:poke) + end + + it "should fail when messages are received out of order" do + mock = mock("one two three") + mock.should_receive(:one).ordered + mock.should_receive(:two).ordered + mock.should_receive(:three).ordered + mock.one + mock.three + mock.two + end + + it "should get yelled at when sending unexpected messages" do + mock = mock("don't talk to me") + mock.should_not_receive(:any_message_at_all) + mock.any_message_at_all + end + + it "has a bug we need to fix" do + pending "here is the bug" do + # Actually, no. It's fixed. This will fail because it passes :-) + mock = mock("Bug") + mock.should_receive(:hello) + mock.hello + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_flexmock.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_flexmock.rb new file mode 100644 index 00000000..6e79ece0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_flexmock.rb @@ -0,0 +1,26 @@ +# stub frameworks like to gum up Object, so this is deliberately +# set NOT to run so that you don't accidentally run it when you +# run this dir. + +# To run it, stand in this directory and say: +# +# RUN_FLEXMOCK_EXAMPLE=true ruby ../bin/spec mocking_with_flexmock.rb + +if ENV['RUN_FLEXMOCK_EXAMPLE'] + Spec::Runner.configure do |config| + config.mock_with :flexmock + end + + describe "Flexmocks" do + it "should fail when the expected message is received with wrong arguments" do + m = flexmock("now flex!") + m.should_receive(:msg).with("arg").once + m.msg("other arg") + end + + it "should fail when the expected message is not received at all" do + m = flexmock("now flex!") + m.should_receive(:msg).with("arg").once + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_mocha.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_mocha.rb new file mode 100644 index 00000000..f14a1a3e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_mocha.rb @@ -0,0 +1,25 @@ +# stub frameworks like to gum up Object, so this is deliberately +# set NOT to run so that you don't accidentally run it when you +# run this dir. + +# To run it, stand in this directory and say: +# +# RUN_MOCHA_EXAMPLE=true ruby ../bin/spec mocking_with_mocha.rb + +if ENV['RUN_MOCHA_EXAMPLE'] + Spec::Runner.configure do |config| + config.mock_with :mocha + end + describe "Mocha framework" do + it "should should be made available by saying config.mock_with :mocha" do + m = mock() + m.expects(:msg).with("arg") + m.msg + end + it "should should be made available by saying config.mock_with :mocha" do + o = Object.new + o.expects(:msg).with("arg") + o.msg + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_rr.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_rr.rb new file mode 100644 index 00000000..0d2b4fe0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/mocking_with_rr.rb @@ -0,0 +1,27 @@ +# stub frameworks like to gum up Object, so this is deliberately +# set NOT to run so that you don't accidentally run it when you +# run this dir. + +# To run it, stand in this directory and say: +# +# RUN_RR_EXAMPLE=true ruby ../bin/spec mocking_with_rr.rb + +if ENV['RUN_RR_EXAMPLE'] + Spec::Runner.configure do |config| + config.mock_with :rr + end + describe "RR framework" do + it "should should be made available by saying config.mock_with :rr" do + o = Object.new + mock(o).msg("arg") + o.msg + end + it "should should be made available by saying config.mock_with :rr" do + o = Object.new + mock(o) do |m| + m.msg("arg") + end + o.msg + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/partial_mock_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/partial_mock_example.rb new file mode 100644 index 00000000..6d055405 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/partial_mock_example.rb @@ -0,0 +1,20 @@ +require File.dirname(__FILE__) + '/spec_helper' + +class MockableClass + def self.find id + return :original_return + end +end + +describe "A partial mock" do + + it "should work at the class level (but fail here due to the type mismatch)" do + MockableClass.should_receive(:find).with(1).and_return {:stub_return} + MockableClass.find("1").should equal(:stub_return) + end + + it "should revert to the original after each spec" do + MockableClass.find(1).should equal(:original_return) + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/pending_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/pending_example.rb new file mode 100644 index 00000000..c83a77cc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/pending_example.rb @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "pending example (which is fixed)" do + it %Q|reports "FIXED ... Expected ... to fail. No Error was raised."| do + pending("for some reason") do + # success + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/predicate_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/predicate_example.rb new file mode 100644 index 00000000..c412b450 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/predicate_example.rb @@ -0,0 +1,34 @@ +require File.dirname(__FILE__) + '/spec_helper' + +class BddFramework + def intuitive? + true + end + + def adopted_quickly? + #this will cause failures because it reallly SHOULD be adopted quickly + false + end +end + +describe "BDD framework" do + + before(:each) do + @bdd_framework = BddFramework.new + end + + it "should be adopted quickly" do + #this will fail because it reallly SHOULD be adopted quickly + @bdd_framework.should be_adopted_quickly + end + + it "should be intuitive" do + @bdd_framework.should be_intuitive + end + + it "should not respond to test" do + #this will fail + @bdd_framework.test + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/raising_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/raising_example.rb new file mode 100644 index 00000000..e40b51ec --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/raising_example.rb @@ -0,0 +1,47 @@ +describe "This example" do + + it "should show that a NoMethodError is raised but an Exception was expected" do + proc { ''.nonexistent_method }.should raise_error + end + + it "should pass" do + proc { ''.nonexistent_method }.should raise_error(NoMethodError) + end + + it "should show that a NoMethodError is raised but a SyntaxError was expected" do + proc { ''.nonexistent_method }.should raise_error(SyntaxError) + end + + it "should show that nothing is raised when SyntaxError was expected" do + proc { }.should raise_error(SyntaxError) + end + + it "should show that a NoMethodError is raised but a Exception was expected" do + proc { ''.nonexistent_method }.should_not raise_error + end + + it "should show that a NoMethodError is raised" do + proc { ''.nonexistent_method }.should_not raise_error(NoMethodError) + end + + it "should also pass" do + proc { ''.nonexistent_method }.should_not raise_error(SyntaxError) + end + + it "should show that a NoMethodError is raised when nothing expected" do + proc { ''.nonexistent_method }.should_not raise_error(Exception) + end + + it "should show that the wrong message was received" do + proc { raise StandardError.new("what is an enterprise?") }.should raise_error(StandardError, "not this") + end + + it "should show that the unexpected error/message was thrown" do + proc { raise StandardError.new("abc") }.should_not raise_error(StandardError, "abc") + end + + it "should pass too" do + proc { raise StandardError.new("abc") }.should_not raise_error(StandardError, "xyz") + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/spec_helper.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/spec_helper.rb new file mode 100644 index 00000000..a53755ef --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/spec_helper.rb @@ -0,0 +1,3 @@ +lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib") +$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path) +require 'spec/autorun' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/syntax_error_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/syntax_error_example.rb new file mode 100644 index 00000000..c9bb9077 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/syntax_error_example.rb @@ -0,0 +1,7 @@ +describe "when passing a block to a matcher" do + it "you should use {} instead of do/end" do + Object.new.should satisfy do + "this block is being passed to #should instead of #satisfy - use {} instead" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/team_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/team_spec.rb new file mode 100644 index 00000000..41a44e55 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/team_spec.rb @@ -0,0 +1,44 @@ +require File.dirname(__FILE__) + '/spec_helper' + + +class Team + attr_reader :players + def initialize + @players = Players.new + end +end + +class Players + def initialize + @players = [] + end + def size + @players.size + end + def include? player + raise "player must be a string" unless player.is_a?(String) + @players.include? player + end +end + +describe "A new team" do + + before(:each) do + @team = Team.new + end + + it "should have 3 players (failing example)" do + @team.should have(3).players + end + + it "should include some player (failing example)" do + @team.players.should include("Some Player") + end + + it "should include 5 (failing example)" do + @team.players.should include(5) + end + + it "should have no players" + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/timeout_behaviour.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/timeout_behaviour.rb new file mode 100644 index 00000000..18221365 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/failing/timeout_behaviour.rb @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "Something really slow" do + it "should be failed by RSpec when it takes longer than --timeout" do + sleep(2) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/custom_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/custom_formatter.rb new file mode 100644 index 00000000..b121f8b2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/custom_formatter.rb @@ -0,0 +1,12 @@ +require File.dirname(__FILE__) + '/spec_helper' +require 'spec/runner/formatter/progress_bar_formatter' + +# Example of a formatter with custom bactrace printing. Run me with: +# ruby bin/spec examples/failing -r examples/passing/custom_formatter.rb -f CustomFormatter +class CustomFormatter < Spec::Runner::Formatter::ProgressBarFormatter + def backtrace_line(line) + line.gsub(/([^:]*\.rb):(\d*)/) do + "#{$1}:#{$2} " + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/custom_matchers.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/custom_matchers.rb new file mode 100644 index 00000000..075bb542 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/custom_matchers.rb @@ -0,0 +1,54 @@ +module AnimalSpecHelper + class Eat + def initialize(food) + @food = food + end + + def matches?(animal) + @animal = animal + @animal.eats?(@food) + end + + def failure_message + "expected #{@animal} to eat #{@food}, but it does not" + end + + def negative_failure_message + "expected #{@animal} not to eat #{@food}, but it does" + end + end + + def eat(food) + Eat.new(food) + end +end + +module Animals + class Animal + def eats?(food) + return foods_i_eat.include?(food) + end + end + + class Mouse < Animal + def foods_i_eat + [:cheese] + end + end + + describe Mouse do + include AnimalSpecHelper + before(:each) do + @mouse = Animals::Mouse.new + end + + it "should eat cheese" do + @mouse.should eat(:cheese) + end + + it "should not eat cat" do + @mouse.should_not eat(:cat) + end + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/dynamic_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/dynamic_spec.rb new file mode 100644 index 00000000..1f9bc58a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/dynamic_spec.rb @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "The square root" do + (1..10).each do |n| + it "of #{n*n} should be #{n}" do + Math.sqrt(n*n).should == n + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/file_accessor.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/file_accessor.rb new file mode 100644 index 00000000..ff6fb743 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/file_accessor.rb @@ -0,0 +1,19 @@ +require File.dirname(__FILE__) + '/spec_helper' +class FileAccessor + def open_and_handle_with(pathname, processor) + pathname.open do |io| + processor.process(io) + end + end +end + +if __FILE__ == $0 + require File.dirname(__FILE__) + '/io_processor' + require 'pathname' + + accessor = FileAccessor.new + io_processor = IoProcessor.new + file = Pathname.new ARGV[0] + + accessor.open_and_handle_with(file, io_processor) +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/file_accessor_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/file_accessor_spec.rb new file mode 100644 index 00000000..628d4c0b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/file_accessor_spec.rb @@ -0,0 +1,38 @@ +require File.dirname(__FILE__) + '/spec_helper' +require File.dirname(__FILE__) + '/file_accessor' +require 'stringio' + +describe "A FileAccessor" do + # This sequence diagram illustrates what this spec specifies. + # + # +--------------+ +----------+ +-------------+ + # | FileAccessor | | Pathname | | IoProcessor | + # +--------------+ +----------+ +-------------+ + # | | | + # open_and_handle_with | | | + # -------------------->| | open | | + # | |--------------->| | | + # | | io | | | + # | |<...............| | | + # | | | process(io) | + # | |---------------------------------->| | + # | | | | | + # | |<..................................| | + # | | | + # + it "should open a file and pass it to the processor's process method" do + # This is the primary actor + accessor = FileAccessor.new + + # These are the primary actor's neighbours, which we mock. + file = mock "Pathname" + io_processor = mock "IoProcessor" + + io = StringIO.new "whatever" + file.should_receive(:open).and_yield io + io_processor.should_receive(:process).with(io) + + accessor.open_and_handle_with(file, io_processor) + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/filtered_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/filtered_formatter.rb new file mode 100644 index 00000000..14410795 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/filtered_formatter.rb @@ -0,0 +1,18 @@ +$:.unshift File.join(File.dirname(__FILE__), "/../../lib") +require 'spec/runner/formatter/nested_text_formatter' + +class FilteredFormatter < Spec::Runner::Formatter::NestedTextFormatter + def add_example_group(example_group) + if example_group.options[:show] == false + @showing = false + else + @showing = true + puts example_group.description + end + end + + def example_passed(example) + puts " " << example.description if @showing unless example.options[:show] == false + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/filtered_formatter_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/filtered_formatter_example.rb new file mode 100644 index 00000000..3c9d067f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/filtered_formatter_example.rb @@ -0,0 +1,31 @@ +# This demonstrates how you can write custom formatters to handle arbitrary +# options passed to the +describe+ and +it+ methods. To see it in action, stand +# in the project root and say: +# +# bin/spec -r examples/passing/filtered_formatter.rb examples/passing/filtered_formatter_example.rb -f FilteredFormatter +# +# You should only see the examples and groups below that are not explicitly +# marked :show => false +# +# group 1 +# example 1 a +# group 3 +# example 3 + + +describe "group 1", :show => true do + it "example 1 a", :show => true do + end + it "example 1 b", :show => false do + end +end + +describe "group 2", :show => false do + it "example 2" do + end +end + +describe "group 3" do + it "example 3" do + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/greeter_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/greeter_spec.rb new file mode 100644 index 00000000..ec7669dc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/greeter_spec.rb @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/spec_helper' +# greeter.rb +# +# Based on http://glu.ttono.us/articles/2006/12/19/tormenting-your-tests-with-heckle +# +# Run with: +# +# spec greeter_spec.rb --heckle Greeter +# +class Greeter + def initialize(person = nil) + @person = person + end + + def greet + @person.nil? ? "Hi there!" : "Hi #{@person}!" + end +end + +describe "Greeter" do + it "should say Hi to person" do + greeter = Greeter.new("Kevin") + greeter.greet.should == "Hi Kevin!" + end + + it "should say Hi to nobody" do + greeter = Greeter.new + # Uncomment the next line to make Heckle happy + #greeter.greet.should == "Hi there!" + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/helper_method_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/helper_method_example.rb new file mode 100644 index 00000000..d97f19e6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/helper_method_example.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/spec_helper' + +module HelperMethodExample + describe "an example group with helper a method" do + def helper_method + "received call" + end + + it "should make that method available to specs" do + helper_method.should == "received call" + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/implicit_docstrings_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/implicit_docstrings_example.rb new file mode 100644 index 00000000..376349ea --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/implicit_docstrings_example.rb @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/spec_helper' + +# Run "spec implicit_docstrings_example.rb --format specdoc" to see the output of this file + +describe "Examples with no docstrings generate their own:" do + + specify { 3.should be < 5 } + + specify { ["a"].should include("a") } + + specify { [1,2,3].should respond_to(:size) } + +end + +describe 1 do + it { should == 1 } + it { should be < 2} +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/io_processor.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/io_processor.rb new file mode 100644 index 00000000..6b15147b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/io_processor.rb @@ -0,0 +1,8 @@ +class DataTooShort < StandardError; end + +class IoProcessor + # Does some fancy stuff unless the length of +io+ is shorter than 32 + def process(io) + raise DataTooShort if io.read.length < 32 + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/io_processor_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/io_processor_spec.rb new file mode 100644 index 00000000..5cab7bf3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/io_processor_spec.rb @@ -0,0 +1,21 @@ +require File.dirname(__FILE__) + '/spec_helper' +require File.dirname(__FILE__) + '/io_processor' +require 'stringio' + +describe "An IoProcessor" do + before(:each) do + @processor = IoProcessor.new + end + + it "should raise nothing when the file is exactly 32 bytes" do + lambda { + @processor.process(StringIO.new("z"*32)) + }.should_not raise_error + end + + it "should raise an exception when the file length is less than 32 bytes" do + lambda { + @processor.process(StringIO.new("z"*31)) + }.should raise_error(DataTooShort) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/mocking_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/mocking_example.rb new file mode 100644 index 00000000..6adbef59 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/mocking_example.rb @@ -0,0 +1,27 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "A consumer of a mock" do + it "should be able to send messages to the mock" do + mock = mock("poke me") + mock.should_receive(:poke) + mock.poke + end +end + +describe "a mock" do + it "should be able to mock the same message twice w/ different args" do + mock = mock("mock") + mock.should_receive(:msg).with(:arg1).and_return(:val1) + mock.should_receive(:msg).with(:arg2).and_return(:val2) + mock.msg(:arg1).should eql(:val1) + mock.msg(:arg2).should eql(:val2) + end + + it "should be able to mock the same message twice w/ different args in reverse order" do + mock = mock("mock") + mock.should_receive(:msg).with(:arg1).and_return(:val1) + mock.should_receive(:msg).with(:arg2).and_return(:val2) + mock.msg(:arg2).should eql(:val2) + mock.msg(:arg1).should eql(:val1) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/multi_threaded_example_group_runner.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/multi_threaded_example_group_runner.rb new file mode 100644 index 00000000..d5458ddf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/multi_threaded_example_group_runner.rb @@ -0,0 +1,26 @@ +class MultiThreadedExampleGroupRunner < Spec::Runner::ExampleGroupRunner + def initialize(options, arg) + super(options) + # configure these + @thread_count = 4 + @thread_wait = 0 + end + + def run + @threads = [] + q = Queue.new + example_groups.each { |b| q << b} + success = true + @thread_count.times do + @threads << Thread.new(q) do |queue| + while not queue.empty? + example_group = queue.pop + success &= example_group.suite.run(nil) + end + end + sleep @thread_wait + end + @threads.each {|t| t.join} + success + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/nested_classes_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/nested_classes_example.rb new file mode 100644 index 00000000..abe43b0a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/nested_classes_example.rb @@ -0,0 +1,36 @@ +require File.dirname(__FILE__) + '/spec_helper' +require File.dirname(__FILE__) + '/stack' + +class StackExamples < Spec::ExampleGroup + describe(Stack) + before(:each) do + @stack = Stack.new + end +end + +class EmptyStackExamples < StackExamples + describe("when empty") + it "should be empty" do + @stack.should be_empty + end +end + +class AlmostFullStackExamples < StackExamples + describe("when almost full") + before(:each) do + (1..9).each {|n| @stack.push n} + end + it "should be full" do + @stack.should_not be_full + end +end + +class FullStackExamples < StackExamples + describe("when full") + before(:each) do + (1..10).each {|n| @stack.push n} + end + it "should be full" do + @stack.should be_full + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/options_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/options_example.rb new file mode 100644 index 00000000..645eb1fb --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/options_example.rb @@ -0,0 +1,31 @@ +# This demonstrates the use of the options hash to support custom reporting. +# To see the result, run this command from the project root: +# +# bin/spec --require examples/passing/options_formatter.rb examples/passing/options_example.rb \ +# --format OptionsFormatter + +require File.dirname(__FILE__) + '/spec_helper' + +describe "this group will be reported", :report => true do + it "this example will be reported", :report => true do + # no-op + end + + it "this example will not be reported", :report => false do + # no-op + end + + it "this example will also not be reported", :foo => 'bar' do + # no-op + end + + it "this example will also also not be reported" do + # no-op + end +end + +describe "this group will not be reported", :report => false do + it "though this example will", :report => true do + # no-op + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/options_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/options_formatter.rb new file mode 100644 index 00000000..b88bebbc --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/options_formatter.rb @@ -0,0 +1,20 @@ +# This is an example of how you can use a custom formatter to do custom +# reporting. This formatter will only report example groups and examples that +# have :report => true (or anything truthy) in the declaration. See +# options_example.rb in this directory. + +require 'spec/runner/formatter/base_text_formatter' + +class OptionsFormatter < Spec::Runner::Formatter::BaseTextFormatter + def example_started(proxy) + if proxy.options[:report] + puts proxy.description + end + end + + def example_group_started(proxy) + if proxy.options[:report] + puts proxy.description + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/partial_mock_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/partial_mock_example.rb new file mode 100644 index 00000000..2af608b2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/partial_mock_example.rb @@ -0,0 +1,29 @@ +require File.dirname(__FILE__) + '/spec_helper' + +class MockableClass + def self.find id + return :original_return + end +end + +describe "A partial mock" do + + it "should work at the class level" do + MockableClass.should_receive(:find).with(1).and_return {:stub_return} + MockableClass.find(1).should equal(:stub_return) + end + + it "should revert to the original after each spec" do + MockableClass.find(1).should equal(:original_return) + end + + it "can be mocked w/ ordering" do + MockableClass.should_receive(:msg_1).ordered + MockableClass.should_receive(:msg_2).ordered + MockableClass.should_receive(:msg_3).ordered + MockableClass.msg_1 + MockableClass.msg_2 + MockableClass.msg_3 + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/pending_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/pending_example.rb new file mode 100644 index 00000000..13f3d00c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/pending_example.rb @@ -0,0 +1,20 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "pending example (using pending method)" do + it %Q|should be reported as "PENDING: for some reason"| do + pending("for some reason") + end +end + +describe "pending example (with no block)" do + it %Q|should be reported as "PENDING: Not Yet Implemented"| +end + +describe "pending example (with block for pending)" do + it %Q|should have a failing block, passed to pending, reported as "PENDING: for some reason"| do + pending("for some reason") do + raise "some reason" + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/predicate_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/predicate_example.rb new file mode 100644 index 00000000..1202bb67 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/predicate_example.rb @@ -0,0 +1,27 @@ +require File.dirname(__FILE__) + '/spec_helper' + +class BddFramework + def intuitive? + true + end + + def adopted_quickly? + true + end +end + +describe "BDD framework" do + + before(:each) do + @bdd_framework = BddFramework.new + end + + it "should be adopted quickly" do + @bdd_framework.should be_adopted_quickly + end + + it "should be intuitive" do + @bdd_framework.should be_intuitive + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/shared_example_group_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/shared_example_group_example.rb new file mode 100644 index 00000000..42a385f9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/shared_example_group_example.rb @@ -0,0 +1,81 @@ +require File.dirname(__FILE__) + '/spec_helper' + +module SharedExampleGroupExample + class OneThing + def what_things_do + "stuff" + end + end + + class AnotherThing + def what_things_do + "stuff" + end + end + + class YetAnotherThing + def what_things_do + "stuff" + end + end + + # A SharedExampleGroup is an example group that doesn't get run. + # You can create one like this: + share_examples_for "most things" do + def helper_method + "helper method" + end + + it "should do what things do" do + @thing.what_things_do.should == "stuff" + end + end + + # A SharedExampleGroup is also a module. If you create one like this it gets + # assigned to the constant MostThings + share_as :MostThings do + def helper_method + "helper method" + end + + it "should do what things do" do + @thing.what_things_do.should == "stuff" + end + end + + describe OneThing do + # Now you can include the shared example group like this, which + # feels more like what you might say ... + it_should_behave_like "most things" + + before(:each) { @thing = OneThing.new } + + it "should have access to helper methods defined in the shared example group" do + helper_method.should == "helper method" + end + end + + describe AnotherThing do + # ... or you can include the example group like this, which + # feels more like the programming language we love. + it_should_behave_like MostThings + + before(:each) { @thing = AnotherThing.new } + + it "should have access to helper methods defined in the shared example group" do + helper_method.should == "helper method" + end + end + + describe YetAnotherThing do + # ... or you can include the example group like this, which + # feels more like the programming language we love. + include MostThings + + before(:each) { @thing = AnotherThing.new } + + it "should have access to helper methods defined in the shared example group" do + helper_method.should == "helper method" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/shared_stack_examples.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/shared_stack_examples.rb new file mode 100644 index 00000000..e14fd146 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/shared_stack_examples.rb @@ -0,0 +1,36 @@ +shared_examples_for "non-empty Stack" do + + it { @stack.should_not be_empty } + + it "should return the top item when sent #peek" do + @stack.peek.should == @last_item_added + end + + it "should NOT remove the top item when sent #peek" do + @stack.peek.should == @last_item_added + @stack.peek.should == @last_item_added + end + + it "should return the top item when sent #pop" do + @stack.pop.should == @last_item_added + end + + it "should remove the top item when sent #pop" do + @stack.pop.should == @last_item_added + unless @stack.empty? + @stack.pop.should_not == @last_item_added + end + end + +end + +shared_examples_for "non-full Stack" do + + it { @stack.should_not be_full } + + it "should add to the top when sent #push" do + @stack.push "newly added top item" + @stack.peek.should == "newly added top item" + end + +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/simple_matcher_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/simple_matcher_example.rb new file mode 100644 index 00000000..a4be7ea3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/simple_matcher_example.rb @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "arrays" do + def contain_same_elements_as(expected) + simple_matcher "array with same elements in any order as #{expected.inspect}" do |actual| + if actual.size == expected.size + a, e = actual.dup, expected.dup + until e.empty? do + if i = a.index(e.pop) then a.delete_at(i) end + end + a.empty? + else + false + end + end + end + + describe "can be matched by their contents disregarding order" do + subject { [1,2,2,3] } + it { should contain_same_elements_as([1,2,2,3]) } + it { should contain_same_elements_as([2,3,2,1]) } + it { should_not contain_same_elements_as([3,3,2,1]) } + end + + describe "fail the match with different contents" do + subject { [1,2,3] } + it { should_not contain_same_elements_as([2,3,4])} + it { should_not contain_same_elements_as([1,2,2,3])} + it { should_not contain_same_elements_as([1,2])} + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/spec_helper.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/spec_helper.rb new file mode 100644 index 00000000..580ad2f5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/spec_helper.rb @@ -0,0 +1,3 @@ +lib_path = File.expand_path("#{File.dirname(__FILE__)}/../../lib") +$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path) +require 'spec/autorun' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack.rb new file mode 100644 index 00000000..407173f7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack.rb @@ -0,0 +1,36 @@ +class StackUnderflowError < RuntimeError +end + +class StackOverflowError < RuntimeError +end + +class Stack + + def initialize + @items = [] + end + + def push object + raise StackOverflowError if @items.length == 10 + @items.push object + end + + def pop + raise StackUnderflowError if @items.empty? + @items.delete @items.last + end + + def peek + raise StackUnderflowError if @items.empty? + @items.last + end + + def empty? + @items.empty? + end + + def full? + @items.length == 10 + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack_spec.rb new file mode 100644 index 00000000..2de3177c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack_spec.rb @@ -0,0 +1,64 @@ +require File.dirname(__FILE__) + '/spec_helper' +require File.dirname(__FILE__) + "/stack" +require File.dirname(__FILE__) + '/shared_stack_examples' + +describe Stack, " (empty)" do + before(:each) do + @stack = Stack.new + end + + # This uses @stack (because the described class is Stack) auto-generates the + # description "should be empty" + it { should be_empty } + + it_should_behave_like "non-full Stack" + + it "should complain when sent #peek" do + lambda { @stack.peek }.should raise_error(StackUnderflowError) + end + + it "should complain when sent #pop" do + lambda { @stack.pop }.should raise_error(StackUnderflowError) + end +end + +describe Stack, " (with one item)" do + before(:each) do + @stack = Stack.new + @stack.push 3 + @last_item_added = 3 + end + + it_should_behave_like "non-empty Stack" + it_should_behave_like "non-full Stack" + +end + +describe Stack, " (with one item less than capacity)" do + before(:each) do + @stack = Stack.new + (1..9).each { |i| @stack.push i } + @last_item_added = 9 + end + + it_should_behave_like "non-empty Stack" + it_should_behave_like "non-full Stack" +end + +describe Stack, " (full)" do + before(:each) do + @stack = Stack.new + (1..10).each { |i| @stack.push i } + @last_item_added = 10 + end + + # NOTE that this one auto-generates the description "should be full" + it { @stack.should be_full } + + it_should_behave_like "non-empty Stack" + + it "should complain on #push" do + lambda { @stack.push Object.new }.should raise_error(StackOverflowError) + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack_spec_with_nested_example_groups.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack_spec_with_nested_example_groups.rb new file mode 100644 index 00000000..05f6ad46 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stack_spec_with_nested_example_groups.rb @@ -0,0 +1,67 @@ +require File.dirname(__FILE__) + '/spec_helper' +require File.dirname(__FILE__) + '/stack' +require File.dirname(__FILE__) + '/shared_stack_examples' + +describe Stack do + + before(:each) do + @stack = Stack.new + end + + describe "(empty)" do + + it { @stack.should be_empty } + + it_should_behave_like "non-full Stack" + + it "should complain when sent #peek" do + lambda { @stack.peek }.should raise_error(StackUnderflowError) + end + + it "should complain when sent #pop" do + lambda { @stack.pop }.should raise_error(StackUnderflowError) + end + + end + + describe "(with one item)" do + + before(:each) do + @stack.push 3 + @last_item_added = 3 + end + + it_should_behave_like "non-empty Stack" + it_should_behave_like "non-full Stack" + + end + + describe "(with one item less than capacity)" do + + before(:each) do + (1..9).each { |i| @stack.push i } + @last_item_added = 9 + end + + it_should_behave_like "non-empty Stack" + it_should_behave_like "non-full Stack" + end + + describe "(full)" do + + before(:each) do + (1..10).each { |i| @stack.push i } + @last_item_added = 10 + end + + it { @stack.should be_full } + + it_should_behave_like "non-empty Stack" + + it "should complain on #push" do + lambda { @stack.push Object.new }.should raise_error(StackOverflowError) + end + + end + +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stubbing_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stubbing_example.rb new file mode 100644 index 00000000..31354aec --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/stubbing_example.rb @@ -0,0 +1,69 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe "A consumer of a stub" do + it "should be able to stub methods on any Object" do + obj = Object.new + obj.stub!(:foobar).and_return {:return_value} + obj.foobar.should equal(:return_value) + end +end + +class StubbableClass + def self.find id + return :original_return + end +end + +describe "A stubbed method on a class" do + it "should return the stubbed value" do + StubbableClass.stub!(:find).and_return(:stub_return) + StubbableClass.find(1).should equal(:stub_return) + end + + it "should revert to the original method after each spec" do + StubbableClass.find(1).should equal(:original_return) + end + + it "can stub! and mock the same message" do + StubbableClass.stub!(:msg).and_return(:stub_value) + StubbableClass.should_receive(:msg).with(:arg).and_return(:mock_value) + + StubbableClass.msg.should equal(:stub_value) + StubbableClass.msg(:other_arg).should equal(:stub_value) + StubbableClass.msg(:arg).should equal(:mock_value) + StubbableClass.msg(:another_arg).should equal(:stub_value) + StubbableClass.msg(:yet_another_arg).should equal(:stub_value) + StubbableClass.msg.should equal(:stub_value) + end +end + +describe "A mock" do + it "can stub!" do + mock = mock("stubbing mock") + mock.stub!(:msg).and_return(:value) + (1..10).each {mock.msg.should equal(:value)} + end + + it "can stub! and mock" do + mock = mock("stubbing mock") + mock.stub!(:stub_message).and_return(:stub_value) + mock.should_receive(:mock_message).once.and_return(:mock_value) + (1..10).each {mock.stub_message.should equal(:stub_value)} + mock.mock_message.should equal(:mock_value) + (1..10).each {mock.stub_message.should equal(:stub_value)} + end + + it "can stub! and mock the same message" do + mock = mock("stubbing mock") + mock.stub!(:msg).and_return(:stub_value) + mock.should_receive(:msg).with(:arg).and_return(:mock_value) + mock.msg.should equal(:stub_value) + mock.msg(:other_arg).should equal(:stub_value) + mock.msg(:arg).should equal(:mock_value) + mock.msg(:another_arg).should equal(:stub_value) + mock.msg(:yet_another_arg).should equal(:stub_value) + mock.msg.should equal(:stub_value) + end +end + + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/yielding_example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/yielding_example.rb new file mode 100644 index 00000000..4f627183 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/passing/yielding_example.rb @@ -0,0 +1,33 @@ +require File.dirname(__FILE__) + '/spec_helper' + +class MessageAppender + + def initialize(appendage) + @appendage = appendage + end + + def append_to(message) + if_told_to_yield do + message << @appendage + end + end + +end + +describe "a message expectation yielding to a block" do + it "should yield if told to" do + appender = MessageAppender.new("appended to") + appender.should_receive(:if_told_to_yield).and_yield + message = "" + appender.append_to(message) + message.should == "appended to" + end + + it "should not yield if not told to" do + appender = MessageAppender.new("appended to") + appender.should_receive(:if_told_to_yield) + message = "" + appender.append_to(message) + message.should == "" + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/ruby1.9.compatibility/access_to_constants_spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/ruby1.9.compatibility/access_to_constants_spec.rb new file mode 100644 index 00000000..b34b8ba6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/examples/ruby1.9.compatibility/access_to_constants_spec.rb @@ -0,0 +1,85 @@ +# courtesy of Matthias Hennemeyer +# +# The following should pass against ruby 1.8 and 1.9. It currently only passes +# 1.8 (as of 1/2/2009) +# +# Once cucumber supports ruby 1.9, this should be moved to cucumber scenarios instead. +module Foo + module Bar + + module ModuleInEnclosingModule;end + class ClassInEnclosingModule;end + def method_in_enclosing_module;end + CONSTANT_IN_ENCLOSING_MODULE = 0 + + describe "Examples trying to access constants defined in an enclosing module" do + + it "can access Modules" do + ModuleInEnclosingModule + end + it "can access Classes" do + ClassInEnclosingModule.new + end + it "can access CONSTANTS" do + CONSTANT_IN_ENCLOSING_MODULE + end + it "can NOT access methods" do + lambda {method_in_enclosing_module}.should raise_error(/undefined/) + end + + describe "from a nested example group" do + + it "can access Modules" do + ModuleInEnclosingModule + end + it "can access Classes" do + ClassInEnclosingModule.new + end + it "can access CONSTANTS" do + CONSTANT_IN_ENCLOSING_MODULE + end + it "can NOT access methods" do + lambda {method_in_enclosing_module}.should raise_error(/undefined/) + end + + end + + end + + describe "Examples trying to access constants defined in the example group" do + + module ModuleDefinedInGroup;end + class ClassDefinedInGroup; end + def method_defined_in_group; end + CONSTANT_DEFINED_IN_GROUP = 0 + + it "can access Modules" do + ModuleDefinedInGroup + end + it "can access Classes" do + ClassDefinedInGroup.new + end + it "can access CONSTANTS" do + CONSTANT_DEFINED_IN_GROUP + end + it "can access methods" do + method_defined_in_group + end + + describe "that live inside a nested group" do + it "can access Modules" do + ModuleDefinedInGroup + end + it "can access Classes" do + ClassDefinedInGroup.new + end + it "can access CONSTANTS" do + CONSTANT_DEFINED_IN_GROUP + end + it "can access methods" do + method_defined_in_group + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/autotest/discover.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/autotest/discover.rb new file mode 100644 index 00000000..3ac51c13 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/autotest/discover.rb @@ -0,0 +1,3 @@ +Autotest.add_discovery do + "rspec" if File.directory?('spec') && ENV['RSPEC'] +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/autotest/rspec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/autotest/rspec.rb new file mode 100644 index 00000000..625e340b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/autotest/rspec.rb @@ -0,0 +1,47 @@ +require 'autotest' + +Autotest.add_hook :initialize do |at| + at.clear_mappings + # watch out: Ruby bug (1.8.6): + # %r(/) != /\// + at.add_mapping(%r%^spec/.*_spec.rb$%) { |filename, _| + filename + } + at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m| + ["spec/#{m[1]}_spec.rb"] + } + at.add_mapping(%r%^spec/(spec_helper|shared/.*)\.rb$%) { + at.files_matching %r%^spec/.*_spec\.rb$% + } +end + +class RspecCommandError < StandardError; end + +class Autotest::Rspec < Autotest + + def initialize + super + self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n\n?(.*?(\n\n\(.*?)?)\n\n/m + self.completed_re = /\n(?:\e\[\d*m)?\d* examples?/m + end + + def consolidate_failures(failed) + filters = new_hash_of_arrays + failed.each do |spec, trace| + if trace =~ /\n(\.\/)?(.*spec\.rb):[\d]+:/ + filters[$2] << spec + end + end + return filters + end + + def make_test_cmd(files_to_test) + return '' if files_to_test.empty? + spec_program = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')) + return "#{ruby} #{spec_program} --autospec #{files_to_test.keys.flatten.join(' ')} #{add_options_if_present}" + end + + def add_options_if_present # :nodoc: + File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : "" + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec.rb new file mode 100644 index 00000000..879c373e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec.rb @@ -0,0 +1,8 @@ +require 'spec/deprecation' +require 'spec/ruby' +require 'spec/matchers' +require 'spec/expectations' +require 'spec/example' +require 'spec/runner' +require 'spec/version' +require 'spec/dsl' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/flexmock.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/flexmock.rb new file mode 100644 index 00000000..18dd453d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/flexmock.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +# +# Created by Jim Weirich on 2007-04-10. +# Copyright (c) 2007. All rights reserved. + +require 'rubygems' unless ENV['NO_RUBYGEMS'] +require 'flexmock/rspec' + +module Spec + module Adapters + module MockFramework + include FlexMock::MockContainer + def setup_mocks_for_rspec + # No setup required + end + def verify_mocks_for_rspec + flexmock_verify + end + def teardown_mocks_for_rspec + flexmock_close + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/mocha.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/mocha.rb new file mode 100644 index 00000000..3fbac7e3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/mocha.rb @@ -0,0 +1,20 @@ +require 'rubygems' unless ENV['NO_RUBYGEMS'] +require 'mocha/standalone' +require 'mocha/object' + +module Spec + module Adapters + module MockFramework + include Mocha::Standalone + def setup_mocks_for_rspec + mocha_setup + end + def verify_mocks_for_rspec + mocha_verify + end + def teardown_mocks_for_rspec + mocha_teardown + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/rr.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/rr.rb new file mode 100644 index 00000000..758ddf61 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/rr.rb @@ -0,0 +1,22 @@ +require 'rubygems' unless ENV['NO_RUBYGEMS'] +require 'rr' + +patterns = ::Spec::Runner::QuietBacktraceTweaker::IGNORE_PATTERNS +patterns.push(RR::Errors::BACKTRACE_IDENTIFIER) + +module Spec + module Adapters + module MockFramework + include RR::Extensions::InstanceMethods + def setup_mocks_for_rspec + RR::Space.instance.reset + end + def verify_mocks_for_rspec + RR::Space.instance.verify_doubles + end + def teardown_mocks_for_rspec + RR::Space.instance.reset + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/rspec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/rspec.rb new file mode 100644 index 00000000..b159f8bf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/adapters/mock_frameworks/rspec.rb @@ -0,0 +1,21 @@ +require 'spec/mocks/framework' +require 'spec/mocks/extensions' + +module Spec + module Adapters + unless defined?(MockFramework) + module MockFramework + include Spec::Mocks::ExampleMethods + def setup_mocks_for_rspec + $rspec_mocks ||= Spec::Mocks::Space.new + end + def verify_mocks_for_rspec + $rspec_mocks.verify_all + end + def teardown_mocks_for_rspec + $rspec_mocks.reset_all + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/autorun.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/autorun.rb new file mode 100644 index 00000000..f29b8196 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/autorun.rb @@ -0,0 +1,3 @@ +require 'spec' + +Spec::Runner.autorun diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/deprecation.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/deprecation.rb new file mode 100644 index 00000000..ebab7894 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/deprecation.rb @@ -0,0 +1,40 @@ +module Spec + class << self + def deprecate(method, alternate_method=nil) + message = <<-NOTICE + +***************************************************************** +DEPRECATION WARNING: you are using deprecated behaviour that will +be removed from a future version of RSpec. + +#{caller(0)[2]} + +* #{method} is deprecated. +NOTICE + if alternate_method + message << <<-ADDITIONAL +* please use #{alternate_method} instead. +ADDITIONAL + end + + message << "*****************************************************************" + warn(message) + end + + def warn(message) + Kernel.warn(message) + end + + end + + class HashWithDeprecationNotice < Hash + def initialize(method, alternate_method=nil, &block) + @method, @alternate_method = method, alternate_method + end + def []=(k,v) + Spec.deprecate(@method, @alternate_method) + super + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/dsl.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/dsl.rb new file mode 100644 index 00000000..d93e90d8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/dsl.rb @@ -0,0 +1 @@ +require 'spec/dsl/main' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/dsl/main.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/dsl/main.rb new file mode 100644 index 00000000..3459275b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/dsl/main.rb @@ -0,0 +1,92 @@ +module Spec + module DSL + module Main + include Spec::Example::ArgsAndOptions + + # Creates and returns a class that includes the ExampleGroupMethods + # module. Which ExampleGroup type is created depends on the directory of the file + # calling this method. For example, Spec::Rails will use different + # classes for specs living in spec/models, + # spec/helpers, spec/views and + # spec/controllers. + # + # It is also possible to override autodiscovery of the example group + # type with an options Hash as the last argument: + # + # describe "name", :type => :something_special do ... + # + # The reason for using different example group classes is to have different + # matcher methods available from within the describe block. + # + # See Spec::Example::ExampleGroupFactory#register for details about how to + # register special implementations. + # + def describe(*args, &block) + raise Spec::Example::NoDescriptionError.new("example group", caller(0)[1]) if args.empty? + add_options(args, :scope => self) + set_location(args.options, caller(0)[1]) + Spec::Example::ExampleGroupFactory.create_example_group(*args, &block) + end + alias :context :describe + + # Creates an example group that can be shared by other example groups + # + # == Examples + # + # share_examples_for "All Editions" do + # it "all editions behaviour" ... + # end + # + # describe SmallEdition do + # it_should_behave_like "All Editions" + # + # it "should do small edition stuff" do + # ... + # end + # end + def share_examples_for(*args, &block) + add_options(args) + set_location(args.options, caller(0)[1]) + Spec::Example::ExampleGroupFactory.create_shared_example_group(*args, &block) + end + alias :shared_examples_for :share_examples_for + + # Creates a Shared Example Group and assigns it to a constant + # + # share_as :AllEditions do + # it "should do all editions stuff" ... + # end + # + # describe SmallEdition do + # it_should_behave_like AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + # + # And, for those of you who prefer to use something more like Ruby, you + # can just include the module directly + # + # describe SmallEdition do + # include AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + def share_as(name, &block) + begin + args = [name] + add_options(args) + set_location(args.options, caller(0)[1]) + Object.const_set(name, Spec::Example::ExampleGroupFactory.create_shared_example_group(*args, &block)) + rescue NameError => e + raise NameError.new(e.message + "\nThe first argument to share_as must be a legal name for a constant\n") + end + end + end + end +end + +include Spec::DSL::Main diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example.rb new file mode 100644 index 00000000..afbf4128 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example.rb @@ -0,0 +1,164 @@ +module Spec + # == Example Groups and Code Examples + # + # A Code Example is an executable example of how a bit of code is expected + # to behave. + # + # An Example Group is a group of code examples. + # + # RSpec exposes a DSL to describe groups of examples. + # + # describe Account do + # it "should have a balance of $0" do + # account = Account.new + # account.balance.should == Money.new(0, :dollars) + # end + # end + # + # == Before and After + # + # You can use the before() and after() methods to extract + # common code within an Example Group. Both methods take an optional scope + # argument so you can run the block before :each example or before :all + # examples + # + # describe "..." do + # before :all do + # ... + # end + # + # before :each do + # ... + # end + # + # it "should do something" do + # ... + # end + # + # it "should do something else" do + # ... + # end + # + # after :each do + # ... + # end + # + # after :all do + # ... + # end + # + # end + # + # The before :each block will run before each of the examples, once + # for each example. Likewise, the after :each block will run after + # each of the examples. + # + # It is also possible to specify a before :all and after + # :all block that will run only once for each example group, before the + # first before :each and after the last after + # :each respectively. The use of these is generally discouraged, + # because it introduces dependencies between the examples. Still, it might + # prove useful for very expensive operations if you know what you are doing. + # + # == Local helper methods + # + # You can include local helper methods by simply expressing them within an + # example group: + # + # describe "..." do + # + # it "..." do + # helper_method + # end + # + # def helper_method + # ... + # end + # + # end + # + # == Included helper methods + # + # You can include helper methods in multiple example groups by expressing + # them within a module, and then including that module in your example + # groups: + # + # module AccountExampleHelperMethods + # def helper_method + # ... + # end + # end + # + # describe "A new account" do + # include AccountExampleHelperMethods + # before do + # @account = Account.new + # end + # + # it "should have a balance of $0" do + # helper_method + # @account.balance.should eql(Money.new(0, :dollars)) + # end + # end + # + # == Shared Example Groups + # + # You can define a shared example group, that may be used on other groups + # + # share_examples_for "All Editions" do + # it "all editions behaviour" ... + # end + # + # describe SmallEdition do + # it_should_behave_like "All Editions" + # + # it "should do small edition stuff" do + # ... + # end + # end + # + # You can also assign the shared group to a module and include that + # + # share_as :AllEditions do + # it "should do all editions stuff" ... + # end + # + # describe SmallEdition do + # it_should_behave_like AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + # + # And, for those of you who prefer to use something more like Ruby, you can + # just include the module directly + # + # describe SmallEdition do + # include AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + module Example + end +end + +require 'timeout' +require 'spec/example/args_and_options' +require 'spec/example/predicate_matchers' +require 'spec/example/example_group_proxy' +require 'spec/example/example_proxy' +require 'spec/example/subject' +require 'spec/example/before_and_after_hooks' +require 'spec/example/pending' +require 'spec/example/module_reopening_fix' +require 'spec/example/example_group_hierarchy' +require 'spec/example/example_group_methods' +require 'spec/example/example_methods' +require 'spec/example/example_group' +require 'spec/example/shared_example_group' +require 'spec/example/example_group_factory' +require 'spec/example/errors' +require 'spec/example/example_matcher' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/args_and_options.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/args_and_options.rb new file mode 100644 index 00000000..b74fddd8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/args_and_options.rb @@ -0,0 +1,27 @@ +module Spec + module Example + module ArgsAndOptions + def args_and_options(*args) # :nodoc: + options = Hash === args.last ? args.pop : {} + return args, options + end + + def add_options(args, options={}) # :nodoc: + args << {} unless Hash === args.last + args.extend WithOptions + args.options.merge!(options) + args.options + end + + def set_location(options, location) # :nodoc: + options[:location] ||= location + end + + module WithOptions # :nodoc: + def options + last + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/before_and_after_hooks.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/before_and_after_hooks.rb new file mode 100644 index 00000000..9f5039d1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/before_and_after_hooks.rb @@ -0,0 +1,93 @@ +module Spec + module Example + module BeforeAndAfterHooks + class << self + def before_suite_parts # :nodoc: + @before_suite_parts ||= [] + end + + def after_suite_parts # :nodoc: + @after_suite_parts ||= [] + end + end + + # Registers a block to be executed before examples. scope can be + # :each (default), :all, or :suite. When + # :each, the block is executed before each example. When + # :all, the block is executed only once before any examples are + # run. + def append_before(scope = :each, &block) + before_parts(scope) << block + end + alias_method :before, :append_before + + # Registers a block to be executed before each example. + # This method prepends +block+ to existing before blocks. + # + # See append_before for scoping semantics. + def prepend_before(scope = :each, &block) + before_parts(scope).unshift(block) + end + + # Registers a block to be executed after each example. + # This method prepends +block+ to existing after blocks. + # + # See append_before for scoping semantics. + def prepend_after(scope = :each, &block) + after_parts(scope).unshift(block) + end + alias_method :after, :prepend_after + + # Registers a block to be executed after each example. + # This method appends +block+ to existing after blocks. + # + # See append_before for scoping semantics. + def append_after(scope = :each, &block) + after_parts(scope) << block + end + + def before_each_parts # :nodoc: + @before_each_parts ||= [] + end + + def after_each_parts # :nodoc: + @after_each_parts ||= [] + end + + def before_all_parts # :nodoc: + @before_all_parts ||= [] + end + + def after_all_parts # :nodoc: + @after_all_parts ||= [] + end + + def before_suite_parts # :nodoc: + BeforeAndAfterHooks.before_suite_parts + end + + def after_suite_parts # :nodoc: + BeforeAndAfterHooks.after_suite_parts + end + + private + + def before_parts(scope) + case scope + when :each; before_each_parts + when :all; before_all_parts + when :suite; before_suite_parts + end + end + + def after_parts(scope) + case scope + when :each; after_each_parts + when :all; after_all_parts + when :suite; after_suite_parts + end + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/errors.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/errors.rb new file mode 100644 index 00000000..157b669b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/errors.rb @@ -0,0 +1,25 @@ +module Spec + module Example + class ExamplePendingError < StandardError; end + + class NotYetImplementedError < ExamplePendingError + MESSAGE = "Not Yet Implemented" + def initialize + super(MESSAGE) + end + end + + class PendingExampleFixedError < StandardError; end + + class NoDescriptionError < ArgumentError + class << self + def message(kind, location) + "No description supplied for #{kind} declared on #{location}" + end + end + def initialize(kind, location) + super(self.class.message(kind, location)) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group.rb new file mode 100644 index 00000000..983be9a2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group.rb @@ -0,0 +1,10 @@ +module Spec + module Example + # Base class for customized example groups. Use this if you + # want to make a custom example group. + class ExampleGroup + extend Spec::Example::ExampleGroupMethods + include Spec::Example::ExampleMethods + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_factory.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_factory.rb new file mode 100644 index 00000000..1d662782 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_factory.rb @@ -0,0 +1,82 @@ +module Spec + module Example + + class ExampleGroupFactory + module ClassMethods + include Spec::Example::ArgsAndOptions + + def reset + @example_group_types = nil + default(ExampleGroup) + end + + def example_group_creation_listeners + @example_group_creation_listeners ||= [] + end + + def register_example_group(klass) + example_group_creation_listeners.each do |listener| + listener.register_example_group(klass) + end + end + + def create_shared_example_group(*args, &example_group_block) # :nodoc: + ::Spec::Example::SharedExampleGroup.register(*args, &example_group_block) + end + + def create_example_group(*args, &block) + raise ArgumentError if args.empty? || block.nil? + add_options(args) + superclass = determine_superclass(args.last) + superclass.describe(*args, &block) + end + + # Registers an example group class +klass+ with the symbol +type+. For + # example: + # + # Spec::Example::ExampleGroupFactory.register(:farm, FarmExampleGroup) + # + # With that you can append a hash with :type => :farm to the describe + # method and it will load an instance of FarmExampleGroup. + # + # describe Pig, :type => :farm do + # ... + # + # If you don't use the hash explicitly, describe will + # implicitly use an instance of FarmExampleGroup for any file loaded + # from the ./spec/farm directory. + def register(key, example_group_class) + @example_group_types[key.to_sym] = example_group_class + end + + # Sets the default ExampleGroup class + def default(example_group_class) + Spec.__send__ :remove_const, :ExampleGroup if Spec.const_defined?(:ExampleGroup) + Spec.const_set(:ExampleGroup, example_group_class) + old = @example_group_types + @example_group_types = Hash.new(example_group_class) + @example_group_types.merge!(old) if old + end + + def [](key) + @example_group_types[key] + end + + protected + + def determine_superclass(opts) + if type = opts[:type] + self[type] + elsif opts[:location] =~ /spec(\\|\/)(#{@example_group_types.keys.sort_by{|k| k.to_s.length}.reverse.join('|')})/ + self[$2 == '' ? nil : $2.to_sym] + else + self[nil] + end + end + + end + extend ClassMethods + self.reset + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_hierarchy.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_hierarchy.rb new file mode 100644 index 00000000..f2c9fb5c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_hierarchy.rb @@ -0,0 +1,53 @@ +module Spec + module Example + class ExampleGroupHierarchy < Array + def initialize(example_group_class) + push example_group_class + if example_group_class.respond_to?(:superclass) && example_group_class.superclass.respond_to?(:example_group_hierarchy) + unshift example_group_class.superclass.example_group_hierarchy + flatten! + end + end + + def run_before_all(example) + example.eval_each_fail_fast(before_all_parts) + end + + def run_before_each(example) + example.eval_each_fail_fast(before_each_parts) + end + + def run_after_each(example) + example.eval_each_fail_slow(after_each_parts) + end + + def run_after_all(example) + example.eval_each_fail_slow(after_all_parts) + end + + def before_all_parts + @before_all_parts ||= collect {|klass| klass.before_all_parts}.flatten + end + + def before_each_parts + @before_each_parts ||= collect {|klass| klass.before_each_parts}.flatten + end + + def after_each_parts + @after_each_parts ||= reverse.collect {|klass| klass.after_each_parts}.flatten + end + + def after_all_parts + @after_all_parts ||= reverse.collect {|klass| klass.after_all_parts}.flatten + end + + def nested_descriptions + @nested_descriptions ||= collect {|eg| nested_description_from(eg) == "" ? nil : nested_description_from(eg) }.compact + end + + def nested_description_from(example_group) + example_group.description_args.join + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_methods.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_methods.rb new file mode 100644 index 00000000..e73f3356 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_methods.rb @@ -0,0 +1,275 @@ +module Spec + module Example + + module ExampleGroupMethods + class << self + attr_accessor :matcher_class + + def build_description_from(*args) + text = args.inject("") do |description, arg| + description << " " unless (description == "" || arg.to_s =~ /^(\s|\.|#)/) + description << arg.to_s + end + text == "" ? nil : text + end + end + + include Spec::Example::BeforeAndAfterHooks + include Spec::Example::Subject::ExampleGroupMethods + include Spec::Example::PredicateMatchers + include Spec::Example::ArgsAndOptions + + attr_reader :location + + def options # :nodoc: + @options ||= {} + end + + def inherited(klass) # :nodoc: + super + ExampleGroupFactory.register_example_group(klass) + end + + # Makes the describe/it syntax available from a class. For example: + # + # class StackSpec < Spec::ExampleGroup + # describe Stack, "with no elements" + # + # before + # @stack = Stack.new + # end + # + # it "should raise on pop" do + # lambda{ @stack.pop }.should raise_error + # end + # end + # + def describe(*args, &example_group_block) + raise Spec::Example::NoDescriptionError.new("example group", caller(0)[1]) if args.empty? + if example_group_block + options = add_options(args) + set_location(options, caller(0)[1]) + if options[:shared] + ExampleGroupFactory.create_shared_example_group(*args, &example_group_block) + else + subclass(*args, &example_group_block) + end + else + set_description(*args) + end + end + alias :context :describe + + # Use this to pull in examples from shared example groups. + def it_should_behave_like(*shared_example_groups) + shared_example_groups.each do |group| + include_shared_example_group(group) + end + end + + # Creates an instance of the current example group class and adds it to + # a collection of examples of the current example group. + def example(description=nil, options={}, backtrace=nil, &implementation) + example_proxy = ExampleProxy.new(description, options, backtrace || caller(0)[1]) + example_proxies << example_proxy + example_implementations[example_proxy] = implementation || pending_implementation + example_proxy + end + + def pending_implementation + lambda { raise(Spec::Example::NotYetImplementedError) } + end + + alias_method :it, :example + alias_method :specify, :example + + # Use this to temporarily disable an example. + def xexample(description=nil, opts={}, &block) + Kernel.warn("Example disabled: #{description}") + end + + alias_method :xit, :xexample + alias_method :xspecify, :xexample + + def run(run_options) + examples = examples_to_run(run_options) + notify(run_options.reporter) unless examples.empty? + return true if examples.empty? + return dry_run(examples, run_options) if run_options.dry_run? + + define_methods_from_predicate_matchers + + success, before_all_instance_variables = run_before_all(run_options) + success, after_all_instance_variables = run_examples(success, before_all_instance_variables, examples, run_options) + success = run_after_all(success, after_all_instance_variables, run_options) + end + + def set_description(*args) + @description_args, @options = args_and_options(*args) + @backtrace = caller(1) + @location = File.expand_path(options[:location]) if options[:location] + self + end + + def notify(reporter) # :nodoc: + reporter.example_group_started(ExampleGroupProxy.new(self)) + end + + def description + @description ||= ExampleGroupMethods.build_description_from(*description_parts) || to_s + end + + def described_type + @described_type ||= description_parts.reverse.find {|part| part.is_a?(Module)} + end + + def described_class + @described_class ||= Class === described_type ? described_type : nil + end + + def description_args + @description_args ||= [] + end + + def description_parts #:nodoc: + @description_parts ||= example_group_hierarchy.inject([]) do |parts, example_group_class| + [parts << example_group_class.description_args].flatten + end + end + + def example_proxies # :nodoc: + @example_proxies ||= [] + end + + def example_implementations # :nodoc: + @example_implementations ||= {} + end + + def examples(run_options=nil) #:nodoc: + (run_options && run_options.reverse) ? example_proxies.reverse : example_proxies + end + + def number_of_examples #:nodoc: + example_proxies.length + end + + def example_group_hierarchy + @example_group_hierarchy ||= ExampleGroupHierarchy.new(self) + end + + def nested_descriptions + example_group_hierarchy.nested_descriptions + end + + def include_constants_in(mod) + include mod if (Spec::Ruby.version.to_f >= 1.9) & (Module === mod) & !(Class === mod) + end + + private + + def subclass(*args, &example_group_block) + @class_count ||= 0 + @class_count += 1 + klass = const_set("Subclass_#{@class_count}", Class.new(self)) + klass.set_description(*args) + klass.include_constants_in(args.last[:scope]) + klass.module_eval(&example_group_block) + klass + end + + def dry_run(examples, run_options) + examples.each do |example| + run_options.reporter.example_started(example) + run_options.reporter.example_finished(example) + end + end + + def run_before_all(run_options) + return [true,{}] if example_group_hierarchy.before_all_parts.empty? + example_proxy = ExampleProxy.new("before(:all)") + before_all = new(example_proxy) + begin + example_group_hierarchy.run_before_all(before_all) + return [true, before_all.instance_variable_hash] + rescue Exception => e + run_options.reporter.example_failed(example_proxy, e) + return [false, before_all.instance_variable_hash] + end + end + + def run_examples(success, instance_variables, examples, run_options) + return [success, instance_variables] unless success + + after_all_instance_variables = instance_variables + + examples.each do |example| + example_group_instance = new(example, &example_implementations[example]) + success &= example_group_instance.execute(run_options, instance_variables) + after_all_instance_variables = example_group_instance.instance_variable_hash + end + + return [success, after_all_instance_variables] + end + + def run_after_all(success, instance_variables, run_options) + return success if example_group_hierarchy.after_all_parts.empty? + example_proxy = ExampleProxy.new("after(:all)") + after_all = new(example_proxy) + after_all.set_instance_variables_from_hash(instance_variables) + example_group_hierarchy.run_after_all(after_all) + success + rescue Exception => e + run_options.reporter.example_failed(example_proxy, e) + false + end + + def examples_to_run(run_options) + return example_proxies unless examples_were_specified?(run_options) + if run_options.line_number_requested? + if location =~ /:#{run_options.example_line}$/ + example_proxies + else + example_proxies.select {|proxy| proxy.location =~ /:#{run_options.example_line}$/} + end + else + example_proxies.reject do |proxy| + matcher = ExampleGroupMethods.matcher_class. + new(description.to_s, proxy.description) + !matcher.matches?(run_options.examples) + end + end + end + + def examples_were_specified?(run_options) + !run_options.examples.empty? + end + + def method_added(name) # :nodoc: + example(name.to_s, {}, caller(0)[1]) {__send__ name.to_s} if example_method?(name.to_s) + end + + def example_method?(method_name) + should_method?(method_name) + end + + def should_method?(method_name) + !(method_name =~ /^should(_not)?$/) && + method_name =~ /^should/ && + instance_method(method_name).arity < 1 + end + + def include_shared_example_group(shared_example_group) + case shared_example_group + when SharedExampleGroup + include shared_example_group + else + unless example_group = SharedExampleGroup.find(shared_example_group) + raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found") + end + include(example_group) + end + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_proxy.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_proxy.rb new file mode 100644 index 00000000..3c258d61 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_group_proxy.rb @@ -0,0 +1,61 @@ +module Spec + module Example + # Lightweight proxy for an example group. This is the object that is passed + # to Spec::Runner::Formatter::BaseFormatter#example_group_started + class ExampleGroupProxy + + def initialize(example_group) # :nodoc: + @description = example_group.description + @nested_descriptions = example_group.nested_descriptions + @examples = example_group.example_proxies + @location = example_group.location + @backtrace = example_group.location # deprecated - see the backtrace method below + @options = example_group.options.dup + @options.delete(:location) + @options.delete(:scope) + end + + # Optional hash passed to the example group declaration. Note that RSpec uses + # this hash internally and reserves the keys :location and :scope for its own + # use (and removes them from this hash) + attr_reader :options + + # This is the description passed to the describe() method or any + # of its aliases + attr_reader :description + + # Used by Spec::Runner::Formatter::NestedTextFormatter to access the + # description of each example group in a nested group separately. + attr_reader :nested_descriptions + + # A collection of ExampleGroupProxy objects, one for each example + # declared in this group. + attr_reader :examples + + # The file and line number at which the proxied example group + # was declared. This is extracted from caller, and is therefore + # formatted as an individual line in a backtrace. + attr_reader :location + + # Deprecated - use location() instead + def backtrace + Spec::deprecate("ExampleGroupProxy#backtrace","ExampleGroupProxy#location") + @backtrace + end + + # Deprecated - just use gsub on the description instead. + def filtered_description(regexp) + Spec::deprecate("ExampleGroupProxy#filtered_description","gsub (or similar) to modify ExampleGroupProxy#description") + ExampleGroupMethods.build_description_from( + *nested_descriptions.collect do |description| + description =~ regexp ? description.gsub($1, "") : description + end + ) + end + + def ==(other) # :nodoc: + other.description == description + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_matcher.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_matcher.rb new file mode 100644 index 00000000..3acd7e14 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_matcher.rb @@ -0,0 +1,43 @@ +module Spec + module Example + class ExampleMatcher + def initialize(example_group_description, example_name) + @example_group_description = example_group_description + @example_name = example_name + end + + def matches?(specified_examples) + specified_examples.any? do |specified_example| + matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example) + end + end + + protected + def matches_literal_example?(specified_example) + specified_example =~ /(^#{example_group_regex} #{example_regexp}$|^#{example_group_regex}$|^#{example_group_with_before_all_regexp}$|^#{example_regexp}$)/ + end + + def matches_example_not_considering_modules?(specified_example) + specified_example =~ /(^#{example_group_regex_not_considering_modules} #{example_regexp}$|^#{example_group_regex_not_considering_modules}$|^#{example_regexp}$)/ + end + + def example_group_regex + Regexp.escape(@example_group_description) + end + + def example_group_with_before_all_regexp + Regexp.escape("#{@example_group_description} before(:all)") + end + + def example_group_regex_not_considering_modules + Regexp.escape(@example_group_description.split('::').last) + end + + def example_regexp + Regexp.escape(@example_name) if @example_name + end + end + + ExampleGroupMethods.matcher_class = ExampleMatcher + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_methods.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_methods.rb new file mode 100644 index 00000000..c82141a8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_methods.rb @@ -0,0 +1,148 @@ +module Spec + module Example + module ExampleMethods + + extend Spec::Example::ModuleReopeningFix + include Spec::Example::Subject::ExampleMethods + + def violated(message="") + raise Spec::Expectations::ExpectationNotMetError.new(message) + end + + # Declared description for this example: + # + # describe Account do + # it "should start with a balance of 0" do + # ... + # + # description + # => "should start with a balance of 0" + def description + if description = @_proxy.description || ::Spec::Matchers.generated_description + description + else + Spec.warn Spec::Example::NoDescriptionError.message("example", @_proxy.location) + end + end + + def options # :nodoc: + @_proxy.options + end + + def execute(run_options, instance_variables) # :nodoc: + run_options.reporter.example_started(@_proxy) + set_instance_variables_from_hash(instance_variables) + + execution_error = nil + Timeout.timeout(run_options.timeout) do + begin + before_each_example + instance_eval(&@_implementation) + rescue Exception => e + execution_error ||= e + end + begin + after_each_example + rescue Exception => e + execution_error ||= e + end + end + + run_options.reporter.example_finished(@_proxy.update(description), execution_error) + success = execution_error.nil? || ExamplePendingError === execution_error + end + + module BlockAliases + alias_method :to, :should + alias_method :to_not, :should_not + end + + # Extends the submitted block with aliases to and to_not + # for should and should_not. Allows expectations like this: + # + # expect { this_block }.to change{this.expression}.from(old_value).to(new_value) + # expect { this_block }.to raise_error + def expect(&block) + block.extend BlockAliases + end + + def eval_each_fail_fast(blocks) # :nodoc: + blocks.each {|block| instance_eval(&block)} + end + + def eval_each_fail_slow(blocks) # :nodoc: + first_exception = nil + blocks.each do |block| + begin + instance_eval(&block) + rescue Exception => e + first_exception ||= e + end + end + raise first_exception if first_exception + end + + def instance_variable_hash # :nodoc: + instance_variables.inject({}) do |variable_hash, variable_name| + variable_hash[variable_name] = instance_variable_get(variable_name) + variable_hash + end + end + + def set_instance_variables_from_hash(ivars) # :nodoc: + ivars.each do |variable_name, value| + # Ruby 1.9 requires variable.to_s on the next line + unless ['@_proxy', '@_implementation', '@method_name'].include?(variable_name.to_s) + instance_variable_set variable_name, value + end + end + end + + # Run all the before(:each) blocks for this example + def run_before_each + example_group_hierarchy.run_before_each(self) + end + + # Run all the after(:each) blocks for this example + def run_after_each + example_group_hierarchy.run_after_each(self) + end + + def initialize(example_proxy, &implementation) + @_proxy = example_proxy + @_implementation = implementation + @_backtrace = caller + end + + private + + include Matchers + include Pending + + def before_each_example + setup_mocks_for_rspec + run_before_each + end + + def after_each_example + run_after_each + verify_mocks_for_rspec + ensure + teardown_mocks_for_rspec + end + + def described_class + self.class.described_class + end + + def description_args + self.class.description_args + end + + def example_group_hierarchy + self.class.example_group_hierarchy + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_proxy.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_proxy.rb new file mode 100644 index 00000000..f726d0e7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/example_proxy.rb @@ -0,0 +1,41 @@ +module Spec + module Example + # Lightweight proxy for an example. This is the object that is passed to + # example-related methods in Spec::Runner::Formatter::BaseFormatter + class ExampleProxy + + def initialize(description=nil, options={}, location=nil) # :nodoc: + @description, @options, @location = description, options, location + end + + # Optional hash passed to the example declaration + attr_reader :options + + # This is the docstring passed to the it() method or any + # of its aliases + attr_reader :description + + # The file and line number at which the represented example + # was declared. This is extracted from caller, and is therefore + # formatted as an individual line in a backtrace. + attr_reader :location + + # Deprecated - use location() + def backtrace + Spec.deprecate("ExampleProxy#backtrace","ExampleProxy#location") + location + end + + # Convenience method for example group - updates the value of + # description and returns self. + def update(description) # :nodoc: + @description = description + self + end + + def ==(other) # :nodoc: + (other.description == description) & (other.location == location) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/module_reopening_fix.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/module_reopening_fix.rb new file mode 100644 index 00000000..9ea088a2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/module_reopening_fix.rb @@ -0,0 +1,43 @@ +module Spec + module Example + # When you reopen a module that is included in another module that is included in a class, + # the new material you define does not make it to the class. This fixes that. + # + # == Example + # + # module M1; end + # + # module M2 + # def foo; "FOO"; end + # end + # + # class C + # include M1 + # end + # + # module M1 + # include M2 + # end + # + # c = C.new + # c.foo + # NoMethodError: undefined method `foo' for # + # from (irb):12 + module ModuleReopeningFix + def child_modules + @child_modules ||= [] + end + + def included(mod) + child_modules << mod + end + + def include(mod) + super + child_modules.each do |child_module| + child_module.__send__(:include, mod) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/pending.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/pending.rb new file mode 100644 index 00000000..9aad1aab --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/pending.rb @@ -0,0 +1,18 @@ +module Spec + module Example + module Pending + def pending(message = "TODO") + if block_given? + begin + yield + rescue Exception + raise Spec::Example::ExamplePendingError.new(message) + end + raise Spec::Example::PendingExampleFixedError.new("Expected pending '#{message}' to fail. No Error was raised.") + else + raise Spec::Example::ExamplePendingError.new(message) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/predicate_matchers.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/predicate_matchers.rb new file mode 100644 index 00000000..c3c31951 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/predicate_matchers.rb @@ -0,0 +1,46 @@ +module Spec + module Example + module PredicateMatchers + # :call-seq: + # predicate_matchers[matcher_name] = method_on_object + # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object] + # + # Dynamically generates a custom matcher that will match + # a predicate on your class. RSpec provides a couple of these + # out of the box: + # + # exist (for state expectations) + # File.should exist("path/to/file") + # + # an_instance_of (for mock argument matchers) + # mock.should_receive(:message).with(an_instance_of(String)) + # + # == Examples + # + # class Fish + # def can_swim? + # true + # end + # end + # + # describe Fish do + # predicate_matchers[:swim] = :can_swim? + # it "should swim" do + # Fish.new.should swim + # end + # end + def predicate_matchers + @predicate_matchers ||= Spec::HashWithDeprecationNotice.new("predicate_matchers", "the new Matcher DSL") + end + + def define_methods_from_predicate_matchers # :nodoc: + predicate_matchers.each_pair do |matcher_method, method_on_object| + define_method matcher_method do |*args| + eval("be_#{method_on_object.to_s.gsub('?','')}(*args)") + end + end + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/shared_example_group.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/shared_example_group.rb new file mode 100644 index 00000000..33694491 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/shared_example_group.rb @@ -0,0 +1,59 @@ +module Spec + module Example + class SharedExampleGroup < Module + module ClassMethods + def register(*args, &block) + new_example_group = new(*args, &block) + shared_example_groups << new_example_group unless already_registered?(new_example_group) + new_example_group + end + + def find(example_group_description) + shared_example_groups.find {|b| b.description == example_group_description} + end + + def clear + shared_example_groups.clear + end + + def include?(group) + shared_example_groups.include?(group) + end + + def count + shared_example_groups.length + end + + private + + def shared_example_groups + @shared_example_groups ||= [] + end + + def already_registered?(new_example_group) + existing_example_group = find(new_example_group.description) + return false unless existing_example_group + return true if new_example_group.equal?(existing_example_group) + return true if expanded_path(new_example_group) == expanded_path(existing_example_group) + raise ArgumentError.new("Shared Example '#{existing_example_group.description}' already exists") + end + + def expanded_path(example_group) + File.expand_path(example_group.location) + end + end + + extend ClassMethods + include ExampleGroupMethods + + def initialize(*args, &example_group_block) + set_description(*args) + @example_group_block = example_group_block + end + + def included(mod) # :nodoc: + mod.module_eval(&@example_group_block) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/subject.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/subject.rb new file mode 100644 index 00000000..d67e84cd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/example/subject.rb @@ -0,0 +1,100 @@ +module Spec + module Example + module Subject + module ExampleGroupMethods + # Defines an explicit subject for an example group which can then be the + # implicit receiver (through delegation) of calls to +should+. + # + # == Examples + # + # describe CheckingAccount, "with $50" do + # subject { CheckingAccount.new(:amount => 50, :currency => :USD) } + # it { should have_a_balance_of(50, :USD) } + # it { should_not be_overdrawn } + # end + # + # See +ExampleMethods#should+ for more information about this approach. + def subject(&block) + block.nil? ? + explicit_subject || implicit_subject : @explicit_subject_block = block + end + + attr_reader :explicit_subject_block # :nodoc: + + private + + def explicit_subject + group = self + while group.respond_to?(:explicit_subject_block) + return group.explicit_subject_block if group.explicit_subject_block + group = group.superclass + end + end + + def implicit_subject + (described_class ? lambda {described_class.new} : lambda {description_args.first}) + end + end + + module ExampleMethods + + alias_method :__should_for_example_group__, :should + alias_method :__should_not_for_example_group__, :should_not + + # Returns the subject defined in ExampleGroupMethods#subject. The + # subject block is only executed once per example, the result of which + # is cached and returned by any subsequent calls to +subject+. + # + # If a class is passed to +describe+ and no subject is explicitly + # declared in the example group, then +subject+ will return a new + # instance of that class. + # + # == Examples + # + # # explicit subject defined by the subject method + # describe Person do + # subject { Person.new(:birthdate => 19.years.ago) } + # it "should be eligible to vote" do + # subject.should be_eligible_to_vote + # end + # end + # + # # implicit subject => { Person.new } + # describe Person do + # it "should be eligible to vote" do + # subject.should be_eligible_to_vote + # end + # end + def subject + @subject ||= instance_eval(&self.class.subject) + end + + # When +should+ is called with no explicit receiver, the call is + # delegated to the object returned by +subject+. Combined with + # an implicit subject (see +subject+), this supports very concise + # expressions. + # + # == Examples + # + # describe Person do + # it { should be_eligible_to_vote } + # end + def should(matcher=nil) + self == subject ? self.__should_for_example_group__(matcher) : subject.should(matcher) + end + + # Just like +should+, +should_not+ delegates to the subject (implicit or + # explicit) of the example group. + # + # == Examples + # + # describe Person do + # it { should_not be_eligible_to_vote } + # end + def should_not(matcher=nil) + self == subject ? self.__should_not_for_example_group__(matcher) : subject.should_not(matcher) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations.rb new file mode 100644 index 00000000..13cf59b2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations.rb @@ -0,0 +1,35 @@ +require 'spec/matchers' +require 'spec/expectations/fail_with' +require 'spec/expectations/errors' +require 'spec/expectations/extensions' +require 'spec/expectations/handler' + +module Spec + + # Spec::Expectations lets you set expectations on your objects. + # + # result.should == 37 + # team.should have(11).players_on_the_field + # + # == How Expectations work. + # + # Spec::Expectations adds two methods to Object: + # + # should(matcher=nil) + # should_not(matcher=nil) + # + # Both methods take an optional Expression Matcher (See Spec::Matchers). + # + # When +should+ receives an Expression Matcher, it calls matches?(self). If + # it returns +true+, the spec passes and execution continues. If it returns + # +false+, then the spec fails with the message returned by matcher.failure_message. + # + # Similarly, when +should_not+ receives a matcher, it calls matches?(self). If + # it returns +false+, the spec passes and execution continues. If it returns + # +true+, then the spec fails with the message returned by matcher.negative_failure_message. + # + # RSpec ships with a standard set of useful matchers, and writing your own + # matchers is quite simple. See Spec::Matchers for details. + module Expectations + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/errors.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/errors.rb new file mode 100644 index 00000000..1fabd105 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/errors.rb @@ -0,0 +1,12 @@ +module Spec + module Expectations + # If Test::Unit is loaed, we'll use its error as baseclass, so that Test::Unit + # will report unmet RSpec expectations as failures rather than errors. + superclass = ['Test::Unit::AssertionFailedError', '::StandardError'].map do |c| + eval(c) rescue nil + end.compact.first + + class ExpectationNotMetError < superclass + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/extensions.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/extensions.rb new file mode 100644 index 00000000..d68212e4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/extensions.rb @@ -0,0 +1 @@ +require 'spec/expectations/extensions/kernel' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/extensions/kernel.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/extensions/kernel.rb new file mode 100644 index 00000000..94d99ede --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/extensions/kernel.rb @@ -0,0 +1,52 @@ +module Kernel + # :call-seq: + # should(matcher) + # should == expected + # should === expected + # should =~ expected + # + # receiver.should(matcher) + # => Passes if matcher.matches?(receiver) + # + # receiver.should == expected #any value + # => Passes if (receiver == expected) + # + # receiver.should === expected #any value + # => Passes if (receiver === expected) + # + # receiver.should =~ regexp + # => Passes if (receiver =~ regexp) + # + # See Spec::Matchers for more information about matchers + # + # == Warning + # + # NOTE that this does NOT support receiver.should != expected. + # Instead, use receiver.should_not == expected + def should(matcher=nil, &block) + Spec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, &block) + end + + # :call-seq: + # should_not(matcher) + # should_not == expected + # should_not === expected + # should_not =~ expected + # + # receiver.should_not(matcher) + # => Passes unless matcher.matches?(receiver) + # + # receiver.should_not == expected + # => Passes unless (receiver == expected) + # + # receiver.should_not === expected + # => Passes unless (receiver === expected) + # + # receiver.should_not =~ regexp + # => Passes unless (receiver =~ regexp) + # + # See Spec::Matchers for more information about matchers + def should_not(matcher=nil, &block) + Spec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, &block) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/fail_with.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/fail_with.rb new file mode 100644 index 00000000..66649ccd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/fail_with.rb @@ -0,0 +1,43 @@ +module Spec + module Expectations + class << self + attr_accessor :differ + + # raises a Spec::Expectations::ExpectationNotMetError with message + # + # When a differ has been assigned and fail_with is passed + # expected and target, passes them + # to the differ to append a diff message to the failure message. + def fail_with(message, expected=nil, target=nil) # :nodoc: + if message.nil? + raise ArgumentError, "Failure message is nil. Does your matcher define the " + + "appropriate failure_message_for_* method to return a string?" + end + if (Array === message) & (message.length == 3) + ::Spec.warn(<<-NOTICE + +***************************************************************** +DEPRECATION WARNING: you are using deprecated behaviour that will +be removed from a future version of RSpec. + +* Support for matchers that return arrays from failure message +methods is deprecated. +* Instead, the matcher should return a string, and expose methods +for the expected() and actual() values. +***************************************************************** +NOTICE + ) + message, expected, target = message[0], message[1], message[2] + end + unless (differ.nil? || expected.nil? || target.nil?) + if expected.is_a?(String) + message << "\nDiff:" << self.differ.diff_as_string(target.to_s, expected) + elsif !target.is_a?(Proc) + message << "\nDiff:" << self.differ.diff_as_object(target, expected) + end + end + Kernel::raise(Spec::Expectations::ExpectationNotMetError.new(message)) + end + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/handler.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/handler.rb new file mode 100644 index 00000000..ed0c9ed0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/expectations/handler.rb @@ -0,0 +1,50 @@ +module Spec + module Expectations + class InvalidMatcherError < ArgumentError; end + + class PositiveExpectationHandler + def self.handle_matcher(actual, matcher, &block) + ::Spec::Matchers.last_should = :should + ::Spec::Matchers.last_matcher = matcher + return ::Spec::Matchers::PositiveOperatorMatcher.new(actual) if matcher.nil? + + match = matcher.matches?(actual, &block) + return match if match + + message = matcher.respond_to?(:failure_message_for_should) ? + matcher.failure_message_for_should : + matcher.failure_message + + if matcher.respond_to?(:diffable?) && matcher.diffable? + ::Spec::Expectations.fail_with message, matcher.expected.first, matcher.actual + else + ::Spec::Expectations.fail_with message + end + end + end + + class NegativeExpectationHandler + def self.handle_matcher(actual, matcher, &block) + ::Spec::Matchers.last_should = :should_not + ::Spec::Matchers.last_matcher = matcher + return ::Spec::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil? + + match = matcher.respond_to?(:does_not_match?) ? + !matcher.does_not_match?(actual, &block) : + matcher.matches?(actual, &block) + return match unless match + + message = matcher.respond_to?(:failure_message_for_should_not) ? + matcher.failure_message_for_should_not : + matcher.negative_failure_message + + if matcher.respond_to?(:diffable?) && matcher.diffable? + ::Spec::Expectations.fail_with message, matcher.expected.first, matcher.actual + else + ::Spec::Expectations.fail_with message + end + end + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test.rb new file mode 100644 index 00000000..ab3e87dd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test.rb @@ -0,0 +1,18 @@ +require 'spec' + +if Spec::Ruby.version.to_f >= 1.9 + gem 'test-unit','1.2.3' +end + +require 'test/unit' +require 'test/unit/testresult' + +require 'spec/interop/test/unit/testcase' +require 'spec/interop/test/unit/testsuite_adapter' +require 'spec/interop/test/unit/autorunner' +require 'spec/interop/test/unit/testresult' +require 'spec/interop/test/unit/ui/console/testrunner' + +Spec::Example::ExampleGroupFactory.default(Test::Unit::TestCase) + +Test::Unit.run = true diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/autorunner.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/autorunner.rb new file mode 100644 index 00000000..3944e699 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/autorunner.rb @@ -0,0 +1,6 @@ +class Test::Unit::AutoRunner + remove_method :process_args + def process_args(argv) + true + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testcase.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testcase.rb new file mode 100644 index 00000000..e68fdeb8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testcase.rb @@ -0,0 +1,56 @@ +require 'test/unit/testcase' + +module Test + module Unit + # This extension of the standard Test::Unit::TestCase makes RSpec + # available from within, so that you can do things like: + # + # require 'spec/test/unit' + # + # class MyTest < Test::Unit::TestCase + # it "should work with Test::Unit assertions" do + # assert_equal 4, 2+1 + # end + # + # def test_should_work_with_rspec_expectations + # (3+1).should == 5 + # end + # end + # + # See also Spec::Example::ExampleGroup + class TestCase + extend Spec::Example::ExampleGroupMethods + include Spec::Example::ExampleMethods + + def self.suite + Test::Unit::TestSuiteAdapter.new(self) + end + + def self.example_method?(method_name) + should_method?(method_name) || test_method?(method_name) + end + + def self.test_method?(method_name) + method_name =~ /^test[_A-Z]./ && ( + instance_method(method_name).arity == 0 || + instance_method(method_name).arity == -1 + ) + end + + before(:each) {setup} + after(:each) {teardown} + + def initialize(description, &implementation) + super + # Some Test::Unit extensions depend on @method_name being present. + @method_name = description.description + @_result = ::Test::Unit::TestResult.new + end + + def run(ignore_this_argument=nil) + super() + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testresult.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testresult.rb new file mode 100644 index 00000000..dddcfe86 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testresult.rb @@ -0,0 +1,6 @@ +class Test::Unit::TestResult + alias_method :tu_passed?, :passed? + def passed? + return tu_passed? & ::Spec::Runner.run + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testsuite_adapter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testsuite_adapter.rb new file mode 100644 index 00000000..912762f1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/testsuite_adapter.rb @@ -0,0 +1,34 @@ +module Test + module Unit + class TestSuiteAdapter < TestSuite + attr_reader :example_group, :examples + alias_method :tests, :examples + def initialize(example_group) + @example_group = example_group + @examples = example_group.examples + end + + def name + example_group.description + end + + def run(*args) + return true unless args.empty? + example_group.run(Spec::Runner.options) + end + + def size + example_group.number_of_examples + end + + def delete(example) + examples.delete example + end + + def empty? + examples.empty? + end + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/ui/console/testrunner.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/ui/console/testrunner.rb new file mode 100644 index 00000000..8e9995e0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/interop/test/unit/ui/console/testrunner.rb @@ -0,0 +1,61 @@ +require 'test/unit/ui/console/testrunner' + +module Test + module Unit + module UI + module Console + class TestRunner + + alias_method :started_without_rspec, :started + def started_with_rspec(result) + @result = result + @need_to_output_started = true + end + alias_method :started, :started_with_rspec + + alias_method :test_started_without_rspec, :test_started + def test_started_with_rspec(name) + if @need_to_output_started + if @rspec_io + @rspec_io.rewind + output(@rspec_io.read) + end + output("Started") + @need_to_output_started = false + end + test_started_without_rspec(name) + end + alias_method :test_started, :test_started_with_rspec + + alias_method :test_finished_without_rspec, :test_finished + def test_finished_with_rspec(name) + test_finished_without_rspec(name) + @ran_test = true + end + alias_method :test_finished, :test_finished_with_rspec + + alias_method :finished_without_rspec, :finished + def finished_with_rspec(elapsed_time) + @ran_test ||= false + if @ran_test + finished_without_rspec(elapsed_time) + end + end + alias_method :finished, :finished_with_rspec + + alias_method :setup_mediator_without_rspec, :setup_mediator + def setup_mediator_with_rspec + orig_io = @io + @io = StringIO.new + setup_mediator_without_rspec + ensure + @rspec_io = @io + @io = orig_io + end + alias_method :setup_mediator, :setup_mediator_with_rspec + + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers.rb new file mode 100644 index 00000000..a6050767 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers.rb @@ -0,0 +1,195 @@ +require 'spec/matchers/extensions/instance_exec' +require 'spec/matchers/pretty' +require 'spec/matchers/matcher' +require 'spec/matchers/operator_matcher' +require 'spec/matchers/be' +require 'spec/matchers/be_close' +require 'spec/matchers/be_instance_of' +require 'spec/matchers/be_kind_of' +require 'spec/matchers/change' +require 'spec/matchers/eql' +require 'spec/matchers/equal' +require 'spec/matchers/errors' +require 'spec/matchers/exist' +require 'spec/matchers/generated_descriptions' +require 'spec/matchers/has' +require 'spec/matchers/have' +require 'spec/matchers/include' +require 'spec/matchers/match' +require 'spec/matchers/match_array' +require 'spec/matchers/method_missing' +require 'spec/matchers/raise_error' +require 'spec/matchers/respond_to' +require 'spec/matchers/satisfy' +require 'spec/matchers/simple_matcher' +require 'spec/matchers/throw_symbol' +require 'spec/matchers/wrap_expectation' +require 'spec/matchers/compatibility' +require 'spec/matchers/dsl' + +module Spec + + # RSpec ships with a number of useful Expression Matchers. An Expression Matcher + # is any object that responds to the following methods: + # + # matches?(actual) + # failure_message_for_should + # + # These methods are also part of the matcher protocol, but are optional: + # + # does_not_match?(actual) + # failure_message_for_should_not + # description #optional + # + # These methods are from older versions of the protocol. They are still supported, + # but are not recommended: + # + # failure_message (use failure_message_for_should instead) + # negative_failure_message (use failure_message_for_should_not instead) + # + # See Spec::Expectations to learn how to use these as Expectation Matchers. + # + # == Predicates + # + # In addition to those Expression Matchers that are defined explicitly, RSpec will + # create custom Matchers on the fly for any arbitrary predicate, giving your specs + # a much more natural language feel. + # + # A Ruby predicate is a method that ends with a "?" and returns true or false. + # Common examples are +empty?+, +nil?+, and +instance_of?+. + # + # All you need to do is write +should be_+ followed by the predicate without + # the question mark, and RSpec will figure it out from there. For example: + # + # [].should be_empty => [].empty? #passes + # [].should_not be_empty => [].empty? #fails + # + # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_" + # and "be_an_", making your specs read much more naturally: + # + # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes + # + # 3.should be_a_kind_of(Fixnum) => 3.kind_of?(Numeric) #passes + # 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) #passes + # 3.should be_an_instance_of(Fixnum) => 3.instance_of?(Fixnum) #passes + # 3.should_not be_instance_of(Numeric) => 3.instance_of?(Numeric) #fails + # + # RSpec will also create custom matchers for predicates like +has_key?+. To + # use this feature, just state that the object should have_key(:key) and RSpec will + # call has_key?(:key) on the target. For example: + # + # {:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #passes + # {:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #fails + # + # You can use this feature to invoke any predicate that begins with "has_", whether it is + # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class. + # + # == Custom Matchers + # + # When you find that none of the stock Expectation Matchers provide a natural + # feeling expectation, you can very easily write your own using RSpec's matcher + # DSL or writing one from scratch. + # + # === Matcher DSL + # + # Imagine that you are writing a game in which players can be in various + # zones on a virtual board. To specify that bob should be in zone 4, you + # could say: + # + # bob.current_zone.should eql(Zone.new("4")) + # + # But you might find it more expressive to say: + # + # bob.should be_in_zone("4") + # + # and/or + # + # bob.should_not be_in_zone("3") + # + # You can create such a matcher like so: + # + # Spec::Matchers.create :be_in_zone do |zone| + # match do |player| + # player.in_zone?(zone) + # end + # end + # + # This will generate a be_in_zone method that returns a matcher + # with logical default messages for failures. You can override the failure + # messages and the generated description as follows: + # + # Spec::Matchers.create :be_in_zone do |zone| + # match do |player| + # player.in_zone?(zone) + # end + # failure_message_for_should do |player| + # # generate and return the appropriate string. + # end + # failure_message_for_should_not do |player| + # # generate and return the appropriate string. + # end + # description do + # # generate and return the appropriate string. + # end + # end + # + # Each of the message-generation methods has access to the block arguments + # passed to the create method (in this case, zone). The + # failure message methods (failure_message_for_should and + # failure_message_for_should_not) are passed the actual value (the + # receiver of should or should_not). + # + # === Custom Matcher from scratch + # + # You could also write a custom matcher from scratch, as follows: + # + # class BeInZone + # def initialize(expected) + # @expected = expected + # end + # def matches?(target) + # @target = target + # @target.current_zone.eql?(Zone.new(@expected)) + # end + # def failure_message_for_should + # "expected #{@target.inspect} to be in Zone #{@expected}" + # end + # def failure_message_for_should_not + # "expected #{@target.inspect} not to be in Zone #{@expected}" + # end + # end + # + # ... and a method like this: + # + # def be_in_zone(expected) + # BeInZone.new(expected) + # end + # + # And then expose the method to your specs. This is normally done + # by including the method and the class in a module, which is then + # included in your spec: + # + # module CustomGameMatchers + # class BeInZone + # ... + # end + # + # def be_in_zone(expected) + # ... + # end + # end + # + # describe "Player behaviour" do + # include CustomGameMatchers + # ... + # end + # + # or you can include in globally in a spec_helper.rb file required + # from your spec file(s): + # + # Spec::Runner.configure do |config| + # config.include(CustomGameMatchers) + # end + # + module Matchers; end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be.rb new file mode 100644 index 00000000..a664cccf --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be.rb @@ -0,0 +1,200 @@ +module Spec + module Matchers + + class Be #:nodoc: + include Spec::Matchers::Pretty + + def initialize(*args) + @expected = args.empty? ? true : set_expected(args.shift) + @args = args + @comparison_method = nil + end + + def matches?(actual) + @actual = actual + handling_predicate? ? run_predicate_on(actual) : match_or_compare(actual) + end + + def run_predicate_on(actual) + begin + return @result = actual.__send__(predicate, *@args) + rescue NameError => predicate_missing_error + "this needs to be here or rcov will not count this branch even though it's executed in a code example" + end + + begin + return @result = actual.__send__(present_tense_predicate, *@args) + rescue NameError + raise predicate_missing_error + end + end + + def failure_message_for_should + handling_predicate? ? + "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}" : + "expected #{@comparison_method} #{expected}, got #{@actual.inspect}".gsub(' ',' ') + end + + def failure_message_for_should_not + if handling_predicate? + "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}" + else + message = <<-MESSAGE +'should_not be #{@comparison_method} #{expected}' not only FAILED, +it is a bit confusing. + MESSAGE + + raise message << ([:===,:==].include?(@comparison_method) ? + "It might be more clearly expressed without the \"be\"?" : + "It might be more clearly expressed in the positive?") + end + end + + def description + "#{prefix_to_sentence}#{comparison} #{expected_to_sentence}#{args_to_sentence}".gsub(/\s+/,' ') + end + + [:==, :<, :<=, :>=, :>, :===].each do |method| + define_method method do |expected| + compare_to(expected, :using => method) + self + end + end + + private + def match_or_compare(actual) + TrueClass === @expected ? @actual : @actual.__send__(comparison_method, @expected) + end + + def comparison_method + @comparison_method || :equal? + end + + def expected + @expected + end + + def compare_to(expected, opts) + @expected, @comparison_method = expected, opts[:using] + end + + def set_expected(expected) + Symbol === expected ? parse_expected(expected) : expected + end + + def parse_expected(expected) + ["be_an_","be_a_","be_"].each do |prefix| + handling_predicate! + if expected.to_s =~ /^#{prefix}/ + set_prefix(prefix) + expected = expected.to_s.sub(prefix,"") + [true, false, nil].each do |val| + return val if val.to_s == expected + end + return expected.to_sym + end + end + end + + def set_prefix(prefix) + @prefix = prefix + end + + def prefix + # FIXME - this is a bit goofy - but we get failures + # if just defining @prefix = nil in initialize + @prefix = nil unless defined?(@prefix) + @prefix + end + + def handling_predicate! + @handling_predicate = true + end + + def handling_predicate? + return false if [true, false, nil].include?(expected) + # FIXME - this is a bit goofy - but we get failures + # if just defining @handling_predicate = nil or false in initialize + return defined?(@handling_predicate) ? @handling_predicate : nil + end + + def predicate + "#{@expected.to_s}?".to_sym + end + + def present_tense_predicate + "#{@expected.to_s}s?".to_sym + end + + def args_to_s + @args.empty? ? "" : parenthesize(inspected_args.join(', ')) + end + + def parenthesize(string) + return "(#{string})" + end + + def inspected_args + @args.collect{|a| a.inspect} + end + + def comparison + @comparison_method.nil? ? " " : "be #{@comparison_method.to_s} " + end + + def expected_to_sentence + split_words(expected) + end + + def prefix_to_sentence + split_words(prefix) + end + + def args_to_sentence + to_sentence(@args) + end + + end + + # :call-seq: + # should be_true + # should be_false + # should be_nil + # should be_[arbitrary_predicate](*args) + # should_not be_nil + # should_not be_[arbitrary_predicate](*args) + # + # Given true, false, or nil, will pass if actual value is + # true, false or nil (respectively). Given no args means + # the caller should satisfy an if condition (to be or not to be). + # + # Predicates are any Ruby method that ends in a "?" and returns true or false. + # Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match + # convert that into a query against the target object. + # + # The arbitrary_predicate feature will handle any predicate + # prefixed with "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of) + # or "be_" (e.g. be_empty), letting you choose the prefix that best suits the predicate. + # + # == Examples + # + # target.should be_true + # target.should be_false + # target.should be_nil + # target.should_not be_nil + # + # collection.should be_empty #passes if target.empty? + # target.should_not be_empty #passes unless target.empty? + # target.should_not be_old_enough(16) #passes unless target.old_enough?(16) + def be(*args) + Matchers::Be.new(*args) + end + + # passes if target.kind_of?(klass) + def be_a(klass) + be_a_kind_of(klass) + end + + alias_method :be_an, :be_a + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_close.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_close.rb new file mode 100644 index 00000000..28015f5f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_close.rb @@ -0,0 +1,32 @@ +module Spec + module Matchers + # :call-seq: + # should be_close(expected, delta) + # should_not be_close(expected, delta) + # + # Passes if actual == expected +/- delta + # + # == Example + # + # result.should be_close(3.0, 0.5) + def be_close(expected, delta) + Matcher.new :be_close, expected, delta do |_expected_, _delta_| + match do |actual| + (actual - _expected_).abs < _delta_ + end + + failure_message_for_should do |actual| + "expected #{_expected_} +/- (< #{_delta_}), got #{actual}" + end + + failure_message_for_should_not do |actual| + "expected #{_expected_} +/- (< #{_delta_}), got #{actual}" + end + + description do + "be close to #{_expected_} (within +- #{_delta_})" + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_instance_of.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_instance_of.rb new file mode 100644 index 00000000..ffc23840 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_instance_of.rb @@ -0,0 +1,26 @@ +module Spec + module Matchers + # :call-seq: + # should be_instance_of(expected) + # should be_an_instance_of(expected) + # should_not be_instance_of(expected) + # should_not be_an_instance_of(expected) + # + # Passes if actual.instance_of?(expected) + # + # == Examples + # + # 5.should be_instance_of(Fixnum) + # 5.should_not be_instance_of(Numeric) + # 5.should_not be_instance_of(Float) + def be_an_instance_of(expected) + Matcher.new :be_an_instance_of, expected do |_expected_| + match do |actual| + actual.instance_of?(_expected_) + end + end + end + + alias_method :be_instance_of, :be_an_instance_of + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_kind_of.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_kind_of.rb new file mode 100644 index 00000000..6a1fddc1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/be_kind_of.rb @@ -0,0 +1,26 @@ +module Spec + module Matchers + # :call-seq: + # should be_kind_of(expected) + # should be_a_kind_of(expected) + # should_not be_kind_of(expected) + # should_not be_a_kind_of(expected) + # + # Passes if actual.kind_of?(expected) + # + # == Examples + # + # 5.should be_kind_of(Fixnum) + # 5.should be_kind_of(Numeric) + # 5.should_not be_kind_of(Float) + def be_a_kind_of(expected) + Matcher.new :be_a_kind_of, expected do |_expected_| + match do |actual| + actual.kind_of?(_expected_) + end + end + end + + alias_method :be_kind_of, :be_a_kind_of + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/change.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/change.rb new file mode 100644 index 00000000..c8ab9e5c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/change.rb @@ -0,0 +1,151 @@ +module Spec + module Matchers + + #Based on patch from Wilson Bilkovich + class Change #:nodoc: + def initialize(receiver=nil, message=nil, &block) + @message = message || "result" + @value_proc = block || lambda {receiver.__send__(message)} + @to = @from = @minimum = @maximum = @amount = nil + end + + def matches?(event_proc) + raise_block_syntax_error if block_given? + + @before = evaluate_value_proc + event_proc.call + @after = evaluate_value_proc + + return (@to = false) if @from unless @from == @before + return false if @to unless @to == @after + return (@before + @amount == @after) if @amount + return ((@after - @before) >= @minimum) if @minimum + return ((@after - @before) <= @maximum) if @maximum + return @before != @after + end + + def raise_block_syntax_error + raise MatcherError.new(<<-MESSAGE +block passed to should or should_not change must use {} instead of do/end +MESSAGE + ) + end + + def evaluate_value_proc + @value_proc.call + end + + def failure_message_for_should + if @to + "#{@message} should have been changed to #{@to.inspect}, but is now #{@after.inspect}" + elsif @from + "#{@message} should have initially been #{@from.inspect}, but was #{@before.inspect}" + elsif @amount + "#{@message} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}" + elsif @minimum + "#{@message} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}" + elsif @maximum + "#{@message} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}" + else + "#{@message} should have changed, but is still #{@before.inspect}" + end + end + + def actual_delta + @after - @before + end + + def failure_message_for_should_not + "#{@message} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}" + end + + def by(amount) + @amount = amount + self + end + + def by_at_least(minimum) + @minimum = minimum + self + end + + def by_at_most(maximum) + @maximum = maximum + self + end + + def to(to) + @to = to + self + end + + def from (from) + @from = from + self + end + + def description + "change ##{@message}" + end + end + + # :call-seq: + # should change(receiver, message, &block) + # should change(receiver, message, &block).by(value) + # should change(receiver, message, &block).from(old).to(new) + # should_not change(receiver, message, &block) + # + # Allows you to specify that a Proc will cause some value to change. + # + # == Examples + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count) + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count).by(1) + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count).by_at_least(1) + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count).by_at_most(1) + # + # string = "string" + # lambda { + # string.reverse! + # }.should change { string }.from("string").to("gnirts") + # + # lambda { + # person.happy_birthday + # }.should change(person, :birthday).from(32).to(33) + # + # lambda { + # employee.develop_great_new_social_networking_app + # }.should change(employee, :title).from("Mail Clerk").to("CEO") + # + # Evaluates receiver.message or block before and after + # it evaluates the c object (generated by the lambdas in the examples + # above). + # + # Then compares the values before and after the receiver.message + # and evaluates the difference compared to the expected difference. + # + # == WARNING + # should_not change only supports the form with no + # subsequent calls to by, by_at_least, + # by_at_most, to or from. + # + # blocks passed to should change and should_not + # change must use the {} form (do/end is not + # supported). + # + def change(receiver=nil, message=nil, &block) + Matchers::Change.new(receiver, message, &block) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/compatibility.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/compatibility.rb new file mode 100644 index 00000000..3b3ddb9b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/compatibility.rb @@ -0,0 +1,14 @@ +Spec::Matchers.constants.each do |c| + if Class === (klass = Spec::Matchers.const_get(c)) + if klass.public_instance_methods.any? {|m| ['failure_message_for_should',:failure_message_for_should].include?(m)} + klass.class_eval do + alias_method :failure_message, :failure_message_for_should + end + end + if klass.public_instance_methods.any? {|m| ['failure_message_for_should_not',:failure_message_for_should_not].include?(m)} + klass.class_eval do + alias_method :negative_failure_message, :failure_message_for_should_not + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/dsl.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/dsl.rb new file mode 100644 index 00000000..73f36345 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/dsl.rb @@ -0,0 +1,20 @@ +module Spec + module Matchers + module DSL + # See Spec::Matchers + def define(name, &declarations) + define_method name do |*expected| + Spec::Matchers::Matcher.new name, *expected, &declarations + end + end + + # Deprecated - use define + def create(name, &declarations) + Spec.deprecate("Spec::Matchers.create","Spec::Matchers.define") + define(name, &declarations) + end + end + end +end + +Spec::Matchers.extend Spec::Matchers::DSL diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/eql.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/eql.rb new file mode 100644 index 00000000..98ab198d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/eql.rb @@ -0,0 +1,42 @@ +module Spec + module Matchers + # :call-seq: + # should eql(expected) + # should_not eql(expected) + # + # Passes if actual and expected are of equal value, but not necessarily the same object. + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby. + # + # == Examples + # + # 5.should eql(5) + # 5.should_not eql(3) + def eql(expected) + Matcher.new :eql, expected do |_expected_| + match do |actual| + actual.eql?(_expected_) + end + + failure_message_for_should do |actual| + <<-MESSAGE + +expected #{_expected_.inspect} + got #{actual.inspect} + +(compared using eql?) +MESSAGE + end + + failure_message_for_should_not do |actual| + <<-MESSAGE + +expected #{actual.inspect} not to equal #{_expected_.inspect} + +(compared using eql?) +MESSAGE + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/equal.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/equal.rb new file mode 100644 index 00000000..3580a95a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/equal.rb @@ -0,0 +1,53 @@ +module Spec + module Matchers + + # :call-seq: + # should equal(expected) + # should_not equal(expected) + # + # Passes if actual and expected are the same object (object identity). + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby. + # + # == Examples + # + # 5.should equal(5) #Fixnums are equal + # "5".should_not equal("5") #Strings that look the same are not the same object + def equal(expected) + Matcher.new :equal, expected do |_expected_| + match do |actual| + actual.equal?(_expected_) + end + + def inspect_object(o) + "#<#{o.class}:#{o.object_id}> => #{o.inspect}" + end + + failure_message_for_should do |actual| + <<-MESSAGE + +expected #{inspect_object(_expected_)} + got #{inspect_object(actual)} + +Compared using equal?, which compares object identity, +but expected and actual are not the same object. Use +'actual.should == expected' if you don't care about +object identity in this example. + +MESSAGE + end + + failure_message_for_should_not do |actual| + <<-MESSAGE + +expected not #{inspect_object(actual)} + got #{inspect_object(_expected_)} + +Compared using equal?, which compares object identity. + +MESSAGE + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/errors.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/errors.rb new file mode 100644 index 00000000..49c267797 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/errors.rb @@ -0,0 +1,5 @@ +module Spec + module Matchers + class MatcherError < StandardError; end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/exist.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/exist.rb new file mode 100644 index 00000000..aafcefe4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/exist.rb @@ -0,0 +1,16 @@ +module Spec + module Matchers + # :call-seq: + # should exist + # should_not exist + # + # Passes if actual.exist? + def exist + Matcher.new :exist do + match do |actual| + actual.exist? + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/extensions/instance_exec.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/extensions/instance_exec.rb new file mode 100644 index 00000000..23e63894 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/extensions/instance_exec.rb @@ -0,0 +1,23 @@ +unless respond_to?(:instance_exec) + # based on Bounded Spec InstanceExec (Mauricio Fernandez) + # http://eigenclass.org/hiki/bounded+space+instance_exec + class Object + module InstanceExecHelper; end + include InstanceExecHelper + def instance_exec(*args, &block) + begin + orig_critical, Thread.critical = Thread.critical, true + n = 0 + n += 1 while respond_to?(method_name="__instance_exec#{n}") + InstanceExecHelper.module_eval{ define_method(method_name, &block) } + ensure + Thread.critical = orig_critical + end + begin + return send(method_name, *args) + ensure + InstanceExecHelper.module_eval{ remove_method(method_name) } rescue nil + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/generated_descriptions.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/generated_descriptions.rb new file mode 100644 index 00000000..2340f57d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/generated_descriptions.rb @@ -0,0 +1,36 @@ +module Spec + module Matchers + class << self + attr_accessor :last_matcher, :last_should # :nodoc: + end + + def self.clear_generated_description + self.last_matcher = nil + self.last_should = nil + end + + def self.generated_description + return nil if last_should.nil? + "#{last_should.to_s.gsub('_',' ')} #{last_description}" + end + + private + + def self.last_description + last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE +When you call a matcher in an example without a String, like this: + +specify { object.should matcher } + +or this: + +it { should matcher } + +RSpec expects the matcher to have a #description method. You should either +add a String to the example this matcher is being used in, or give it a +description method. Then you won't have to suffer this lengthy warning again. +MESSAGE + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/has.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/has.rb new file mode 100644 index 00000000..7073e0a8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/has.rb @@ -0,0 +1,35 @@ +module Spec + module Matchers + + class Has + + def initialize(expected, *args) + @expected, @args = expected, args + end + + def matches?(actual) + actual.__send__(predicate(@expected), *@args) + end + + def failure_message_for_should + "expected ##{predicate(@expected)}(#{@args[0].inspect}) to return true, got false" + end + + def failure_message_for_should_not + "expected ##{predicate(@expected)}(#{@args[0].inspect}) to return false, got true" + end + + def description + "have key #{@args[0].inspect}" + end + + private + + def predicate(sym) + "#{sym.to_s.sub("have_","has_")}?".to_sym + end + + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/have.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/have.rb new file mode 100644 index 00000000..2975ee12 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/have.rb @@ -0,0 +1,151 @@ +module Spec + module Matchers + class Have #:nodoc: + def initialize(expected, relativity=:exactly) + @expected = (expected == :no ? 0 : expected) + @relativity = relativity + @actual = nil + end + + def relativities + @relativities ||= { + :exactly => "", + :at_least => "at least ", + :at_most => "at most " + } + end + + def matches?(collection_owner) + if collection_owner.respond_to?(@collection_name) + collection = collection_owner.__send__(@collection_name, *@args, &@block) + elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name)) + collection = collection_owner.__send__(@plural_collection_name, *@args, &@block) + elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size)) + collection = collection_owner + else + collection_owner.__send__(@collection_name, *@args, &@block) + end + @actual = collection.size if collection.respond_to?(:size) + @actual = collection.length if collection.respond_to?(:length) + raise not_a_collection if @actual.nil? + return @actual >= @expected if @relativity == :at_least + return @actual <= @expected if @relativity == :at_most + return @actual == @expected + end + + def not_a_collection + "expected #{@collection_name} to be a collection but it does not respond to #length or #size" + end + + def failure_message_for_should + "expected #{relative_expectation} #{@collection_name}, got #{@actual}" + end + + def failure_message_for_should_not + if @relativity == :exactly + return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}" + elsif @relativity == :at_most + return <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_most(#{@expected}).#{@collection_name} +We recommend that you use this instead: + should have_at_least(#{@expected + 1}).#{@collection_name} +EOF + elsif @relativity == :at_least + return <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_least(#{@expected}).#{@collection_name} +We recommend that you use this instead: + should have_at_most(#{@expected - 1}).#{@collection_name} +EOF + end + end + + def description + "have #{relative_expectation} #{@collection_name}" + end + + def respond_to?(sym) + @expected.respond_to?(sym) || super + end + + private + + def method_missing(sym, *args, &block) + @collection_name = sym + if inflector = (defined?(ActiveSupport::Inflector) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil)) + @plural_collection_name = inflector.pluralize(sym.to_s) + end + @args = args + @block = block + self + end + + def relative_expectation + "#{relativities[@relativity]}#{@expected}" + end + end + + # :call-seq: + # should have(number).named_collection__or__sugar + # should_not have(number).named_collection__or__sugar + # + # Passes if receiver is a collection with the submitted + # number of items OR if the receiver OWNS a collection + # with the submitted number of items. + # + # If the receiver OWNS the collection, you must use the name + # of the collection. So if a Team instance has a + # collection named #players, you must use that name + # to set the expectation. + # + # If the receiver IS the collection, you can use any name + # you like for named_collection. We'd recommend using + # either "elements", "members", or "items" as these are all + # standard ways of describing the things IN a collection. + # + # This also works for Strings, letting you set an expectation + # about its length + # + # == Examples + # + # # Passes if team.players.size == 11 + # team.should have(11).players + # + # # Passes if [1,2,3].length == 3 + # [1,2,3].should have(3).items #"items" is pure sugar + # + # # Passes if "this string".length == 11 + # "this string".should have(11).characters #"characters" is pure sugar + def have(n) + Matchers::Have.new(n) + end + alias :have_exactly :have + + # :call-seq: + # should have_at_least(number).items + # + # Exactly like have() with >=. + # + # == Warning + # + # +should_not+ +have_at_least+ is not supported + def have_at_least(n) + Matchers::Have.new(n, :at_least) + end + + # :call-seq: + # should have_at_most(number).items + # + # Exactly like have() with <=. + # + # == Warning + # + # +should_not+ +have_at_most+ is not supported + def have_at_most(n) + Matchers::Have.new(n, :at_most) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/include.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/include.rb new file mode 100644 index 00000000..a2a7fe3d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/include.rb @@ -0,0 +1,44 @@ +module Spec + module Matchers + # :call-seq: + # should include(expected) + # should_not include(expected) + # + # Passes if actual includes expected. This works for + # collections and Strings. You can also pass in multiple args + # and it will only pass if all args are found in collection. + # + # == Examples + # + # [1,2,3].should include(3) + # [1,2,3].should include(2,3) #would pass + # [1,2,3].should include(2,3,4) #would fail + # [1,2,3].should_not include(4) + # "spread".should include("read") + # "spread".should_not include("red") + def include(*expected) + Matcher.new :include, *expected do |*_expected_| + match do |actual| + helper(actual, *_expected_) + end + + def helper(actual, *_expected_) + _expected_.each do |expected| + if actual.is_a?(Hash) + if expected.is_a?(Hash) + expected.each_pair do |k,v| + return false unless actual[k] == v + end + else + return false unless actual.has_key?(expected) + end + else + return false unless actual.include?(expected) + end + end + true + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/match.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/match.rb new file mode 100644 index 00000000..b4b9ea86 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/match.rb @@ -0,0 +1,21 @@ +module Spec + module Matchers + # :call-seq: + # should match(pattern) + # should_not match(pattern) + # + # Given a Regexp or String, passes if actual.match(pattern) + # + # == Examples + # + # email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) + # email.should match("@example.com") + def match(expected) + Matcher.new :match, expected do |_expected_| + match do |actual| + actual.match(_expected_) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/match_array.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/match_array.rb new file mode 100644 index 00000000..51b4f392 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/match_array.rb @@ -0,0 +1,71 @@ +module Spec + module Matchers + + class MatchArray #:nodoc: + include Spec::Matchers::Pretty + + def initialize(expected) + @expected = expected + end + + def matches?(actual) + @actual = actual + @extra_items = difference_between_arrays(@actual, @expected) + @missing_items = difference_between_arrays(@expected, @actual) + @extra_items.empty? & @missing_items.empty? + end + + def failure_message_for_should + message = "expected collection contained: #{safe_sort(@expected).inspect}\n" + message += "actual collection contained: #{safe_sort(@actual).inspect}\n" + message += "the missing elements were: #{safe_sort(@missing_items).inspect}\n" unless @missing_items.empty? + message += "the extra elements were: #{safe_sort(@extra_items).inspect}\n" unless @extra_items.empty? + message + end + + def failure_message_for_should_not + "Matcher does not support should_not" + end + + def description + "contain exactly #{_pretty_print(@expected)}" + end + + private + + def safe_sort(array) + array.all?{|item| item.respond_to?(:<=>)} ? array.sort : array + end + + def difference_between_arrays(array_1, array_2) + difference = array_1.dup + array_2.each do |element| + if index = difference.index(element) + difference.delete_at(index) + end + end + difference + end + + + end + + # :call-seq: + # should =~ expected + # + # Passes if actual contains all of the expected regardless of order. + # This works for collections. Pass in multiple args and it will only + # pass if all args are found in collection. + # + # NOTE: there is no should_not version of array.should =~ other_array + # + # == Examples + # + # [1,2,3].should =~ [1,2,3] # => would pass + # [1,2,3].should =~ [2,3,1] # => would pass + # [1,2,3,4].should =~ [1,2,3] # => would fail + # [1,2,2,3].should =~ [1,2,3] # => would fail + # [1,2,3].should =~ [1,2,3,4] # => would fail + OperatorMatcher.register(Array, '=~', Spec::Matchers::MatchArray) + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/matcher.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/matcher.rb new file mode 100644 index 00000000..bd98d474 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/matcher.rb @@ -0,0 +1,85 @@ +module Spec + module Matchers + class Matcher + include Spec::Matchers::Pretty + + attr_reader :expected, :actual + + def initialize(name, *expected, &declarations) + @name = name + @expected = expected + @diffable = false + @messages = { + :description => lambda {"#{name_to_sentence}#{expected_to_sentence}"}, + :failure_message_for_should => lambda {|actual| "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"}, + :failure_message_for_should_not => lambda {|actual| "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"} + } + making_declared_methods_public do + instance_exec(*@expected, &declarations) + end + end + + def matches?(actual) + @actual = actual + instance_exec(@actual, &@match_block) + end + + def description(&block) + cache_or_call_cached(:description, &block) + end + + def failure_message_for_should(&block) + cache_or_call_cached(:failure_message_for_should, @actual, &block) + end + + def failure_message_for_should_not(&block) + cache_or_call_cached(:failure_message_for_should_not, @actual, &block) + end + + def match(&block) + @match_block = block + end + + def diffable? + @diffable + end + + def diffable + @diffable = true + end + + private + + def making_declared_methods_public # :nodoc: + # Our home-grown instance_exec in ruby 1.8.6 results in any methods + # declared in the block eval'd by instance_exec in the block to which we + # are yielding here are scoped private. This is NOT the case for Ruby + # 1.8.7 or 1.9. + # + # Also, due some crazy scoping that I don't understand, these methods + # are actually available in the specs (something about the matcher being + # defined in the scope of Spec::Matchers or within an example), so not + # doing the following will not cause specs to fail, but they *will* + # cause features to fail and that will make users unhappy. So don't. + orig_private_methods = private_methods + yield + st = (class << self; self; end) + (private_methods - orig_private_methods).each {|m| st.__send__ :public, m} + end + + def cache_or_call_cached(key, actual=nil, &block) + block ? @messages[key] = block : + actual.nil? ? @messages[key].call : @messages[key].call(actual) + end + + def name_to_sentence + split_words(@name) + end + + def expected_to_sentence + to_sentence(@expected) + end + + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/method_missing.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/method_missing.rb new file mode 100644 index 00000000..ae7f3979 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/method_missing.rb @@ -0,0 +1,9 @@ +module Spec + module Matchers + def method_missing(sym, *args, &block) # :nodoc: + return Matchers::Be.new(sym, *args) if sym.to_s =~ /^be_/ + return Matchers::Has.new(sym, *args) if sym.to_s =~ /^have_/ + super + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/operator_matcher.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/operator_matcher.rb new file mode 100644 index 00000000..30295be0 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/operator_matcher.rb @@ -0,0 +1,78 @@ +module Spec + module Matchers + + class OperatorMatcher + class << self + def registry + @registry ||= {} + end + + def register(klass, operator, matcher) + registry[klass] ||= {} + registry[klass][operator] = matcher + end + + def get(klass, operator) + registry[klass] && registry[klass][operator] + end + end + + def initialize(actual) + @actual = actual + end + + def self.use_custom_matcher_or_delegate(operator) + define_method(operator) do |expected| + if matcher = OperatorMatcher.get(@actual.class, operator) + @actual.send(::Spec::Matchers.last_should, matcher.new(expected)) + else + eval_match(@actual, operator, expected) + end + end + end + + ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator| + use_custom_matcher_or_delegate operator + end + + def fail_with_message(message) + Spec::Expectations.fail_with(message, @expected, @actual) + end + + def description + "#{@operator} #{@expected.inspect}" + end + + private + + def eval_match(actual, operator, expected) + ::Spec::Matchers.last_matcher = self + @operator, @expected = operator, expected + __delegate_operator(actual, operator, expected) + end + + end + + class PositiveOperatorMatcher < OperatorMatcher #:nodoc: + def __delegate_operator(actual, operator, expected) + if actual.__send__(operator, expected) + true + elsif ['==','===', '=~'].include?(operator) + fail_with_message("expected: #{expected.inspect},\n got: #{actual.inspect} (using #{operator})") + else + fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}") + end + end + + end + + class NegativeOperatorMatcher < OperatorMatcher #:nodoc: + def __delegate_operator(actual, operator, expected) + return false unless actual.__send__(operator, expected) + return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}") + end + + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/pretty.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/pretty.rb new file mode 100644 index 00000000..15205837 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/pretty.rb @@ -0,0 +1,37 @@ +module Spec + module Matchers + module Pretty + def split_words(sym) + sym.to_s.gsub(/_/,' ') + end + + def to_sentence(words) + words = words.map{|w| w.inspect} + case words.length + when 0 + "" + when 1 + " #{words[0]}" + when 2 + " #{words[0]} and #{words[1]}" + else + " #{words[0...-1].join(', ')}, and #{words[-1]}" + end + end + + def _pretty_print(array) + result = "" + array.each_with_index do |item, index| + if index < (array.length - 2) + result << "#{item.inspect}, " + elsif index < (array.length - 1) + result << "#{item.inspect} and " + else + result << "#{item.inspect}" + end + end + result + end + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/raise_error.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/raise_error.rb new file mode 100644 index 00000000..65bdf237 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/raise_error.rb @@ -0,0 +1,129 @@ +module Spec + module Matchers + class RaiseError #:nodoc: + def initialize(expected_error_or_message=Exception, expected_message=nil, &block) + @block = block + @actual_error = nil + case expected_error_or_message + when String, Regexp + @expected_error, @expected_message = Exception, expected_error_or_message + else + @expected_error, @expected_message = expected_error_or_message, expected_message + end + end + + def matches?(given_proc) + @raised_expected_error = false + @with_expected_message = false + @eval_block = false + @eval_block_passed = false + begin + given_proc.call + rescue @expected_error => @actual_error + @raised_expected_error = true + @with_expected_message = verify_message + rescue Exception => @actual_error + # This clause should be empty, but rcov will not report it as covered + # unless something (anything) is executed within the clause + rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0" + end + + unless negative_expectation? + eval_block if @raised_expected_error && @with_expected_message && @block + end + ensure + return (@raised_expected_error & @with_expected_message) ? (@eval_block ? @eval_block_passed : true) : false + end + + def eval_block + @eval_block = true + begin + @block[@actual_error] + @eval_block_passed = true + rescue Exception => err + @actual_error = err + end + end + + def verify_message + case @expected_message + when nil + true + when Regexp + @expected_message =~ @actual_error.message + else + @expected_message == @actual_error.message + end + end + + def failure_message_for_should + @eval_block ? @actual_error.message : "expected #{expected_error}#{given_error}" + end + + def failure_message_for_should_not + "expected no #{expected_error}#{given_error}" + end + + def description + "raise #{expected_error}" + end + + private + def expected_error + case @expected_message + when nil + @expected_error + when Regexp + "#{@expected_error} with message matching #{@expected_message.inspect}" + else + "#{@expected_error} with #{@expected_message.inspect}" + end + end + + def given_error + @actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}" + end + + def negative_expectation? + # YES - I'm a bad person... help me find a better way - ryand + caller.first(3).find { |s| s =~ /should_not/ } + end + end + + # :call-seq: + # should raise_error() + # should raise_error(NamedError) + # should raise_error(NamedError, String) + # should raise_error(NamedError, Regexp) + # should raise_error() { |error| ... } + # should raise_error(NamedError) { |error| ... } + # should raise_error(NamedError, String) { |error| ... } + # should raise_error(NamedError, Regexp) { |error| ... } + # should_not raise_error() + # should_not raise_error(NamedError) + # should_not raise_error(NamedError, String) + # should_not raise_error(NamedError, Regexp) + # + # With no args, matches if any error is raised. + # With a named error, matches only if that specific error is raised. + # With a named error and messsage specified as a String, matches only if both match. + # With a named error and messsage specified as a Regexp, matches only if both match. + # Pass an optional block to perform extra verifications on the exception matched + # + # == Examples + # + # lambda { do_something_risky }.should raise_error + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError) + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError) { |error| error.data.should == 42 } + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky") + # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/) + # + # lambda { do_something_risky }.should_not raise_error + # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError) + # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky") + # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/) + def raise_error(error=Exception, message=nil, &block) + Matchers::RaiseError.new(error, message, &block) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/respond_to.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/respond_to.rb new file mode 100644 index 00000000..9161cb94 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/respond_to.rb @@ -0,0 +1,71 @@ +module Spec + module Matchers + + class RespondTo #:nodoc: + def initialize(*names) + @names = names + @expected_arity = nil + @names_not_responded_to = [] + end + + def matches?(actual) + @actual = actual + @names.each do |name| + @names_not_responded_to << name unless actual.respond_to?(name) && matches_arity?(actual, name) + end + return @names_not_responded_to.empty? + end + + def failure_message_for_should + "expected #{@actual.inspect} to respond to #{@names_not_responded_to.collect {|name| name.inspect }.join(', ')}#{with_arity}" + end + + def failure_message_for_should_not + "expected #{@actual.inspect} not to respond to #{@names.collect {|name| name.inspect }.join(', ')}" + end + + def description + "respond to #{pp_names}#{with_arity}" + end + + def with(n) + @expected_arity = n + self + end + + def argument + self + end + alias :arguments :argument + + private + + def matches_arity?(actual, name) + @expected_arity.nil?? true : @expected_arity == actual.method(name).arity + end + + def with_arity + @expected_arity.nil?? "" : + " with #{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}" + end + + def pp_names + # Ruby 1.9 returns the same thing for array.to_s as array.inspect, so just use array.inspect here + @names.length == 1 ? "##{@names.first}" : @names.inspect + end + end + + # :call-seq: + # should respond_to(*names) + # should_not respond_to(*names) + # + # Matches if the target object responds to all of the names + # provided. Names can be Strings or Symbols. + # + # == Examples + # + def respond_to(*names) + Matchers::RespondTo.new(*names) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/satisfy.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/satisfy.rb new file mode 100644 index 00000000..58e3f56a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/satisfy.rb @@ -0,0 +1,47 @@ +module Spec + module Matchers + + class Satisfy #:nodoc: + def initialize(&block) + @block = block + end + + def matches?(actual, &block) + @block = block if block + @actual = actual + @block.call(actual) + end + + def failure_message_for_should + "expected #{@actual} to satisfy block" + end + + def failure_message_for_should_not + "expected #{@actual} not to satisfy block" + end + end + + # :call-seq: + # should satisfy {} + # should_not satisfy {} + # + # Passes if the submitted block returns true. Yields target to the + # block. + # + # Generally speaking, this should be thought of as a last resort when + # you can't find any other way to specify the behaviour you wish to + # specify. + # + # If you do find yourself in such a situation, you could always write + # a custom matcher, which would likely make your specs more expressive. + # + # == Examples + # + # 5.should satisfy { |n| + # n > 3 + # } + def satisfy(&block) + Matchers::Satisfy.new(&block) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/simple_matcher.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/simple_matcher.rb new file mode 100644 index 00000000..5ab7f306 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/simple_matcher.rb @@ -0,0 +1,133 @@ +module Spec + module Matchers + class SimpleMatcher + attr_writer :failure_message, :negative_failure_message, :description + + def initialize(description, &match_block) + @description = description + @match_block = match_block + @failure_message = @negative_failure_message = nil + end + + def matches?(given) + @given = given + case @match_block.arity + when 2 + @match_block.call(@given, self) + else + @match_block.call(@given) + end + end + + def description + @description || explanation + end + + def failure_message_for_should + @failure_message || (@description.nil? ? explanation : %[expected #{@description.inspect} but got #{@given.inspect}]) + end + + def failure_message_for_should_not + @negative_failure_message || (@description.nil? ? explanation : %[expected not to get #{@description.inspect}, but got #{@given.inspect}]) + end + + def explanation + "No description provided. See RDoc for simple_matcher()" + end + end + + # simple_matcher makes it easy for you to create your own custom matchers + # in just a few lines of code when you don't need all the power of a + # completely custom matcher object. + # + # The description argument will appear as part of any failure + # message, and is also the source for auto-generated descriptions. + # + # The match_block can have an arity of 1 or 2. The first block + # argument will be the given value. The second, if the block accepts it + # will be the matcher itself, giving you access to set custom failure + # messages in favor of the defaults. + # + # The match_block should return a boolean: true + # indicates a match, which will pass if you use should and fail + # if you use should_not. false (or nil) indicates no match, + # which will do the reverse: fail if you use should and pass if + # you use should_not. + # + # An error in the match_block will bubble up, resulting in a + # failure. + # + # == Example with default messages + # + # def be_even + # simple_matcher("an even number") { |given| given % 2 == 0 } + # end + # + # describe 2 do + # it "should be even" do + # 2.should be_even + # end + # end + # + # Given an odd number, this example would produce an error message stating: + # expected "an even number", got 3. + # + # Unfortunately, if you're a fan of auto-generated descriptions, this will + # produce "should an even number." Not the most desirable result. You can + # control that using custom messages: + # + # == Example with custom messages + # + # def rhyme_with(expected) + # simple_matcher("rhyme with #{expected.inspect}") do |given, matcher| + # matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}" + # matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}" + # given.rhymes_with? expected + # end + # end + # + # # OR + # + # def rhyme_with(expected) + # simple_matcher do |given, matcher| + # matcher.description = "rhyme with #{expected.inspect}" + # matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}" + # matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}" + # given.rhymes_with? expected + # end + # end + # + # describe "pecan" do + # it "should rhyme with 'be gone'" do + # nut = "pecan" + # nut.extend Rhymer + # nut.should rhyme_with("be gone") + # end + # end + # + # The resulting messages would be: + # description: rhyme with "be gone" + # failure_message: expected "pecan" to rhyme with "be gone" + # negative failure_message: expected "pecan" not to rhyme with "be gone" + # + # == Wrapped Expectations + # + # Because errors will bubble up, it is possible to wrap other expectations + # in a SimpleMatcher. + # + # def be_even + # simple_matcher("an even number") { |given| (given % 2).should == 0 } + # end + # + # BE VERY CAREFUL when you do this. Only use wrapped expectations for + # matchers that will always be used in only the positive + # (should) or negative (should_not), but not both. + # The reason is that is you wrap a should and call the wrapper + # with should_not, the correct result (the should + # failing), will fail when you want it to pass. + # + def simple_matcher(description=nil, &match_block) + SimpleMatcher.new(description, &match_block) + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/throw_symbol.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/throw_symbol.rb new file mode 100644 index 00000000..da16bb65 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/throw_symbol.rb @@ -0,0 +1,104 @@ +module Spec + module Matchers + + class ThrowSymbol #:nodoc: + def initialize(expected_symbol = nil, expected_arg=nil) + @expected_symbol = expected_symbol + @expected_arg = expected_arg + @caught_symbol = @caught_arg = nil + end + + def matches?(given_proc) + begin + if @expected_symbol.nil? + given_proc.call + else + @caught_arg = catch :proc_did_not_throw_anything do + catch @expected_symbol do + given_proc.call + throw :proc_did_not_throw_anything, :nothing_thrown + end + end + @caught_symbol = @expected_symbol unless @caught_arg == :nothing_thrown + end + + # Ruby 1.8 uses NameError with `symbol' + # Ruby 1.9 uses ArgumentError with :symbol + rescue NameError, ArgumentError => e + raise e unless e.message =~ /uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/ + @caught_symbol = $2.to_sym + + ensure + if @expected_symbol.nil? + return !@caught_symbol.nil? + else + if @expected_arg.nil? + return @caught_symbol == @expected_symbol + else + return (@caught_symbol == @expected_symbol) & (@caught_arg == @expected_arg) + end + end + end + end + + def failure_message_for_should + if @caught_symbol + "expected #{expected}, got #{@caught_symbol.inspect}" + else + "expected #{expected} but nothing was thrown" + end + end + + def failure_message_for_should_not + if @expected_symbol + "expected #{expected} not to be thrown" + else + "expected no Symbol, got :#{@caught_symbol}" + end + end + + def description + "throw #{expected}" + end + + private + + def expected + @expected_symbol.nil? ? "a Symbol" : "#{@expected_symbol.inspect}#{args}" + end + + def args + @expected_arg.nil? ? "" : " with #{@expected_arg.inspect}" + end + + end + + # :call-seq: + # should throw_symbol() + # should throw_symbol(:sym) + # should throw_symbol(:sym, arg) + # should_not throw_symbol() + # should_not throw_symbol(:sym) + # should_not throw_symbol(:sym, arg) + # + # Given no argument, matches if a proc throws any Symbol. + # + # Given a Symbol, matches if the given proc throws the specified Symbol. + # + # Given a Symbol and an arg, matches if the given proc throws the + # specified Symbol with the specified arg. + # + # == Examples + # + # lambda { do_something_risky }.should throw_symbol + # lambda { do_something_risky }.should throw_symbol(:that_was_risky) + # lambda { do_something_risky }.should throw_symbol(:that_was_risky, culprit) + # + # lambda { do_something_risky }.should_not throw_symbol + # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky) + # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky, culprit) + def throw_symbol(sym=nil) + Matchers::ThrowSymbol.new(sym) + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/wrap_expectation.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/wrap_expectation.rb new file mode 100644 index 00000000..95162cae --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/matchers/wrap_expectation.rb @@ -0,0 +1,55 @@ +module Spec + module Matchers + # wraps an expectation in a block that will return true if the + # expectation passes and false if it fails (without bubbling up + # the failure). + # + # This is intended to be used in the context of a simple matcher, + # and is especially useful for wrapping multiple expectations or + # one or more assertions from test/unit extensions when running + # with test/unit. + # + # == Examples + # + # def eat_cheese(cheese) + # simple_matcher do |mouse, matcher| + # matcher.failure_message = "expected #{mouse} to eat cheese" + # wrap_expectation do |matcher| + # assert_eats_cheese(mouse) + # end + # end + # end + # + # describe Mouse do + # it "eats cheese" do + # Mouse.new.should eat_cheese + # end + # end + # + # You might be wondering "why would I do this if I could just say" + # assert_eats_cheese?", a fair question, indeed. You might prefer + # to replace the word assert with something more aligned with the + # rest of your code examples. You are using rspec, after all. + # + # The other benefit you get is that you can use the negative version + # of the matcher: + # + # describe Cat do + # it "does not eat cheese" do + # Cat.new.should_not eat_cheese + # end + # end + # + # So in the event there is no assert_does_not_eat_cheese available, + # you're all set! + def wrap_expectation(matcher, &block) + begin + block.call(matcher) + return true + rescue Exception => e + matcher.failure_message = e.message + return false + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks.rb new file mode 100644 index 00000000..339c0cc5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks.rb @@ -0,0 +1,200 @@ +require 'spec/mocks/framework' +require 'spec/mocks/extensions/object' + +module Spec + # == Mocks and Stubs + # + # RSpec will create Mock Objects and Stubs for you at runtime, or attach stub/mock behaviour + # to any of your real objects (Partial Mock/Stub). Because the underlying implementation + # for mocks and stubs is the same, you can intermingle mock and stub + # behaviour in either dynamically generated mocks or your pre-existing classes. + # There is a semantic difference in how they are created, however, + # which can help clarify the role it is playing within a given spec. + # + # == Mock Objects + # + # Mocks are objects that allow you to set and verify expectations that they will + # receive specific messages during run time. They are very useful for specifying how the subject of + # the spec interacts with its collaborators. This approach is widely known as "interaction + # testing". + # + # Mocks are also very powerful as a design tool. As you are + # driving the implementation of a given class, Mocks provide an anonymous + # collaborator that can change in behaviour as quickly as you can write an expectation in your + # spec. This flexibility allows you to design the interface of a collaborator that often + # does not yet exist. As the shape of the class being specified becomes more clear, so do the + # requirements for its collaborators - often leading to the discovery of new types that are + # needed in your system. + # + # Read Endo-Testing[http://www.mockobjects.com/files/endotesting.pdf] for a much + # more in depth description of this process. + # + # == Stubs + # + # Stubs are objects that allow you to set "stub" responses to + # messages. As Martin Fowler points out on his site, + # mocks_arent_stubs[http://www.martinfowler.com/articles/mocksArentStubs.html]. + # Paraphrasing Fowler's paraphrasing + # of Gerard Meszaros: Stubs provide canned responses to messages they might receive in a test, while + # mocks allow you to specify and, subsquently, verify that certain messages should be received during + # the execution of a test. + # + # == Partial Mocks/Stubs + # + # RSpec also supports partial mocking/stubbing, allowing you to add stub/mock behaviour + # to instances of your existing classes. This is generally + # something to be avoided, because changes to the class can have ripple effects on + # seemingly unrelated specs. When specs fail due to these ripple effects, the fact + # that some methods are being mocked can make it difficult to understand why a + # failure is occurring. + # + # That said, partials do allow you to expect and + # verify interactions with class methods such as +#find+ and +#create+ + # on Ruby on Rails model classes. + # + # == Further Reading + # + # There are many different viewpoints about the meaning of mocks and stubs. If you are interested + # in learning more, here is some recommended reading: + # + # * Mock Objects: http://www.mockobjects.com/ + # * Endo-Testing: http://www.mockobjects.com/files/endotesting.pdf + # * Mock Roles, Not Objects: http://www.mockobjects.com/files/mockrolesnotobjects.pdf + # * Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html + # * Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html + # + # == Creating a Mock + # + # You can create a mock in any specification (or setup) using: + # + # mock(name, options={}) + # + # The optional +options+ argument is a +Hash+. Currently the only supported + # option is +:null_object+. Setting this to true instructs the mock to ignore + # any messages it hasn’t been told to expect – and quietly return itself. For example: + # + # mock("person", :null_object => true) + # + # == Creating a Stub + # + # You can create a stub in any specification (or setup) using: + # + # stub(name, stub_methods_and_values_hash) + # + # For example, if you wanted to create an object that always returns + # "More?!?!?!" to "please_sir_may_i_have_some_more" you would do this: + # + # stub("Mr Sykes", :please_sir_may_i_have_some_more => "More?!?!?!") + # + # == Creating a Partial Mock + # + # You don't really "create" a partial mock, you simply add method stubs and/or + # mock expectations to existing classes and objects: + # + # Factory.should_receive(:find).with(id).and_return(value) + # obj.stub!(:to_i).and_return(3) + # etc ... + # + # == Expecting Messages + # + # my_mock.should_receive(:sym) + # my_mock.should_not_receive(:sym) + # + # == Expecting Arguments + # + # my_mock.should_receive(:sym).with(*args) + # my_mock.should_not_receive(:sym).with(*args) + # + # == Argument Matchers + # + # Arguments that are passed to #with are compared with actual arguments received + # using == by default. In cases in which you want to specify things about the arguments + # rather than the arguments themselves, you can use any of RSpec's Expression Matchers. + # They don't all make syntactic sense (they were primarily designed for use with + # Spec::Expectations), but you are free to create your own custom Spec::Matchers. + # + # Spec::Mocks does provide one additional Matcher method named #ducktype. + # + # In addition, Spec::Mocks adds some keyword Symbols that you can use to + # specify certain kinds of arguments: + # + # my_mock.should_receive(:sym).with(no_args()) + # my_mock.should_receive(:sym).with(any_args()) + # my_mock.should_receive(:sym).with(1, kind_of(Numeric), "b") #2nd argument can any kind of Numeric + # my_mock.should_receive(:sym).with(1, boolean(), "b") #2nd argument can true or false + # my_mock.should_receive(:sym).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp + # my_mock.should_receive(:sym).with(1, anything(), "b") #2nd argument can be anything at all + # my_mock.should_receive(:sym).with(1, ducktype(:abs, :div), "b") + # #2nd argument can be object that responds to #abs and #div + # + # == Receive Counts + # + # my_mock.should_receive(:sym).once + # my_mock.should_receive(:sym).twice + # my_mock.should_receive(:sym).exactly(n).times + # my_mock.should_receive(:sym).at_least(:once) + # my_mock.should_receive(:sym).at_least(:twice) + # my_mock.should_receive(:sym).at_least(n).times + # my_mock.should_receive(:sym).at_most(:once) + # my_mock.should_receive(:sym).at_most(:twice) + # my_mock.should_receive(:sym).at_most(n).times + # my_mock.should_receive(:sym).any_number_of_times + # + # == Ordering + # + # my_mock.should_receive(:sym).ordered + # my_mock.should_receive(:other_sym).ordered + # #This will fail if the messages are received out of order + # + # == Setting Reponses + # + # Whether you are setting a mock expectation or a simple stub, you can tell the + # object precisely how to respond: + # + # my_mock.should_receive(:sym).and_return(value) + # my_mock.should_receive(:sym).exactly(3).times.and_return(value1, value2, value3) + # # returns value1 the first time, value2 the second, etc + # my_mock.should_receive(:sym).and_return { ... } #returns value returned by the block + # my_mock.should_receive(:sym).and_raise(error) + # #error can be an instantiated object or a class + # #if it is a class, it must be instantiable with no args + # my_mock.should_receive(:sym).and_throw(:sym) + # my_mock.should_receive(:sym).and_yield(values,to,yield) + # my_mock.should_receive(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time) + # # for methods that yield to a block multiple times + # + # Any of these responses can be applied to a stub as well, but stubs do + # not support any qualifiers about the message received (i.e. you can't specify arguments + # or receive counts): + # + # my_mock.stub!(:sym).and_return(value) + # my_mock.stub!(:sym).and_return(value1, value2, value3) + # my_mock.stub!(:sym).and_raise(error) + # my_mock.stub!(:sym).and_throw(:sym) + # my_mock.stub!(:sym).and_yield(values,to,yield) + # my_mock.stub!(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time) + # + # == Arbitrary Handling + # + # Once in a while you'll find that the available expectations don't solve the + # particular problem you are trying to solve. Imagine that you expect the message + # to come with an Array argument that has a specific length, but you don't care + # what is in it. You could do this: + # + # my_mock.should_receive(:sym) do |arg| + # arg.should be_an_istance_of(Array) + # arg.length.should == 7 + # end + # + # Note that this would fail if the number of arguments received was different from + # the number of block arguments (in this case 1). + # + # == Combining Expectation Details + # + # Combining the message name with specific arguments, receive counts and responses + # you can get quite a bit of detail in your expectations: + # + # my_mock.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError) + module Mocks + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/argument_expectation.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/argument_expectation.rb new file mode 100644 index 00000000..b51b7bae --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/argument_expectation.rb @@ -0,0 +1,51 @@ +module Spec + module Mocks + + class ArgumentExpectation + attr_reader :args + + def initialize(args, &block) + @args = args + @matchers_block = block + @match_any_args = false + @matchers = nil + + if ArgumentMatchers::AnyArgsMatcher === args.first + @match_any_args = true + elsif ArgumentMatchers::NoArgsMatcher === args.first + @matchers = [] + else + @matchers = args.collect {|arg| matcher_for(arg)} + end + end + + def matcher_for(arg) + return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg) + return ArgumentMatchers::RegexpMatcher.new(arg) if arg.is_a?(Regexp) + return ArgumentMatchers::EqualityProxy.new(arg) + end + + def is_matcher?(obj) + return obj.respond_to?(:matches?) & obj.respond_to?(:description) + end + + def args_match?(given_args) + match_any_args? || matchers_block_matches?(given_args) || matchers_match?(given_args) + end + + def matchers_block_matches?(given_args) + @matchers_block ? @matchers_block.call(*given_args) : nil + end + + def matchers_match?(given_args) + @matchers == given_args + end + + def match_any_args? + @match_any_args + end + + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/argument_matchers.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/argument_matchers.rb new file mode 100644 index 00000000..d42d9220 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/argument_matchers.rb @@ -0,0 +1,233 @@ +module Spec + module Mocks + + # ArgumentMatchers are messages that you can include in message + # expectations to match arguments against a broader check than simple + # equality. + # + # With the exception of any_args() and no_args(), the matchers + # are all positional - they match against the arg in the given position. + module ArgumentMatchers + + class AnyArgsMatcher + def description + "any args" + end + end + + class AnyArgMatcher + def initialize(ignore) + end + + def ==(other) + true + end + end + + class NoArgsMatcher + def description + "no args" + end + end + + class RegexpMatcher + def initialize(regexp) + @regexp = regexp + end + + def ==(value) + return value =~ @regexp unless value.is_a?(Regexp) + value == @regexp + end + end + + class BooleanMatcher + def initialize(ignore) + end + + def ==(value) + TrueClass === value || FalseClass === value + end + end + + class HashIncludingMatcher + def initialize(expected) + @expected = expected + end + + def ==(actual) + @expected.each do | key, value | + return false unless actual.has_key?(key) && value == actual[key] + end + true + rescue NoMethodError => ex + return false + end + + def description + "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})" + end + end + + class HashNotIncludingMatcher + def initialize(expected) + @expected = expected + end + + def ==(actual) + @expected.each do | key, value | + return false if actual.has_key?(key) && value == actual[key] + end + true + rescue NoMethodError => ex + return false + end + + def description + "hash_not_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})" + end + end + + class DuckTypeMatcher + def initialize(*methods_to_respond_to) + @methods_to_respond_to = methods_to_respond_to + end + + def ==(value) + @methods_to_respond_to.all? { |sym| value.respond_to?(sym) } + end + end + + class MatcherMatcher + def initialize(matcher) + @matcher = matcher + end + + def ==(value) + @matcher.matches?(value) + end + end + + class EqualityProxy + def initialize(given) + @given = given + end + + def ==(expected) + @given == expected + end + end + + class InstanceOf + def initialize(klass) + @klass = klass + end + + def ==(actual) + actual.instance_of?(@klass) + end + end + + class KindOf + def initialize(klass) + @klass = klass + end + + def ==(actual) + actual.kind_of?(@klass) + end + end + + # :call-seq: + # object.should_receive(:message).with(any_args()) + # + # Passes if object receives :message with any args at all. This is + # really a more explicit variation of object.should_receive(:message) + def any_args + AnyArgsMatcher.new + end + + # :call-seq: + # object.should_receive(:message).with(anything()) + # + # Passes as long as there is an argument. + def anything + AnyArgMatcher.new(nil) + end + + # :call-seq: + # object.should_receive(:message).with(no_args) + # + # Passes if no arguments are passed along with the message + def no_args + NoArgsMatcher.new + end + + # :call-seq: + # object.should_receive(:message).with(duck_type(:hello)) + # object.should_receive(:message).with(duck_type(:hello, :goodbye)) + # + # Passes if the argument responds to the specified messages. + # + # == Examples + # + # array = [] + # display = mock('display') + # display.should_receive(:present_names).with(duck_type(:length, :each)) + # => passes + def duck_type(*args) + DuckTypeMatcher.new(*args) + end + + # :call-seq: + # object.should_receive(:message).with(boolean()) + # + # Passes if the argument is boolean. + def boolean + BooleanMatcher.new(nil) + end + + # :call-seq: + # object.should_receive(:message).with(hash_including(:key => val)) + # object.should_receive(:message).with(hash_including(:key)) + # object.should_receive(:message).with(hash_including(:key, :key2 => val2)) + # Passes if the argument is a hash that includes the specified key(s) or key/value + # pairs. If the hash includes other keys, it will still pass. + def hash_including(*args) + HashIncludingMatcher.new(anythingize_lonely_keys(*args)) + end + + # :call-seq: + # object.should_receive(:message).with(hash_not_including(:key => val)) + # object.should_receive(:message).with(hash_not_including(:key)) + # object.should_receive(:message).with(hash_not_including(:key, :key2 => :val2)) + # + # Passes if the argument is a hash that doesn't include the specified key(s) or key/value + def hash_not_including(*args) + HashNotIncludingMatcher.new(anythingize_lonely_keys(*args)) + end + + # Passes if arg.instance_of?(klass) + def instance_of(klass) + InstanceOf.new(klass) + end + + alias_method :an_instance_of, :instance_of + + # Passes if arg.kind_of?(klass) + def kind_of(klass) + KindOf.new(klass) + end + + alias_method :a_kind_of, :kind_of + + private + + def anythingize_lonely_keys(*args) + hash = args.last.class == Hash ? args.delete_at(-1) : {} + args.each { | arg | hash[arg] = anything } + hash + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/error_generator.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/error_generator.rb new file mode 100644 index 00000000..791e566c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/error_generator.rb @@ -0,0 +1,81 @@ +module Spec + module Mocks + class ErrorGenerator + attr_writer :opts + + def initialize(target, name) + @target = target + @name = name + end + + def opts + @opts ||= {} + end + + def raise_unexpected_message_error(sym, *args) + __raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}" + end + + def raise_unexpected_message_args_error(expectation, *args) + expected_args = format_args(*expectation.expected_args) + actual_args = args.empty? ? "(no args)" : format_args(*args) + __raise "#{intro} expected #{expectation.sym.inspect} with #{expected_args} but received it with #{actual_args}" + end + + def raise_expectation_error(sym, expected_received_count, actual_received_count, *args) + __raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}" + end + + def raise_out_of_order_error(sym) + __raise "#{intro} received :#{sym} out of order" + end + + def raise_block_failed_error(sym, detail) + __raise "#{intro} received :#{sym} but passed block failed with: #{detail}" + end + + def raise_missing_block_error(args_to_yield) + __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed" + end + + def raise_wrong_arity_error(args_to_yield, arity) + __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}" + end + + private + + def intro + @name ? "Mock '#{@name}'" : @target.class == Class ? "<#{@target.inspect} (class)>" : (@target.nil? ? "nil" : @target) + end + + def __raise(message) + message = opts[:message] unless opts[:message].nil? + Kernel::raise(Spec::Mocks::MockExpectationError, message) + end + + def arg_message(*args) + " with " + format_args(*args) + end + + def format_args(*args) + args.empty? ? "(no args)" : "(" + arg_list(*args) + ")" + end + + def arg_list(*args) + args.collect {|arg| arg.respond_to?(:description) ? arg.description : arg.inspect}.join(", ") + end + + def count_message(count) + return "at least #{pretty_print(count.abs)}" if count < 0 + return pretty_print(count) + end + + def pretty_print(count) + return "once" if count == 1 + return "twice" if count == 2 + return "#{count} times" + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/errors.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/errors.rb new file mode 100644 index 00000000..560b66a9 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/errors.rb @@ -0,0 +1,10 @@ +module Spec + module Mocks + class MockExpectationError < Exception + end + + class AmbiguousReturnError < StandardError + end + end +end + diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/extensions.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/extensions.rb new file mode 100644 index 00000000..6fd51a27 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/extensions.rb @@ -0,0 +1 @@ +require 'spec/mocks/extensions/object' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/extensions/object.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/extensions/object.rb new file mode 100644 index 00000000..4b753106 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/extensions/object.rb @@ -0,0 +1,3 @@ +class Object + include Spec::Mocks::Methods +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/framework.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/framework.rb new file mode 100644 index 00000000..4758bc84 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/framework.rb @@ -0,0 +1,15 @@ +# Require everything except the global extensions of class and object. This +# supports wrapping rspec's mocking functionality without invading every +# object in the system. + +require 'spec/mocks/methods' +require 'spec/mocks/argument_matchers' +require 'spec/mocks/spec_methods' +require 'spec/mocks/proxy' +require 'spec/mocks/mock' +require 'spec/mocks/argument_expectation' +require 'spec/mocks/message_expectation' +require 'spec/mocks/order_group' +require 'spec/mocks/errors' +require 'spec/mocks/error_generator' +require 'spec/mocks/space' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/message_expectation.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/message_expectation.rb new file mode 100644 index 00000000..5a57a0ac --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/message_expectation.rb @@ -0,0 +1,326 @@ +module Spec + module Mocks + + class BaseExpectation + attr_reader :sym + attr_writer :expected_received_count, :method_block, :expected_from + protected :expected_received_count=, :method_block=, :expected_from= + attr_accessor :error_generator + protected :error_generator, :error_generator= + + def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={}, &implementation) + @error_generator = error_generator + @error_generator.opts = opts + @expected_from = expected_from + @sym = sym + @method_block = method_block + @return_block = nil + @actual_received_count = 0 + @expected_received_count = expected_received_count + @args_expectation = ArgumentExpectation.new([ArgumentMatchers::AnyArgsMatcher.new]) + @consecutive = false + @exception_to_raise = nil + @symbol_to_throw = nil + @order_group = expectation_ordering + @at_least = nil + @at_most = nil + @args_to_yield = [] + @failed_fast = nil + @args_to_yield_were_cloned = false + @return_block = implementation + end + + def build_child(expected_from, method_block, expected_received_count, opts={}) + child = clone + child.expected_from = expected_from + child.method_block = method_block + child.expected_received_count = expected_received_count + child.clear_actual_received_count! + new_gen = error_generator.clone + new_gen.opts = opts + child.error_generator = new_gen + child.clone_args_to_yield @args_to_yield + child + end + + def expected_args + @args_expectation.args + end + + def and_return(*values, &return_block) + Kernel::raise AmbiguousReturnError unless @method_block.nil? + case values.size + when 0 then value = nil + when 1 then value = values[0] + else + value = values + @consecutive = true + @expected_received_count = values.size if !ignoring_args? && + @expected_received_count < values.size + end + @return_block = block_given? ? return_block : lambda { value } + end + + # :call-seq: + # and_raise() + # and_raise(Exception) #any exception class + # and_raise(exception) #any exception object + # + # == Warning + # + # When you pass an exception class, the MessageExpectation will + # raise an instance of it, creating it with +new+. If the exception + # class initializer requires any parameters, you must pass in an + # instance and not the class. + def and_raise(exception=Exception) + @exception_to_raise = exception + end + + def and_throw(symbol) + @symbol_to_throw = symbol + end + + def and_yield(*args) + if @args_to_yield_were_cloned + @args_to_yield.clear + @args_to_yield_were_cloned = false + end + + @args_to_yield << args + self + end + + def matches(sym, args) + @sym == sym and @args_expectation.args_match?(args) + end + + def invoke(args, block) + if @expected_received_count == 0 + @failed_fast = true + @actual_received_count += 1 + @error_generator.raise_expectation_error @sym, @expected_received_count, @actual_received_count, *args + end + + @order_group.handle_order_constraint self + + begin + Kernel::raise @exception_to_raise unless @exception_to_raise.nil? + Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil? + + + if !@method_block.nil? + default_return_val = invoke_method_block(args) + elsif @args_to_yield.size > 0 + default_return_val = invoke_with_yield(block) + else + default_return_val = nil + end + + if @consecutive + return invoke_consecutive_return_block(args, block) + elsif @return_block + return invoke_return_block(args, block) + else + return default_return_val + end + ensure + @actual_received_count += 1 + end + end + + def called_max_times? + @expected_received_count != :any && @expected_received_count > 0 && + @actual_received_count >= @expected_received_count + end + + protected + + def invoke_method_block(args) + begin + @method_block.call(*args) + rescue => detail + @error_generator.raise_block_failed_error @sym, detail.message + end + end + + def invoke_with_yield(block) + if block.nil? + @error_generator.raise_missing_block_error @args_to_yield + end + value = nil + @args_to_yield.each do |args_to_yield_this_time| + if block.arity > -1 && args_to_yield_this_time.length != block.arity + @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity + end + value = block.call(*args_to_yield_this_time) + end + value + end + + def invoke_consecutive_return_block(args, block) + value = invoke_return_block(args, block) + index = [@actual_received_count, value.size-1].min + value[index] + end + + def invoke_return_block(args, block) + args << block unless block.nil? + # Ruby 1.9 - when we set @return_block to return values + # regardless of arguments, any arguments will result in + # a "wrong number of arguments" error + @return_block.arity == 0 ? @return_block.call : @return_block.call(*args) + end + + def clone_args_to_yield(args) + @args_to_yield = args.clone + @args_to_yield_were_cloned = true + end + + def failed_fast? + @failed_fast + end + end + + class MessageExpectation < BaseExpectation + + def matches_name_but_not_args(sym, args) + @sym == sym and not @args_expectation.args_match?(args) + end + + def verify_messages_received + return if expected_messages_received? || failed_fast? + + generate_error + rescue Spec::Mocks::MockExpectationError => error + error.backtrace.insert(0, @expected_from) + Kernel::raise error + end + + def expected_messages_received? + ignoring_args? || matches_exact_count? || + matches_at_least_count? || matches_at_most_count? + end + + def ignoring_args? + @expected_received_count == :any + end + + def matches_at_least_count? + @at_least && @actual_received_count >= @expected_received_count + end + + def matches_at_most_count? + @at_most && @actual_received_count <= @expected_received_count + end + + def matches_exact_count? + @expected_received_count == @actual_received_count + end + + def similar_messages + @similar_messages ||= [] + end + + def advise(args, block) + similar_messages << args + end + + def generate_error + if similar_messages.empty? + @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args) + else + @error_generator.raise_unexpected_message_args_error(self, *@similar_messages) + end + end + + def with(*args, &block) + @args_expectation = ArgumentExpectation.new(args, &block) + self + end + + def exactly(n) + set_expected_received_count :exactly, n + self + end + + def at_least(n) + set_expected_received_count :at_least, n + self + end + + def at_most(n) + set_expected_received_count :at_most, n + self + end + + def times(&block) + @method_block = block if block + self + end + + def any_number_of_times(&block) + @method_block = block if block + @expected_received_count = :any + self + end + + def never + @expected_received_count = 0 + self + end + + def once(&block) + @method_block = block if block + @expected_received_count = 1 + self + end + + def twice(&block) + @method_block = block if block + @expected_received_count = 2 + self + end + + def ordered(&block) + @method_block = block if block + @order_group.register(self) + @ordered = true + self + end + + def negative_expectation_for?(sym) + return false + end + + protected + def set_expected_received_count(relativity, n) + @at_least = (relativity == :at_least) + @at_most = (relativity == :at_most) + @expected_received_count = case n + when Numeric + n + when :once + 1 + when :twice + 2 + end + end + + def clear_actual_received_count! + @actual_received_count = 0 + end + + end + + class NegativeMessageExpectation < MessageExpectation + def initialize(message, expectation_ordering, expected_from, sym, method_block) + super(message, expectation_ordering, expected_from, sym, method_block, 0) + end + + def negative_expectation_for?(sym) + return @sym == sym + end + end + + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/methods.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/methods.rb new file mode 100644 index 00000000..93ee3306 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/methods.rb @@ -0,0 +1,63 @@ +module Spec + module Mocks + module Methods + def should_receive(sym, opts={}, &block) + __mock_proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], sym.to_sym, opts, &block) + end + + def should_not_receive(sym, &block) + __mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block) + end + + def stub!(sym_or_hash, opts={}, &block) + if Hash === sym_or_hash + sym_or_hash.each {|method, value| stub!(method).and_return value } + else + __mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts, &block) + end + end + + alias_method :stub, :stub! + + def stub_chain(*methods) + if methods.length > 1 + next_in_chain = Object.new + stub!(methods.shift) {next_in_chain} + next_in_chain.stub_chain(*methods) + else + stub!(methods.shift) + end + end + + def received_message?(sym, *args, &block) #:nodoc: + __mock_proxy.received_message?(sym.to_sym, *args, &block) + end + + def rspec_verify #:nodoc: + __mock_proxy.verify + end + + def rspec_reset #:nodoc: + __mock_proxy.reset + end + + def as_null_object + __mock_proxy.as_null_object + end + + def null_object? + __mock_proxy.null_object? + end + + private + + def __mock_proxy + if Mock === self + @mock_proxy ||= Proxy.new(self, @name, @options) + else + @mock_proxy ||= Proxy.new(self) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/mock.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/mock.rb new file mode 100644 index 00000000..0293f7b6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/mock.rb @@ -0,0 +1,65 @@ +module Spec + module Mocks + class Mock + include Methods + + # Creates a new mock with a +name+ (that will be used in error messages + # only) == Options: + # * :null_object - if true, the mock object acts as a forgiving + # null object allowing any message to be sent to it. + def initialize(name='mock', stubs_and_options={}) + if name.is_a?(Hash) && stubs_and_options.empty? + stubs_and_options = name + build_name_from_options stubs_and_options + else + @name = name + end + @options = parse_options(stubs_and_options) + assign_stubs(stubs_and_options) + end + + # This allows for comparing the mock to other objects that proxy such as + # ActiveRecords belongs_to proxy objects. By making the other object run + # the comparison, we're sure the call gets delegated to the proxy + # target. + def ==(other) + other == __mock_proxy + end + + def inspect + "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>" + end + + def to_s + inspect.gsub('<','[').gsub('>',']') + end + + private + + def method_missing(sym, *args, &block) + __mock_proxy.record_message_received(sym, args, block) + begin + return self if __mock_proxy.null_object? + super(sym, *args, &block) + rescue NameError + __mock_proxy.raise_unexpected_message_error sym, *args + end + end + + def parse_options(options) + options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {} + end + + def assign_stubs(stubs) + stubs.each_pair do |message, response| + stub!(message).and_return(response) + end + end + + def build_name_from_options(options) + vals = options.inject([]) {|coll, pair| coll << "#{pair.first}: #{pair.last.inspect}"} + @name = '{' + vals.join(', ') + '}' + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/order_group.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/order_group.rb new file mode 100644 index 00000000..9983207e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/order_group.rb @@ -0,0 +1,29 @@ +module Spec + module Mocks + class OrderGroup + def initialize error_generator + @error_generator = error_generator + @ordering = Array.new + end + + def register(expectation) + @ordering << expectation + end + + def ready_for?(expectation) + return @ordering.first == expectation + end + + def consume + @ordering.shift + end + + def handle_order_constraint expectation + return unless @ordering.include? expectation + return consume if ready_for?(expectation) + @error_generator.raise_out_of_order_error expectation.sym + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/proxy.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/proxy.rb new file mode 100644 index 00000000..c21ca678 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/proxy.rb @@ -0,0 +1,230 @@ +module Spec + module Mocks + class Proxy + DEFAULT_OPTIONS = { + :null_object => false, + } + + @@warn_about_expectations_on_nil = true + + def self.allow_message_expectations_on_nil + @@warn_about_expectations_on_nil = false + + # ensure nil.rspec_verify is called even if an expectation is not set in the example + # otherwise the allowance would effect subsequent examples + $rspec_mocks.add(nil) unless $rspec_mocks.nil? + end + + def initialize(target, name=nil, options={}) + @target = target + @name = name + @error_generator = ErrorGenerator.new target, name + @expectation_ordering = OrderGroup.new @error_generator + @expectations = [] + @messages_received = [] + @stubs = [] + @proxied_methods = [] + @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS + @already_proxied_respond_to = false + end + + def null_object? + @options[:null_object] + end + + def as_null_object + @options[:null_object] = true + @target + end + + def add_message_expectation(expected_from, sym, opts={}, &block) + __add sym + warn_if_nil_class sym + if existing_stub = @stubs.detect {|s| s.sym == sym } + expectation = existing_stub.build_child(expected_from, block_given?? block : nil, 1, opts) + else + expectation = MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts) + end + @expectations << expectation + @expectations.last + end + + def add_negative_message_expectation(expected_from, sym, &block) + __add sym + warn_if_nil_class sym + @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil) + @expectations.last + end + + def add_stub(expected_from, sym, opts={}, &implementation) + __add sym + @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts, &implementation) + @stubs.first + end + + def verify #:nodoc: + verify_expectations + ensure + reset + end + + def reset + clear_expectations + clear_stubs + reset_proxied_methods + clear_proxied_methods + reset_nil_expectations_warning + end + + def received_message?(sym, *args, &block) + @messages_received.any? {|array| array == [sym, args, block]} + end + + def has_negative_expectation?(sym) + @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)} + end + + def record_message_received(sym, args, block) + @messages_received << [sym, args, block] + end + + def message_received(sym, *args, &block) + expectation = find_matching_expectation(sym, *args) + stub = find_matching_method_stub(sym, *args) + + if (stub && expectation && expectation.called_max_times?) || (stub && !expectation) + if expectation = find_almost_matching_expectation(sym, *args) + expectation.advise(args, block) unless expectation.expected_messages_received? + end + stub.invoke(args, block) + elsif expectation + expectation.invoke(args, block) + elsif expectation = find_almost_matching_expectation(sym, *args) + expectation.advise(args, block) if null_object? unless expectation.expected_messages_received? + raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?) + else + @target.__send__ :method_missing, sym, *args, &block + end + end + + def raise_unexpected_message_args_error(expectation, *args) + @error_generator.raise_unexpected_message_args_error expectation, *args + end + + def raise_unexpected_message_error(sym, *args) + @error_generator.raise_unexpected_message_error sym, *args + end + + private + + def __add(sym) + $rspec_mocks.add(@target) unless $rspec_mocks.nil? + define_expected_method(sym) + end + + def warn_if_nil_class(sym) + if proxy_for_nil_class? & @@warn_about_expectations_on_nil + Kernel.warn("An expectation of :#{sym} was set on nil. Called from #{caller[2]}. Use allow_message_expectations_on_nil to disable warnings.") + end + end + + def define_expected_method(sym) + unless @proxied_methods.include?(sym) + visibility_string = "#{visibility(sym)} :#{sym}" + if target_responds_to?(sym) + munged_sym = munge(sym) + target_metaclass.instance_eval do + alias_method munged_sym, sym if method_defined?(sym) + end + @proxied_methods << sym + end + target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__) + def #{sym}(*args, &block) + __mock_proxy.message_received :#{sym}, *args, &block + end + #{visibility_string} + EOF + end + end + + def target_responds_to?(sym) + return @target.__send__(munge(:respond_to?),sym) if @already_proxied_respond_to + return @already_proxied_respond_to = true if sym == :respond_to? + return @target.respond_to?(sym, true) + end + + def visibility(sym) + if Mock === @target + 'public' + elsif target_metaclass.private_method_defined?(sym) + 'private' + elsif target_metaclass.protected_method_defined?(sym) + 'protected' + else + 'public' + end + end + + def munge(sym) + "proxied_by_rspec__#{sym}" + end + + def clear_expectations + @expectations.clear + end + + def clear_stubs + @stubs.clear + end + + def clear_proxied_methods + @proxied_methods.clear + end + + def target_metaclass + class << @target; self; end + end + + def verify_expectations + @expectations.each do |expectation| + expectation.verify_messages_received + end + end + + def reset_proxied_methods + @proxied_methods.each do |sym| + munged_sym = munge(sym) + target_metaclass.instance_eval do + remove_method sym + if method_defined?(munged_sym) + alias_method sym, munged_sym + remove_method munged_sym + end + end + end + end + + def proxy_for_nil_class? + @target.nil? + end + + def reset_nil_expectations_warning + @@warn_about_expectations_on_nil = true if proxy_for_nil_class? + end + + def find_matching_expectation(sym, *args) + @expectations.find {|expectation| expectation.matches(sym, args) && !expectation.called_max_times?} || + @expectations.find {|expectation| expectation.matches(sym, args)} + end + + def find_almost_matching_expectation(sym, *args) + @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)} + end + + def find_matching_method_stub(sym, *args) + @stubs.find {|stub| stub.matches(sym, args)} + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/space.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/space.rb new file mode 100644 index 00000000..3e13224c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/space.rb @@ -0,0 +1,28 @@ +module Spec + module Mocks + class Space + def add(obj) + mocks << obj unless mocks.detect {|m| m.equal? obj} + end + + def verify_all + mocks.each do |mock| + mock.rspec_verify + end + end + + def reset_all + mocks.each do |mock| + mock.rspec_reset + end + mocks.clear + end + + private + + def mocks + @mocks ||= [] + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/spec_methods.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/spec_methods.rb new file mode 100644 index 00000000..a63dce90 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/mocks/spec_methods.rb @@ -0,0 +1,55 @@ +module Spec + module Mocks + module ExampleMethods + include Spec::Mocks::ArgumentMatchers + + # Shortcut for creating an instance of Spec::Mocks::Mock. + # + # +name+ is used for failure reporting, so you should use the + # role that the mock is playing in the example. + # + # +stubs_and_options+ lets you assign options and stub values + # at the same time. The only option available is :null_object. + # Anything else is treated as a stub value. + # + # == Examples + # + # stub_thing = mock("thing", :a => "A") + # stub_thing.a == "A" => true + # + # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com") + # stub_person.name => "Joe" + # stub_person.email => "joe@domain.com" + def mock(*args) + Spec::Mocks::Mock.new(*args) + end + + alias :stub :mock + + # DEPRECATED - use mock('name').as_null_object instead + # + # Shortcut for creating a mock object that will return itself in response + # to any message it receives that it hasn't been explicitly instructed + # to respond to. + def stub_everything(name = 'stub') + Spec.warn(<<-WARNING) + +DEPRECATION: stub_everything('#{name}') is deprecated and will be removed +from a future version of rspec. Please use mock('#{name}').as_null_object +or stub('#{name}').as_null_object instead. + +WARNING + mock(name, :null_object => true) + end + + # Disables warning messages about expectations being set on nil. + # + # By default warning messages are issued when expectations are set on nil. This is to + # prevent false-positives and to catch potential bugs early on. + def allow_message_expectations_on_nil + Proxy.allow_message_expectations_on_nil + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/rake/spectask.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/rake/spectask.rb new file mode 100644 index 00000000..d0a0aa9c --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/rake/spectask.rb @@ -0,0 +1,230 @@ +#!/usr/bin/env ruby + +# Define a task library for running RSpec contexts. + +require 'rake' +require 'rake/tasklib' + +module Spec + module Rake + + # A Rake task that runs a set of specs. + # + # Example: + # + # Spec::Rake::SpecTask.new do |t| + # t.warning = true + # t.rcov = true + # end + # + # This will create a task that can be run with: + # + # rake spec + # + # If rake is invoked with a "SPEC=filename" command line option, + # then the list of spec files will be overridden to include only the + # filename specified on the command line. This provides an easy way + # to run just one spec. + # + # If rake is invoked with a "SPEC_OPTS=options" command line option, + # then the given options will override the value of the +spec_opts+ + # attribute. + # + # If rake is invoked with a "RCOV_OPTS=options" command line option, + # then the given options will override the value of the +rcov_opts+ + # attribute. + # + # Examples: + # + # rake spec # run specs normally + # rake spec SPEC=just_one_file.rb # run just one spec file. + # rake spec SPEC_OPTS="--diff" # enable diffing + # rake spec RCOV_OPTS="--aggregate myfile.txt" # see rcov --help for details + # + # Each attribute of this task may be a proc. This allows for lazy evaluation, + # which is sometimes handy if you want to defer the evaluation of an attribute value + # until the task is run (as opposed to when it is defined). + # + # This task can also be used to run existing Test::Unit tests and get RSpec + # output, for example like this: + # + # require 'spec/rake/spectask' + # Spec::Rake::SpecTask.new do |t| + # t.ruby_opts = ['-rtest/unit'] + # t.spec_files = FileList['test/**/*_test.rb'] + # end + # + class SpecTask < ::Rake::TaskLib + def self.attr_accessor(*names) + super(*names) + names.each do |name| + module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs + end + end + + # Name of spec task. (default is :spec) + attr_accessor :name + + # Array of directories to be added to $LOAD_PATH before running the + # specs. Defaults to [''] + attr_accessor :libs + + # If true, requests that the specs be run with the warning flag set. + # E.g. warning=true implies "ruby -w" used to run the specs. Defaults to false. + attr_accessor :warning + + # Glob pattern to match spec files. (default is 'spec/**/*_spec.rb') + # Setting the SPEC environment variable overrides this. + attr_accessor :pattern + + # Array of commandline options to pass to RSpec. Defaults to []. + # Setting the SPEC_OPTS environment variable overrides this. + attr_accessor :spec_opts + + # Whether or not to use RCov (default is false) + # See http://eigenclass.org/hiki.rb?rcov + attr_accessor :rcov + + # Array of commandline options to pass to RCov. Defaults to ['--exclude', 'lib\/spec,bin\/spec']. + # Ignored if rcov=false + # Setting the RCOV_OPTS environment variable overrides this. + attr_accessor :rcov_opts + + # Directory where the RCov report is written. Defaults to "coverage" + # Ignored if rcov=false + attr_accessor :rcov_dir + + # Array of commandline options to pass to ruby. Defaults to []. + attr_accessor :ruby_opts + + # Whether or not to fail Rake when an error occurs (typically when specs fail). + # Defaults to true. + attr_accessor :fail_on_error + + # A message to print to stderr when there are failures. + attr_accessor :failure_message + + # Where RSpec's output is written. Defaults to $stdout. + # DEPRECATED. Use --format FORMAT:WHERE in spec_opts. + attr_accessor :out + + # Explicitly define the list of spec files to be included in a + # spec. +spec_files+ is expected to be an array of file names (a + # FileList is acceptable). If both +pattern+ and +spec_files+ are + # used, then the list of spec files is the union of the two. + # Setting the SPEC environment variable overrides this. + attr_accessor :spec_files + + # Use verbose output. If this is set to true, the task will print + # the executed spec command to stdout. Defaults to false. + attr_accessor :verbose + + # Explicitly define the path to the ruby binary, or its proxy (e.g. multiruby) + attr_accessor :ruby_cmd + + # Defines a new task, using the name +name+. + def initialize(name=:spec) + @name = name + @libs = [File.expand_path(File.dirname(__FILE__) + '/../../../lib')] + @pattern = nil + @spec_files = nil + @spec_opts = [] + @warning = false + @ruby_opts = [] + @fail_on_error = true + @rcov = false + @rcov_opts = ['--exclude', 'lib\/spec,bin\/spec,config\/boot.rb'] + @rcov_dir = "coverage" + + yield self if block_given? + @pattern = 'spec/**/*_spec.rb' if pattern.nil? && spec_files.nil? + define + end + + def define # :nodoc: + spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/spec') + + lib_path = libs.join(File::PATH_SEPARATOR) + actual_name = Hash === name ? name.keys.first : name + unless ::Rake.application.last_comment + desc "Run specs" + (rcov ? " using RCov" : "") + end + task name do + RakeFileUtils.verbose(verbose) do + unless spec_file_list.empty? + # ruby [ruby_opts] -Ilib -S rcov [rcov_opts] bin/spec -- examples [spec_opts] + # or + # ruby [ruby_opts] -Ilib bin/spec examples [spec_opts] + cmd_parts = [ruby_cmd || RUBY] + cmd_parts += ruby_opts + cmd_parts << %[-I"#{lib_path}"] + cmd_parts << "-S rcov" if rcov + cmd_parts << "-w" if warning + cmd_parts << rcov_option_list + cmd_parts << %[-o "#{rcov_dir}"] if rcov + cmd_parts << %["#{spec_script}"] + cmd_parts << "--" if rcov + cmd_parts += spec_file_list.collect { |fn| %["#{fn}"] } + cmd_parts << spec_option_list + if out + cmd_parts << %[> "#{out}"] + STDERR.puts "The Spec::Rake::SpecTask#out attribute is DEPRECATED and will be removed in a future version. Use --format FORMAT:WHERE instead." + end + cmd = cmd_parts.join(" ") + puts cmd if verbose + unless system(cmd) + STDERR.puts failure_message if failure_message + raise("Command #{cmd} failed") if fail_on_error + end + end + end + end + + if rcov + desc "Remove rcov products for #{actual_name}" + task paste("clobber_", actual_name) do + rm_r rcov_dir rescue nil + end + + clobber_task = paste("clobber_", actual_name) + task :clobber => [clobber_task] + + task actual_name => clobber_task + end + self + end + + def rcov_option_list # :nodoc: + if rcov + ENV['RCOV_OPTS'] || rcov_opts.join(" ") || "" + else + "" + end + end + + def spec_option_list # :nodoc: + STDERR.puts "RSPECOPTS is DEPRECATED and will be removed in a future version. Use SPEC_OPTS instead." if ENV['RSPECOPTS'] + ENV['SPEC_OPTS'] || ENV['RSPECOPTS'] || spec_opts.join(" ") || "" + end + + def evaluate(o) # :nodoc: + case o + when Proc then o.call + else o + end + end + + def spec_file_list # :nodoc: + if ENV['SPEC'] + FileList[ ENV['SPEC'] ] + else + result = [] + result += spec_files.to_a if spec_files + result += FileList[ pattern ].to_a if pattern + FileList[result] + end + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/rake/verify_rcov.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/rake/verify_rcov.rb new file mode 100644 index 00000000..199bd854 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/rake/verify_rcov.rb @@ -0,0 +1,52 @@ +module RCov + # A task that can verify that the RCov coverage doesn't + # drop below a certain threshold. It should be run after + # running Spec::Rake::SpecTask. + class VerifyTask < Rake::TaskLib + # Name of the task. Defaults to :verify_rcov + attr_accessor :name + + # Path to the index.html file generated by RCov, which + # is the file containing the total coverage. + # Defaults to 'coverage/index.html' + attr_accessor :index_html + + # Whether or not to output details. Defaults to true. + attr_accessor :verbose + + # The threshold value (in percent) for coverage. If the + # actual coverage is not equal to this value, the task will raise an + # exception. + attr_accessor :threshold + + # Require the threshold value be met exactly. This is the default. + attr_accessor :require_exact_threshold + + def initialize(name=:verify_rcov) + @name = name + @index_html = 'coverage/index.html' + @verbose = true + @require_exact_threshold = true + yield self if block_given? + raise "Threshold must be set" if @threshold.nil? + define + end + + def define + desc "Verify that rcov coverage is at least #{threshold}%" + task @name do + total_coverage = 0 + + File.open(index_html).each_line do |line| + if line =~ /\s*(\d+\.\d+)%\s*<\/tt>/ + total_coverage = $1.to_f + break + end + end + puts "Coverage: #{total_coverage}% (threshold: #{threshold}%)" if verbose + raise "Coverage must be at least #{threshold}% but was #{total_coverage}%" if total_coverage < threshold + raise "Coverage has increased above the threshold of #{threshold}% to #{total_coverage}%. You should update your threshold value." if (total_coverage > threshold) and require_exact_threshold + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/ruby.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/ruby.rb new file mode 100644 index 00000000..863877c7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/ruby.rb @@ -0,0 +1,9 @@ +module Spec + module Ruby + class << self + def version + RUBY_VERSION + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner.rb new file mode 100644 index 00000000..519b536e --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner.rb @@ -0,0 +1,66 @@ +require 'spec/runner/configuration' +require 'spec/runner/options' +require 'spec/runner/option_parser' +require 'spec/runner/example_group_runner' +require 'spec/runner/command_line' +require 'spec/runner/drb_command_line' +require 'spec/runner/backtrace_tweaker' +require 'spec/runner/reporter' +require 'spec/runner/line_number_query' +require 'spec/runner/class_and_arguments_parser' +require 'spec/runner/extensions/kernel' + +module Spec + module Runner + + class ExampleGroupCreationListener + def register_example_group(klass) + Spec::Runner.options.add_example_group klass + end + end + + Spec::Example::ExampleGroupFactory.example_group_creation_listeners << ExampleGroupCreationListener.new + + class << self + def configuration # :nodoc: + @configuration ||= Spec::Runner::Configuration.new + end + + # Use this to configure various configurable aspects of + # RSpec: + # + # Spec::Runner.configure do |configuration| + # # Configure RSpec here + # end + # + # The yielded configuration object is a + # Spec::Runner::Configuration instance. See its RDoc + # for details about what you can do with it. + # + def configure + yield configuration + end + + def autorun # :nodoc: + at_exit {exit run unless $!} + end + + def options # :nodoc: + @options ||= begin + parser = ::Spec::Runner::OptionParser.new($stderr, $stdout) + parser.order!(ARGV) + parser.options + end + end + + def use options + @options = options + end + + def run + options.examples_run? || options.run_examples + end + + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/backtrace_tweaker.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/backtrace_tweaker.rb new file mode 100644 index 00000000..5f8914fd --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/backtrace_tweaker.rb @@ -0,0 +1,58 @@ +module Spec + module Runner + class BacktraceTweaker + def clean_up_double_slashes(line) + line.gsub!('//','/') + end + end + + class NoisyBacktraceTweaker < BacktraceTweaker + def tweak_backtrace(error) + return if error.backtrace.nil? + tweaked = error.backtrace.collect do |line| + clean_up_double_slashes(line) + line + end + error.set_backtrace(tweaked) + end + end + + # Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace + class QuietBacktraceTweaker < BacktraceTweaker + unless defined?(IGNORE_PATTERNS) + root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..')) + spec_files = Dir["#{root_dir}/lib/*"].map do |path| + subpath = path[root_dir.length..-1] + /#{subpath}/ + end + IGNORE_PATTERNS = spec_files + [ + /\/lib\/ruby\//, + /bin\/spec:/, + /bin\/rcov:/, + /lib\/rspec-rails/, + /vendor\/rails/, + # TextMate's Ruby and RSpec plugins + /Ruby\.tmbundle\/Support\/tmruby.rb:/, + /RSpec\.tmbundle\/Support\/lib/, + /temp_textmate\./, + /mock_frameworks\/rspec/, + /spec_server/ + ] + end + + def tweak_backtrace(error) + return if error.backtrace.nil? + tweaked = error.backtrace.collect do |message| + clean_up_double_slashes(message) + kept_lines = message.split("\n").select do |line| + IGNORE_PATTERNS.each do |ignore| + break if line =~ ignore + end + end + kept_lines.empty?? nil : kept_lines.join("\n") + end + error.set_backtrace(tweaked.select {|line| line}) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/class_and_arguments_parser.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/class_and_arguments_parser.rb new file mode 100644 index 00000000..a49ade26 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/class_and_arguments_parser.rb @@ -0,0 +1,14 @@ +module Spec + module Runner + class ClassAndArgumentsParser + def self.parse(s) + if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/ + arg = $2 == "" ? nil : $2 + [$1, arg] + else + raise "Couldn't parse #{s.inspect}" + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/command_line.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/command_line.rb new file mode 100644 index 00000000..35a7e315 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/command_line.rb @@ -0,0 +1,15 @@ +require 'spec/runner/option_parser' + +module Spec + module Runner + class CommandLine + def self.run(tmp_options=Spec::Runner.options) + orig_options = Spec::Runner.options + Spec::Runner.use tmp_options + tmp_options.run_examples + ensure + Spec::Runner.use orig_options + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/configuration.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/configuration.rb new file mode 100644 index 00000000..abe166d5 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/configuration.rb @@ -0,0 +1,177 @@ +module Spec + module Runner + class Configuration + include Spec::Example::ArgsAndOptions + + # Chooses what mock framework to use. Example: + # + # Spec::Runner.configure do |config| + # config.mock_with :rspec, :mocha, :flexmock, or :rr + # end + # + # To use any other mock framework, you'll have to provide your own + # adapter. This is simply a module that responds to the following + # methods: + # + # setup_mocks_for_rspec + # verify_mocks_for_rspec + # teardown_mocks_for_rspec. + # + # These are your hooks into the lifecycle of a given example. RSpec will + # call setup_mocks_for_rspec before running anything else in each + # Example. After executing the #after methods, RSpec will then call + # verify_mocks_for_rspec and teardown_mocks_for_rspec (this is + # guaranteed to run even if there are failures in + # verify_mocks_for_rspec). + # + # Once you've defined this module, you can pass that to mock_with: + # + # Spec::Runner.configure do |config| + # config.mock_with MyMockFrameworkAdapter + # end + # + def mock_with(mock_framework) + @mock_framework = case mock_framework + when Symbol + mock_framework_path(mock_framework.to_s) + else + mock_framework + end + end + + def mock_framework # :nodoc: + @mock_framework ||= mock_framework_path("rspec") + end + + # :call-seq: + # include(Some::Helpers) + # include(Some::Helpers, More::Helpers) + # include(My::Helpers, :type => :key) + # + # Declares modules to be included in multiple example groups + # (describe blocks). With no :type, the modules listed + # will be included in all example groups. + # + # Use :type to restrict + # the inclusion to a subset of example groups. The value assigned to + # :type should be a key that maps to a class that is either a + # subclass of Spec::Example::ExampleGroup or extends + # Spec::Example::ExampleGroupMethods and includes + # Spec::Example::ExampleMethods. + # + # For example, the rspec-rails gem/plugin extends Test::Unit::TestCase + # with Spec::Example::ExampleGroupMethods and includes + # Spec::Example::ExampleMethods in it. So if you have a module of helper + # methods for controller examples, you could do this: + # + # config.include(ControllerExampleHelpers, :type => :controller) + # + # Only example groups that have that type will get the modules included: + # + # describe Account, :type => :model do + # # Will *not* include ControllerExampleHelpers + # end + # + # describe AccountsController, :type => :controller do + # # *Will* include ControllerExampleHelpers + # end + # + def include(*modules_and_options) + include_or_extend(:include, *modules_and_options) + end + + # :call-seq: + # extend(Some::Helpers) + # extend(Some::Helpers, More::Helpers) + # extend(My::Helpers, :type => :key) + # + # Works just like #include, but extends the example groups + # with the modules rather than including them. + def extend(*modules_and_options) + include_or_extend(:extend, *modules_and_options) + end + + # Appends a global before block to all example groups. + # scope can be any of :each (default), :all, or + # :suite. When :each, the block is executed before each + # example. When :all, the block is executed once per example + # group, before any of its examples are run. When :suite the + # block is run once before the entire suite is run. + def append_before(scope = :each, options={}, &proc) + add_callback(:append_before, scope, options, &proc) + end + alias_method :before, :append_before + + # Prepends a global before block to all example groups. + # + # See append_before for scoping semantics. + def prepend_before(scope = :each, options={}, &proc) + add_callback(:prepend_before, scope, options, &proc) + end + + # Prepends a global after block to all example groups. + # + # See append_before for scoping semantics. + def prepend_after(scope = :each, options={}, &proc) + add_callback(:prepend_after, scope, options, &proc) + end + alias_method :after, :prepend_after + + # Appends a global after block to all example groups. + # + # See append_before for scoping semantics. + def append_after(scope = :each, options={}, &proc) + add_callback(:append_after, scope, options, &proc) + end + + # DEPRECATED - use Spec::Matchers::DSL instead + # + # Defines global predicate matchers. Example: + # + # config.predicate_matchers[:swim] = :can_swim? + # + # This makes it possible to say: + # + # person.should swim # passes if person.can_swim? returns true + # + def predicate_matchers + @predicate_matchers ||= Spec::HashWithDeprecationNotice.new("predicate_matchers", "the new Matcher DSL") + end + + private + + def include_or_extend(action, *args) + modules, options = args_and_options(*args) + [get_type_from_options(options)].flatten.each do |required_example_group| + required_example_group = required_example_group.to_sym if required_example_group + modules.each do |mod| + Spec::Example::ExampleGroupFactory[required_example_group].__send__(action, mod) + end + end + end + + def add_callback(sym, *args, &proc) + scope, options = scope_and_options(*args) + example_group = Spec::Example::ExampleGroupFactory[get_type_from_options(options)] + example_group.__send__(sym, scope, &proc) + end + + def get_type_from_options(options) + options[:type] || options[:behaviour_type] + end + + def mock_framework_path(framework_name) + File.expand_path(File.join(File.dirname(__FILE__), "/../adapters/mock_frameworks/#{framework_name}")) + end + + def scope_and_options(*args) # :nodoc: + args, options = args_and_options(*args) + return scope_from(*args), options + end + + def scope_from(*args) # :nodoc: + args[0] || :each + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/differs/default.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/differs/default.rb new file mode 100644 index 00000000..73f0dcae --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/differs/default.rb @@ -0,0 +1,62 @@ +require File.join(File.dirname(__FILE__), "/load-diff-lcs") +require 'pp' + +module Spec + module Expectations + module Differs + unless defined?(Default) + class Default + def initialize(options) + @options = options + end + + # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool) + def diff_as_string(data_new, data_old) + data_old = data_old.split(/\n/).map! { |e| e.chomp } + data_new = data_new.split(/\n/).map! { |e| e.chomp } + output = "" + diffs = Diff::LCS.diff(data_old, data_new) + return output if diffs.empty? + oldhunk = hunk = nil + file_length_difference = 0 + diffs.each do |piece| + begin + hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines, + file_length_difference) + file_length_difference = hunk.file_length_difference + next unless oldhunk + # Hunks may overlap, which is why we need to be careful when our + # diff includes lines of context. Otherwise, we might print + # redundant lines. + if (context_lines > 0) and hunk.overlaps?(oldhunk) + hunk.unshift(oldhunk) + else + output << oldhunk.diff(format) + end + ensure + oldhunk = hunk + output << "\n" + end + end + #Handle the last remaining hunk + output << oldhunk.diff(format) << "\n" + end + + def diff_as_object(target,expected) + diff_as_string(PP.pp(target,""), PP.pp(expected,"")) + end + + protected + def format + @options.diff_format + end + + def context_lines + @options.context_lines + end + end + + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/differs/load-diff-lcs.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/differs/load-diff-lcs.rb new file mode 100644 index 00000000..f708bc9b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/differs/load-diff-lcs.rb @@ -0,0 +1,12 @@ +begin + require 'diff/lcs' +rescue LoadError + begin + require 'rubygems' unless ENV['NO_RUBYGEMS'] + require 'diff/lcs' + rescue LoadError + raise "You must gem install diff-lcs to use diffing" + end +end + +require 'diff/lcs/hunk' diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/drb_command_line.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/drb_command_line.rb new file mode 100644 index 00000000..261201b1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/drb_command_line.rb @@ -0,0 +1,23 @@ +require "drb/drb" + +module Spec + module Runner + # Facade to run specs by connecting to a DRB server + class DrbCommandLine + # Runs specs on a DRB server. Note that this API is similar to that of + # CommandLine - making it possible for clients to use both interchangeably. + def self.run(options) + begin + # See http://redmine.ruby-lang.org/issues/show/496 as to why we specify localhost:0 + DRb.start_service("druby://localhost:0") + spec_server = DRbObject.new_with_uri("druby://127.0.0.1:8989") + spec_server.run(options.argv, options.error_stream, options.output_stream) + true + rescue DRb::DRbConnError + options.error_stream.puts "No server is running" + false + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/example_group_runner.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/example_group_runner.rb new file mode 100644 index 00000000..67dc9950 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/example_group_runner.rb @@ -0,0 +1,59 @@ +module Spec + module Runner + class ExampleGroupRunner + def initialize(options) + @options = options + end + + def load_files(files) + $KCODE = 'u' if RUBY_VERSION.to_f < 1.9 + # It's important that loading files (or choosing not to) stays the + # responsibility of the ExampleGroupRunner. Some implementations (like) + # the one using DRb may choose *not* to load files, but instead tell + # someone else to do it over the wire. + files.each do |file| + load file + end + end + + def run + prepare + success = true + example_groups.each do |example_group| + success = success & example_group.run(@options) + end + return success + ensure + finish + end + + protected + + def prepare + reporter.start(number_of_examples) + example_groups.reverse! if reverse + end + + def finish + reporter.end + reporter.dump + end + + def reporter + @options.reporter + end + + def reverse + @options.reverse + end + + def example_groups + @options.example_groups + end + + def number_of_examples + @options.number_of_examples + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/extensions/kernel.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/extensions/kernel.rb new file mode 100644 index 00000000..4e23cdf2 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/extensions/kernel.rb @@ -0,0 +1,9 @@ +module Kernel + unless respond_to?(:debugger) + # Start a debugging session if ruby-debug is loaded with the -u/--debugger option + def debugger(steps=1) + # If not then just comment and proceed + $stderr.puts "debugger statement ignored, use -u or --debugger option on rspec to enable debugging" + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/base_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/base_formatter.rb new file mode 100644 index 00000000..0fbc12ce --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/base_formatter.rb @@ -0,0 +1,139 @@ +module Spec + module Runner + module Formatter + # Formatter base-class, which implements all required methods as no-ops, with the exception + class BaseFormatter + # Formatters are initialized with options and output + # arguments. RSpec's built-in formatters already expect this, and any + # custom formatters should as well. + # + # ==== Parameters + # options:: + # A struct containing boolean values for colour, autospec, + # and dry_run + # output:: + # Used by RSpec's built-in formatters to determine where to + # write the output. Default is STDOUT, otherwise a + # filename is expected. + # + # === Example + # If you invoke the spec command with: + # + # --format progress:progress_report.txt + # + # ... the value of output will be progress_report.txt. If you + # don't identify an output destination, the default is STDOUT. + def initialize(options, output) + end + + # This method is invoked before any examples are run, right after + # they have all been collected. This can be useful for special + # formatters that need to provide progress on feedback (graphical ones) + # + # This method will only be invoked once, and the next one to be invoked + # is #example_group_started + # + # ==== Parameters + # example_count:: the total number of examples to be run + def start(example_count) + end + + # This method is invoked at the beginning of the execution of each + # example_group. The next method to be invoked after this is + # #example_started + # + # ==== Parameters + # example_group_proxy:: instance of Spec::Example::ExampleGroupProxy + def example_group_started(example_group_proxy) + end + + # Deprecated - use example_group_started instead + def add_example_group(example_group_proxy) + Spec.deprecate("BaseFormatter#add_example_group", "BaseFormatter#example_group_started") + example_group_started(example_group_proxy) + end + + # This method is invoked when an +example+ starts. The next method to be + # invoked after this is #example_passed, #example_failed, or + # #example_pending + # + # ==== Parameters + # example_proxy:: instance of Spec::Example::ExampleProxy + def example_started(example_proxy) + end + + # This method is invoked when an +example+ passes. + # +example_proxy+ is the same instance of Spec::Example::ExampleProxy + # that was passed to example_started + # + # ==== Parameters + # example_proxy:: instance of Spec::Example::ExampleProxy + def example_passed(example_proxy) + end + + # This method is invoked when an +example+ fails, i.e. an exception occurred + # inside it (such as a failed should or other exception). + # + # ==== Parameters + # example_proxy:: + # The same instance of Spec::Example::ExampleProxy that was passed + # to example_started + # + # counter:: the sequential number of this failure + # + # failure:: instance of Spec::Runner::Reporter::Failure + def example_failed(example_proxy, counter, failure) + end + + # This method is invoked when an example is not yet implemented (i.e. has not + # been provided a block), or when an ExamplePendingError is raised. + # +message+ is the message from the ExamplePendingError, if it exists, or the + # default value of "Not Yet Implemented". +deprecated_pending_location+ is + # deprecated - use example_proxy.location instead + # + # ==== Parameters + # example_proxy:: instance of Spec::Example::ExampleProxy + # message:: + # the message passed to the pending message, or an internal + # default + # + def example_pending(example_proxy, message, deprecated_pending_location=nil) + end + + # This method is invoked after all of the examples have executed. The next method + # to be invoked after this one is #dump_failure (once for each failed example) + def start_dump + end + + # Dumps detailed information about an example failure. + # This method is invoked for each failed example after all examples have run. +counter+ is the sequence number + # of the associated example. +failure+ is a Failure object, which contains detailed + # information about the failure. + # + # ==== Parameters + # counter:: the sequential number of this failure + # failure:: instance of Spec::Runner::Reporter::Failure + def dump_failure(counter, failure) + end + + # This method is invoked after the dumping of examples and failures. + # + # ==== Parameters + # duration:: the total time for the entire run + # example_count:: the number of examples run + # failure_count:: the number of examples that failed + # pending_count:: the number of examples that are pending + def dump_summary(duration, example_count, failure_count, pending_count) + end + + # This gets invoked after the summary + def dump_pending + end + + # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams. + def close + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/base_text_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/base_text_formatter.rb new file mode 100644 index 00000000..4f8b9b78 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/base_text_formatter.rb @@ -0,0 +1,137 @@ +require 'spec/runner/formatter/base_formatter' +require 'fileutils' + +module Spec + module Runner + module Formatter + # Baseclass for text-based formatters. Can in fact be used for + # non-text based ones too - just ignore the +output+ constructor + # argument. + class BaseTextFormatter < BaseFormatter + attr_reader :output, :example_group + # Creates a new instance that will write to +output+. If +output+ is a + # String, output will be written to the File with that name, otherwise + # +output+ is exected to be an IO (or an object that responds to #puts + # and #write). + def initialize(options, output) + @options = options + if String === output + FileUtils.mkdir_p(File.dirname(output)) + @output = File.open(output, 'w') + else + @output = output + end + @pending_examples = [] + end + + def example_group_started(example_group_proxy) + @example_group = example_group_proxy + end + + def example_pending(example, message, deprecated_pending_location=nil) + @pending_examples << ["#{@example_group.description} #{example.description}", message, example.location] + end + + def dump_failure(counter, failure) + @output.puts + @output.puts "#{counter.to_s})" + @output.puts colorize_failure("#{failure.header}\n#{failure.exception.message}", failure) + @output.puts format_backtrace(failure.exception.backtrace) + @output.flush + end + + def colorize_failure(message, failure) + failure.pending_fixed? ? blue(message) : red(message) + end + + def colourise(message, failure) + Spec::deprecate("BaseTextFormatter#colourise", "colorize_failure") + colorize_failure(message, failure) + end + + def dump_summary(duration, example_count, failure_count, pending_count) + return if dry_run? + @output.puts + @output.puts "Finished in #{duration} seconds" + @output.puts + + summary = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}" + summary << ", #{pending_count} pending" if pending_count > 0 + + if failure_count == 0 + if pending_count > 0 + @output.puts yellow(summary) + else + @output.puts green(summary) + end + else + @output.puts red(summary) + end + @output.flush + end + + def dump_pending + unless @pending_examples.empty? + @output.puts + @output.puts "Pending:" + @pending_examples.each do |pending_example| + @output.puts "\n#{pending_example[0]} (#{pending_example[1]})" + @output.puts "#{pending_example[2]}\n" + end + end + @output.flush + end + + def close + @output.close if (IO === @output) & (@output != $stdout) + end + + def format_backtrace(backtrace) + return "" if backtrace.nil? + backtrace.map { |line| backtrace_line(line) }.join("\n") + end + + protected + + def colour? + !!@options.colour + end + + def dry_run? + !!@options.dry_run + end + + def autospec? + !!@options.autospec + end + + def backtrace_line(line) + line.sub(/\A([^:]+:\d+)$/, '\\1:') + end + + def colour(text, colour_code) + return text unless ENV['RSPEC_COLOR'] || (colour? & (autospec? || output_to_tty?)) + "#{colour_code}#{text}\e[0m" + end + + def output_to_tty? + begin + @output.tty? || ENV.has_key?("AUTOTEST") + rescue NoMethodError + false + end + end + + def green(text); colour(text, "\e[32m"); end + def red(text); colour(text, "\e[31m"); end + def yellow(text); colour(text, "\e[33m"); end + def blue(text); colour(text, "\e[34m"); end + + def magenta(text) + Spec::deprecate("BaseTextFormatter#magenta") + red(text) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/failing_example_groups_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/failing_example_groups_formatter.rb new file mode 100644 index 00000000..31729438 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/failing_example_groups_formatter.rb @@ -0,0 +1,25 @@ +require 'spec/runner/formatter/base_text_formatter' + +module Spec + module Runner + module Formatter + class FailingExampleGroupsFormatter < BaseTextFormatter + def example_failed(example, counter, failure) + if @example_group + @output.puts @example_group.description.gsub(/ \(druby.*\)/,"") + + @output.flush + @example_group = nil + end + end + + def dump_failure(counter, failure) + end + + def dump_summary(duration, example_count, failure_count, pending_count) + end + + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/failing_examples_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/failing_examples_formatter.rb new file mode 100644 index 00000000..e3a271c8 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/failing_examples_formatter.rb @@ -0,0 +1,20 @@ +require 'spec/runner/formatter/base_text_formatter' + +module Spec + module Runner + module Formatter + class FailingExamplesFormatter < BaseTextFormatter + def example_failed(example, counter, failure) + @output.puts "#{example_group.description} #{example.description}" + @output.flush + end + + def dump_failure(counter, failure) + end + + def dump_summary(duration, example_count, failure_count, pending_count) + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/html_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/html_formatter.rb new file mode 100644 index 00000000..2d0c65d1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/html_formatter.rb @@ -0,0 +1,338 @@ +require 'erb' +require 'spec/runner/formatter/base_text_formatter' +require 'spec/runner/formatter/no_op_method_missing' + +module Spec + module Runner + module Formatter + class HtmlFormatter < BaseTextFormatter + include ERB::Util # for the #h method + include NOOPMethodMissing + + def initialize(options, output) + super + @example_group_number = 0 + @example_number = 0 + @header_red = nil + end + + # The number of the currently running example_group + def example_group_number + @example_group_number + end + + # The number of the currently running example (a global counter) + def example_number + @example_number + end + + def start(example_count) + @example_count = example_count + + @output.puts html_header + @output.puts report_header + @output.flush + end + + def example_group_started(example_group) + super + @example_group_red = false + @example_group_number += 1 + unless example_group_number == 1 + @output.puts " " + @output.puts "
  • " + end + @output.puts "
    " + @output.puts "
    " + @output.puts "
    #{h(example_group.description)}
    " + @output.flush + end + + def start_dump + @output.puts "
    " + @output.puts "
    " + @output.flush + end + + def example_started(example) + @example_number += 1 + end + + def example_passed(example) + move_progress + @output.puts "
    #{h(example.description)}
    " + @output.flush + end + + def example_failed(example, counter, failure) + extra = extra_failure_content(failure) + failure_style = failure.pending_fixed? ? 'pending_fixed' : 'failed' + @output.puts " " unless @header_red + @header_red = true + @output.puts " " unless @example_group_red + @example_group_red = true + move_progress + @output.puts "
    " + @output.puts " #{h(example.description)}" + @output.puts "
    " + @output.puts "
    #{h(failure.exception.message)}
    " unless failure.exception.nil? + @output.puts "
    #{format_backtrace(failure.exception.backtrace)}
    " unless failure.exception.nil? + @output.puts extra unless extra == "" + @output.puts "
    " + @output.puts "
    " + @output.flush + end + + def example_pending(example, message, deprecated_pending_location=nil) + @output.puts " " unless @header_red + @output.puts " " unless @example_group_red + move_progress + @output.puts "
    #{h(example.description)} (PENDING: #{h(message)})
    " + @output.flush + end + + # Override this method if you wish to output extra HTML for a failed spec. For example, you + # could output links to images or other files produced during the specs. + # + def extra_failure_content(failure) + require 'spec/runner/formatter/snippet_extractor' + @snippet_extractor ||= SnippetExtractor.new + "
    #{@snippet_extractor.snippet(failure.exception)}
    " + end + + def move_progress + @output.puts " " + @output.flush + end + + def percent_done + result = 100.0 + if @example_count != 0 + result = ((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0 + end + result + end + + def dump_failure(counter, failure) + end + + def dump_summary(duration, example_count, failure_count, pending_count) + if dry_run? + totals = "This was a dry-run" + else + totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}" + totals << ", #{pending_count} pending" if pending_count > 0 + end + @output.puts "" + @output.puts "" + @output.puts "
    " + @output.puts "" + @output.puts "" + @output.puts "" + @output.flush + end + + def html_header + <<-EOF + + + + + RSpec results + + + + + + + + +EOF + end + + def report_header + <<-EOF +
    + +
    +
    +

    RSpec Code Examples

    +
    + +
    +

     

    +

     

    +
    +
    + +
    +EOF + end + + def global_scripts + <<-EOF +function moveProgressBar(percentDone) { + document.getElementById("rspec-header").style.width = percentDone +"%"; +} +function makeRed(element_id) { + document.getElementById(element_id).style.background = '#C40D0D'; + document.getElementById(element_id).style.color = '#FFFFFF'; +} + +function makeYellow(element_id) { + if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D') + { + document.getElementById(element_id).style.background = '#FAF834'; + document.getElementById(element_id).style.color = '#000000'; + } + else + { + document.getElementById(element_id).style.background = '#FAF834'; + document.getElementById(element_id).style.color = '#000000'; + } +} +EOF + end + + def global_styles + <<-EOF +#rspec-header { + background: #65C400; color: #fff; height: 4em; +} + +.rspec-report h1 { + margin: 0px 10px 0px 10px; + padding: 10px; + font-family: "Lucida Grande", Helvetica, sans-serif; + font-size: 1.8em; + position: absolute; +} + +#summary { + margin: 0; padding: 5px 10px; + font-family: "Lucida Grande", Helvetica, sans-serif; + text-align: right; + top: 0px; + right: 0px; + float:right; +} + +#summary p { + margin: 0 0 0 2px; +} + +#summary #totals { + font-size: 1.2em; +} + +.example_group { + margin: 0 10px 5px; + background: #fff; +} + +dl { + margin: 0; padding: 0 0 5px; + font: normal 11px "Lucida Grande", Helvetica, sans-serif; +} + +dt { + padding: 3px; + background: #65C400; + color: #fff; + font-weight: bold; +} + +dd { + margin: 5px 0 5px 5px; + padding: 3px 3px 3px 18px; +} + +dd.spec.passed { + border-left: 5px solid #65C400; + border-bottom: 1px solid #65C400; + background: #DBFFB4; color: #3D7700; +} + +dd.spec.failed { + border-left: 5px solid #C20000; + border-bottom: 1px solid #C20000; + color: #C20000; background: #FFFBD3; +} + +dd.spec.not_implemented { + border-left: 5px solid #FAF834; + border-bottom: 1px solid #FAF834; + background: #FCFB98; color: #131313; +} + +dd.spec.pending_fixed { + border-left: 5px solid #0000C2; + border-bottom: 1px solid #0000C2; + color: #0000C2; background: #D3FBFF; +} + +.backtrace { + color: #000; + font-size: 12px; +} + +a { + color: #BE5C00; +} + +/* Ruby code, style similar to vibrant ink */ +.ruby { + font-size: 12px; + font-family: monospace; + color: white; + background-color: black; + padding: 0.1em 0 0.2em 0; +} + +.ruby .keyword { color: #FF6600; } +.ruby .constant { color: #339999; } +.ruby .attribute { color: white; } +.ruby .global { color: white; } +.ruby .module { color: white; } +.ruby .class { color: white; } +.ruby .string { color: #66FF00; } +.ruby .ident { color: white; } +.ruby .method { color: #FFCC00; } +.ruby .number { color: white; } +.ruby .char { color: white; } +.ruby .comment { color: #9933CC; } +.ruby .symbol { color: white; } +.ruby .regex { color: #44B4CC; } +.ruby .punct { color: white; } +.ruby .escape { color: white; } +.ruby .interp { color: white; } +.ruby .expr { color: white; } + +.ruby .offending { background-color: gray; } +.ruby .linenum { + width: 75px; + padding: 0.1em 1em 0.2em 0; + color: #000000; + background-color: #FFFBD3; +} +EOF + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/nested_text_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/nested_text_formatter.rb new file mode 100644 index 00000000..5caec5a4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/nested_text_formatter.rb @@ -0,0 +1,47 @@ +require 'spec/runner/formatter/base_text_formatter' + +module Spec + module Runner + module Formatter + class NestedTextFormatter < BaseTextFormatter + def initialize(options, where) + super + @last_nested_descriptions = [] + end + + def example_group_started(example_group) + super + + example_group.nested_descriptions.each_with_index do |nested_description, i| + unless nested_description == @last_nested_descriptions[i] + output.puts "#{' ' * i}#{nested_description}" + end + end + + @last_nested_descriptions = example_group.nested_descriptions + end + + def example_failed(example, counter, failure) + output.puts(red("#{current_indentation}#{example.description} (FAILED - #{counter})")) + output.flush + end + + def example_passed(example) + message = "#{current_indentation}#{example.description}" + output.puts green(message) + output.flush + end + + def example_pending(example, message, deprecated_pending_location=nil) + super + output.puts yellow("#{current_indentation}#{example.description} (PENDING: #{message})") + output.flush + end + + def current_indentation + ' ' * @last_nested_descriptions.length + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/no_op_method_missing.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/no_op_method_missing.rb new file mode 100644 index 00000000..350e29f7 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/no_op_method_missing.rb @@ -0,0 +1,21 @@ +module Spec + module Runner + module Formatter + module NOOPMethodMissing + def respond_to?(message, include_private = false) + if include_private + true + else + !private_methods.any? {|m| [message.to_s, message.to_sym].include?(m)} + end + end + + private + + def method_missing(sym, *args) + # a no-op + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/profile_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/profile_formatter.rb new file mode 100644 index 00000000..3784f3ac --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/profile_formatter.rb @@ -0,0 +1,47 @@ +require 'spec/runner/formatter/progress_bar_formatter' + +module Spec + module Runner + module Formatter + class ProfileFormatter < ProgressBarFormatter + + def initialize(options, where) + super + @example_times = [] + end + + def start(count) + @output.puts "Profiling enabled." + end + + def example_started(example) + @time = Time.now + end + + def example_passed(example) + super + @example_times << [ + example_group.description, + example.description, + Time.now - @time + ] + end + + def start_dump + super + @output.puts "\n\nTop 10 slowest examples:\n" + + @example_times = @example_times.sort_by do |description, example, time| + time + end.reverse + + @example_times[0..9].each do |description, example, time| + @output.print red(sprintf("%.7f", time)) + @output.puts " #{description} #{example}" + end + @output.flush + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/progress_bar_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/progress_bar_formatter.rb new file mode 100644 index 00000000..862f87a4 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/progress_bar_formatter.rb @@ -0,0 +1,33 @@ +require 'spec/runner/formatter/base_text_formatter' +require 'spec/runner/formatter/no_op_method_missing' + +module Spec + module Runner + module Formatter + class ProgressBarFormatter < BaseTextFormatter + include NOOPMethodMissing + + def example_failed(example, counter, failure) + @output.print colorize_failure('F', failure) + @output.flush + end + + def example_passed(example) + @output.print green('.') + @output.flush + end + + def example_pending(example, message, deprecated_pending_location=nil) + super + @output.print yellow('*') + @output.flush + end + + def start_dump + @output.puts + @output.flush + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/silent_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/silent_formatter.rb new file mode 100644 index 00000000..43cce33b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/silent_formatter.rb @@ -0,0 +1,10 @@ +require 'spec/runner/formatter/base_formatter' + +module Spec + module Runner + module Formatter + class SilentFormatter < BaseFormatter + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/snippet_extractor.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/snippet_extractor.rb new file mode 100644 index 00000000..4f34e5fe --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/snippet_extractor.rb @@ -0,0 +1,52 @@ +module Spec + module Runner + module Formatter + # This class extracts code snippets by looking at the backtrace of the passed error + class SnippetExtractor #:nodoc: + class NullConverter; def convert(code, pre); code; end; end #:nodoc: + begin; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end + + def snippet(error) + raw_code, line = snippet_for(error.backtrace[0]) + highlighted = @@converter.convert(raw_code, false) + highlighted << "\n# gem install syntax to get syntax highlighting" if @@converter.is_a?(NullConverter) + post_process(highlighted, line) + end + + def snippet_for(error_line) + if error_line =~ /(.*):(\d+)/ + file = $1 + line = $2.to_i + [lines_around(file, line), line] + else + ["# Couldn't get snippet for #{error_line}", 1] + end + end + + def lines_around(file, line) + if File.file?(file) + lines = File.open(file).read.split("\n") + min = [0, line-3].max + max = [line+1, lines.length-1].min + selected_lines = [] + selected_lines.join("\n") + lines[min..max].join("\n") + else + "# Couldn't get snippet for #{file}" + end + end + + def post_process(highlighted, offending_line) + new_lines = [] + highlighted.split("\n").each_with_index do |line, i| + new_line = "#{offending_line+i-2}#{line}" + new_line = "#{new_line}" if i == 2 + new_lines << new_line + end + new_lines.join("\n") + end + + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/specdoc_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/specdoc_formatter.rb new file mode 100644 index 00000000..7204f214 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/specdoc_formatter.rb @@ -0,0 +1,33 @@ +require 'spec/runner/formatter/base_text_formatter' + +module Spec + module Runner + module Formatter + class SpecdocFormatter < BaseTextFormatter + def example_group_started(example_group) + super + output.puts + output.puts example_group.description + output.flush + end + + def example_failed(example, counter, failure) + output.puts(red("- #{example.description} (FAILED - #{counter})")) + output.flush + end + + def example_passed(example) + message = "- #{example.description}" + output.puts green(message) + output.flush + end + + def example_pending(example, message, deprecated_pending_location=nil) + super + output.puts yellow("- #{example.description} (PENDING: #{message})") + output.flush + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/text_mate_formatter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/text_mate_formatter.rb new file mode 100644 index 00000000..4c0a9c7d --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/formatter/text_mate_formatter.rb @@ -0,0 +1,16 @@ +require 'spec/runner/formatter/html_formatter' + +module Spec + module Runner + module Formatter + # Formats backtraces so they're clickable by TextMate + class TextMateFormatter < HtmlFormatter + def backtrace_line(line) + line.gsub(/([^:]*\.rb):(\d*)/) do + "#{$1}:#{$2} " + end + end + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/heckle_runner.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/heckle_runner.rb new file mode 100644 index 00000000..5c81ea84 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/heckle_runner.rb @@ -0,0 +1,72 @@ +if Spec::Ruby.version.to_f < 1.9 + begin + require 'rubygems' unless ENV['NO_RUBYGEMS'] + require 'heckle' + rescue LoadError ; raise "You must gem install heckle to use --heckle" ; end + + module Spec + module Runner + # Creates a new Heckler configured to heckle all methods in the classes + # whose name matches +filter+ + class HeckleRunner + def initialize(filter, heckle_class=Heckler) + @filter = filter + @heckle_class = heckle_class + end + + # Runs all the example groups held by +rspec_options+ once for each of the + # methods in the matched classes. + def heckle_with + if @filter =~ /(.*)[#\.](.*)/ + heckle_method($1, $2) + else + heckle_class_or_module(@filter) + end + end + + def heckle_method(class_name, method_name) + verify_constant(class_name) + heckle = @heckle_class.new(class_name, method_name, Spec::Runner.options) + heckle.validate + end + + def heckle_class_or_module(class_or_module_name) + verify_constant(class_or_module_name) + pattern = /^#{class_or_module_name}/ + classes = [] + ObjectSpace.each_object(Class) do |klass| + classes << klass if klass.name =~ pattern + end + + classes.each do |klass| + klass.instance_methods(false).each do |method_name| + heckle = @heckle_class.new(klass.name, method_name, Spec::Runner.options) + heckle.validate + end + end + end + + def verify_constant(name) + begin + # This is defined in Heckle + name.to_class + rescue + raise "Heckling failed - \"#{name}\" is not a known class or module" + end + end + end + + class Heckler < Heckle + def initialize(klass_name, method_name, rspec_options) + super(klass_name, method_name) + @rspec_options = rspec_options + end + + def tests_pass? + @rspec_options.run_examples + end + + end + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/heckle_runner_unsupported.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/heckle_runner_unsupported.rb new file mode 100644 index 00000000..35ff86e1 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/heckle_runner_unsupported.rb @@ -0,0 +1,10 @@ +module Spec + module Runner + # Dummy implementation for Windows that just fails (Heckle is not supported on Windows) + class HeckleRunner + def initialize(filter) + raise "Heckle is not supported on Windows or Ruby 1.9" + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/line_number_query.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/line_number_query.rb new file mode 100644 index 00000000..0a907d3f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/line_number_query.rb @@ -0,0 +1,78 @@ +module Spec + module Runner + # Parses a spec file and finds the nearest example for a given line number. + class LineNumberQuery + attr_reader :best_match + + def initialize(run_options) + @best_match = {} + @run_options = run_options + end + + def spec_name_for(file, line_number) + best_match.clear + file = File.expand_path(file) + determine_best_match(file, line_number) + if best_match[:example_group] + if best_match[:example] + "#{best_match[:example_group].description} #{best_match[:example].description}" + else + best_match[:example_group].description + end + else + nil + end + end + + def example_line_for(file, line_number) + determine_best_match(file, line_number) + best_match[:line] + end + + protected + + def determine_best_match(file, line_number) + best_match.clear + file = File.expand_path(file) + @run_options.example_groups.each do |example_group| + next unless example_group.location + consider_example_group_for_best_match(example_group, file, line_number) + + example_group.examples.each do |example| + consider_example_for_best_match(example, example_group, file, line_number) + end + end + end + + def consider_example_group_for_best_match(example_group, file, line_number) + example_group_file, example_group_line = parse_location(example_group.location) + if is_best_match?(file, line_number, example_group_file, example_group_line) + best_match.clear + best_match[:example_group] = example_group + best_match[:line] = example_group_line + end + end + + def consider_example_for_best_match(example, example_group, file, line_number) + example_file, example_line = parse_location(example.location) + if is_best_match?(file, line_number, example_file, example_line) + best_match.clear + best_match[:example_group] = example_group + best_match[:example] = example + best_match[:line] = example_line + end + end + + def is_best_match?(file, line_number, example_file, example_line) + file == File.expand_path(example_file) && + example_line <= line_number && + example_line > best_match[:line].to_i + end + + def parse_location(location) + location =~ /(.*)\:(\d*)(\:|$)/ + return $1, Integer($2) + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/option_parser.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/option_parser.rb new file mode 100644 index 00000000..2e35b871 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/option_parser.rb @@ -0,0 +1,217 @@ +require 'optparse' +require 'stringio' + +module Spec + module Runner + class OptionParser < ::OptionParser + class << self + def parse(args, err, out) + parser = new(err, out) + parser.parse(args) + parser.options + end + + def spec_command? + $0.split('/').last == 'spec' + end + end + + attr_reader :options + + OPTIONS = { + :pattern => ["-p", "--pattern [PATTERN]","Limit files loaded to those matching this pattern. Defaults to '**/*_spec.rb'", + "Separate multiple patterns with commas.", + "Applies only to directories named on the command line (files", + "named explicitly on the command line will be loaded regardless)."], + :diff => ["-D", "--diff [FORMAT]","Show diff of objects that are expected to be equal when they are not", + "Builtin formats: unified|u|context|c", + "You can also specify a custom differ class", + "(in which case you should also specify --require)"], + :colour => ["-c", "--colour", "--color", "Show coloured (red/green) output"], + :example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is", + "the path to an existing file (typically generated by a previous", + "run using --format failing_examples:file.txt), then the examples", + "on each line of that file will be executed. If the file is empty,", + "all examples will be run (as if --example was not specified).", + " ", + "If the argument is not an existing file, then it is treated as", + "an example name directly, causing RSpec to run just the example", + "matching that name"], + :specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"], + :line => ["-l", "--line LINE_NUMBER", Integer, "Execute example group or example at given line.", + "(does not work for dynamically generated examples)"], + :format => ["-f", "--format FORMAT[:WHERE]","Specifies what format to use for output. Specify WHERE to tell", + "the formatter where to write the output. All built-in formats", + "expect WHERE to be a file name, and will write to $stdout if it's", + "not specified. The --format option may be specified several times", + "if you want several outputs", + " ", + "Builtin formats:", + "silent|l : No output", "progress|p : Text-based progress bar", + "profile|o : Text-based progress bar with profiling of 10 slowest examples", + "specdoc|s : Code example doc strings", + "nested|n : Code example doc strings with nested groups indented", + "html|h : A nice HTML report", + "failing_examples|e : Write all failing examples - input for --example", + "failing_example_groups|g : Write all failing example groups - input for --example", + " ", + "FORMAT can also be the name of a custom formatter class", + "(in which case you should also specify --require to load it)"], + :require => ["-r", "--require FILE", "Require FILE before running specs", + "Useful for loading custom formatters or other extensions.", + "If this option is used it must come before the others"], + :backtrace => ["-b", "--backtrace", "Output full backtrace"], + :loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.", + "STRATEGY can currently only be 'mtime' (File modification time)", + "By default, spec files are loaded in alphabetical order if --loadby", + "is not specified."], + :reverse => ["-R", "--reverse", "Run examples in reverse order"], + :timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the", + "specified time"], + :heckle => ["-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods", + "identified by CODE little by little and run all the examples again", + "for each mutation. The intent is that for each mutation, at least", + "one example *should* fail, and RSpec will tell you if this is not the", + "case. CODE should be either Some::Module, Some::Class or", + "Some::Fabulous#method}"], + :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."], + :options_file => ["-O", "--options PATH", "Read options from a file"], + :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"], + :runner => ["-U", "--runner RUNNER", "Use a custom Runner."], + :debug => ["-u", "--debugger", "Enable ruby-debugging."], + :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"], + :version => ["-v", "--version", "Show version"], + :help => ["-h", "--help", "You're looking at it"] + } + + def initialize(err, out) + super() + @error_stream = err + @out_stream = out + @options = Options.new(@error_stream, @out_stream) + + @file_factory = File + + self.banner = "Usage: spec (FILE(:LINE)?|DIRECTORY|GLOB)+ [options]" + self.separator "" + on(*OPTIONS[:pattern]) {|pattern| @options.filename_pattern = pattern} + on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)} + on(*OPTIONS[:colour]) {@options.colour = true} + on(*OPTIONS[:example]) {|example| @options.parse_example(example)} + on(*OPTIONS[:specification]) {|example| @options.parse_example(example)} + on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i} + on(*OPTIONS[:format]) {|format| @options.parse_format(format)} + on(*OPTIONS[:require]) {|requires| invoke_requires(requires)} + on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new} + on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby} + on(*OPTIONS[:reverse]) {@options.reverse = true} + on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f} + on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)} + on(*OPTIONS[:dry_run]) {@options.dry_run = true} + on(*OPTIONS[:options_file]) {|options_file|} + on(*OPTIONS[:generate_options]) {|options_file|} + on(*OPTIONS[:runner]) {|runner| @options.user_input_for_runner = runner} + on(*OPTIONS[:debug]) {@options.debug = true} + on(*OPTIONS[:drb]) {} + on(*OPTIONS[:version]) {parse_version} + on("--autospec") {@options.autospec = true} + on_tail(*OPTIONS[:help]) {parse_help} + end + + def order!(argv, &blk) + @argv = argv.dup + @argv = (@argv.empty? & self.class.spec_command?) ? ['--help'] : @argv + + # Parse options file first + parse_file_options(:options_file, :parse_options_file) + + @options.argv = @argv.dup + return if parse_file_options(:generate_options, :write_generated_options) + return if parse_drb + + super(@argv) do |file| + if file =~ /^(.+):(\d+)$/ + file = $1 + @options.line_number = $2.to_i + end + + @options.files << file + blk.call(file) if blk + end + + @options + end + + protected + + def invoke_requires(requires) + requires.split(",").each do |file| + require file + end + end + + def parse_options_file(options_file) + option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten + @argv.push(*option_file_args) + end + + def parse_file_options(option_name, action) + # Remove the file option and the argument before handling the file + options_file = nil + options_list = OPTIONS[option_name][0..1] + options_list[1].gsub!(" PATH", "") + options_list.each do |option| + if index = @argv.index(option) + @argv.delete_at(index) + options_file = @argv.delete_at(index) + end + end + + if options_file + send(action, options_file) + return true + else + return false + end + end + + def write_generated_options(options_file) + File.open(options_file, 'w') do |io| + io.puts @argv.join("\n") + end + @out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:" + @out_stream.puts "spec --options #{options_file}" + @options.examples_should_not_be_run + end + + def parse_drb + argv = @options.argv + is_drb = false + is_drb ||= argv.delete(OPTIONS[:drb][0]) + is_drb ||= argv.delete(OPTIONS[:drb][1]) + return false unless is_drb + if DrbCommandLine.run(self.class.parse(argv, @error_stream, @out_stream)) + @options.examples_should_not_be_run + true + else + @error_stream.puts "Running specs locally:" + false + end + end + + def parse_version + @out_stream.puts ::Spec::VERSION::SUMMARY + exit if stdout? + end + + def parse_help + @out_stream.puts self + exit if stdout? + end + + def stdout? + @out_stream == $stdout + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/options.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/options.rb new file mode 100644 index 00000000..7c7d7cc3 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/options.rb @@ -0,0 +1,369 @@ +require 'ostruct' + +module Spec + module Runner + class Options + FILE_SORTERS = { + 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)} + } + + EXAMPLE_FORMATTERS = { # Load these lazily for better speed + 'silent' => ['spec/runner/formatter/silent_formatter', 'Formatter::SilentFormatter'], + 'l' => ['spec/runner/formatter/silent_formatter', 'Formatter::SilentFormatter'], + 'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'], + 's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'], + 'nested' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'], + 'n' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'], + 'html' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'], + 'h' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'], + 'progress' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'], + 'p' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'], + 'failing_examples' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'], + 'e' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'], +'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'], + 'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'], + 'profile' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'], + 'o' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'], + 'textmate' => ['spec/runner/formatter/text_mate_formatter', 'Formatter::TextMateFormatter'] + } + + attr_accessor( + :autospec, # hack to tell + :filename_pattern, + :backtrace_tweaker, + :context_lines, + :diff_format, + :dry_run, + :profile, + :heckle_runner, + :debug, + :line_number, + :loadby, + :reporter, + :reverse, + :timeout, + :verbose, + :user_input_for_runner, + :error_stream, + :output_stream, + # TODO: BT - Figure out a better name + :argv + ) + attr_reader :colour, :differ_class, :files, :examples, :example_groups + + def initialize(error_stream, output_stream) + @error_stream = error_stream + @output_stream = output_stream + @filename_pattern = "**/*_spec.rb" + @backtrace_tweaker = QuietBacktraceTweaker.new + @examples = [] + @colour = false + @profile = false + @dry_run = false + @debug = false + @reporter = Reporter.new(self) + @context_lines = 3 + @diff_format = :unified + @files = [] + @example_groups = [] + @result = nil + @examples_run = false + @examples_should_be_run = nil + @user_input_for_runner = nil + @after_suite_parts = [] + @files_loaded = false + @out_used = nil + end + + def add_example_group(example_group) + @example_groups << example_group + end + + def line_number_requested? + !!line_number + end + + def example_line + Spec::Runner::LineNumberQuery.new(self).example_line_for(files.first, line_number) + end + + def remove_example_group(example_group) + @example_groups.delete(example_group) + end + + def require_ruby_debug + require 'rubygems' unless ENV['NO_RUBYGEMS'] + require 'ruby-debug' + end + + def run_examples + require_ruby_debug if debug + return true unless examples_should_be_run? + success = true + begin + runner = custom_runner || ExampleGroupRunner.new(self) + + unless @files_loaded + runner.load_files(files_to_load) + @files_loaded = true + end + + define_predicate_matchers + plugin_mock_framework + + # TODO - this has to happen after the files get loaded, + # otherwise the before_suite_parts are not populated + # from the configuration. There is no spec for this + # directly, but features/before_and_after_blocks/before_and_after_blocks.story + # will fail if this happens before the files are loaded. + before_suite_parts.each do |part| + part.call + end + + if example_groups.empty? + true + else + set_spec_from_line_number if line_number + success = runner.run + @examples_run = true + heckle if heckle_runner + success + end + ensure + after_suite_parts.each do |part| + part.arity < 1 ? part.call : part.call(success) + end + end + end + + def before_suite_parts + Spec::Example::BeforeAndAfterHooks.before_suite_parts + end + + def after_suite_parts + Spec::Example::BeforeAndAfterHooks.after_suite_parts + end + + def examples_run? + @examples_run + end + + def examples_should_not_be_run + @examples_should_be_run = false + end + + def mock_framework + # TODO - don't like this dependency - perhaps store this in here instead? + Spec::Runner.configuration.mock_framework + end + + def colour=(colour) + @colour = colour + if @colour && RUBY_PLATFORM =~ /mswin|mingw/ ;\ + begin ;\ + replace_output = @output_stream.equal?($stdout) ;\ + require 'rubygems' unless ENV['NO_RUBYGEMS'] ;\ + require 'Win32/Console/ANSI' ;\ + @output_stream = $stdout if replace_output ;\ + rescue LoadError ;\ + warn "You must 'gem install win32console' to use colour on Windows" ;\ + @colour = false ;\ + end + end + end + + def parse_diff(format) + case format + when :context, 'context', 'c' + @diff_format = :context + default_differ + when :unified, 'unified', 'u', '', nil + @diff_format = :unified + default_differ + else + @diff_format = :custom + self.differ_class = load_class(format, 'differ', '--diff') + end + end + + def parse_example(example) + if(File.file?(example)) + @examples = [File.open(example).read.split("\n")].flatten + else + @examples = [example] + end + end + + def parse_format(format_arg) + format, where = ClassAndArgumentsParser.parse(format_arg) + unless where + raise "When using several --format options only one of them can be without a file" if @out_used + where = @output_stream + @out_used = true + end + @format_options ||= [] + @format_options << [format, where] + end + + def formatters + @format_options ||= [['progress', @output_stream]] + @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS) + end + + def load_formatters(format_options, formatters) + format_options.map do |format, where| + formatter_type = if formatters[format] + require formatters[format][0] + eval(formatters[format][1], binding, __FILE__, __LINE__) + else + load_class(format, 'formatter', '--format') + end + formatter_type.new(formatter_options, where) + end + end + + def formatter_options + @formatter_options ||= OpenStruct.new( + :colour => colour, + :autospec => autospec, + :dry_run => dry_run + ) + end + + def load_heckle_runner(heckle) + @format_options ||= [['silent', @output_stream]] + suffix = ([/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} || Spec::Ruby.version.to_f == 1.9) ? '_unsupported' : '' + require "spec/runner/heckle_runner#{suffix}" + @heckle_runner = ::Spec::Runner::HeckleRunner.new(heckle) + end + + def number_of_examples + return examples.size unless examples.empty? + @example_groups.inject(0) {|sum, group| sum + group.number_of_examples} + end + + def files_to_load + result = [] + sorted_files.each do |file| + if File.directory?(file) + filename_pattern.split(",").each do |pattern| + result += Dir[File.expand_path("#{file}/#{pattern.strip}")] + end + elsif File.file?(file) + result << file + else + raise "File or directory not found: #{file}" + end + end + result + end + + def dry_run? + @dry_run == true + end + + protected + + def define_predicate_matchers + Spec::Runner.configuration.predicate_matchers.each_pair do |matcher_method, method_on_object| + Spec::Example::ExampleMethods::__send__ :define_method, matcher_method do |*args| + eval("be_#{method_on_object.to_s.gsub('?','')}(*args)") + end + end + end + + def plugin_mock_framework + case mock_framework + when Module + Spec::Example::ExampleMethods.__send__ :include, mock_framework + else + require mock_framework + Spec::Example::ExampleMethods.__send__ :include, Spec::Adapters::MockFramework + end + end + + def examples_should_be_run? + return @examples_should_be_run unless @examples_should_be_run.nil? + @examples_should_be_run = true + end + + def differ_class=(klass) + return unless klass + @differ_class = klass + Spec::Expectations.differ = self.differ_class.new(self) + end + + def load_class(name, kind, option) + if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ + arg = $2 == "" ? nil : $2 + [$1, arg] + else + m = "#{name.inspect} is not a valid class name" + @error_stream.puts m + raise m + end + begin + eval(name, binding, __FILE__, __LINE__) + rescue NameError => e + @error_stream.puts "Couldn't find #{kind} class #{name}" + @error_stream.puts "Make sure the --require option is specified *before* #{option}" + if $_spec_spec ; raise e ; else exit(1) ; end + end + end + + def custom_runner + return nil unless custom_runner? + klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner) + runner_type = load_class(klass_name, 'example group runner', '--runner') + return runner_type.new(self, arg) + end + + def custom_runner? + return user_input_for_runner ? true : false + end + + def heckle + heckle_runner = self.heckle_runner + self.heckle_runner = nil + heckle_runner.heckle_with + end + + def sorted_files + return sorter ? files.sort(&sorter) : files + end + + def sorter + FILE_SORTERS[loadby] + end + + def default_differ + require 'spec/runner/differs/default' + self.differ_class = ::Spec::Expectations::Differs::Default + end + + def set_spec_from_line_number + if examples.empty? + if files.length == 1 + if File.directory?(files[0]) + error_stream.puts "You must specify one file, not a directory when providing a line number" + exit(1) if stderr? + else + example = LineNumberQuery.new(self).spec_name_for(files[0], line_number) + @examples = [example] + end + else + error_stream.puts "Only one file can be specified when providing a line number: #{files.inspect}" + exit(3) if stderr? + end + else + error_stream.puts "You cannot use --example and specify a line number" + exit(4) if stderr? + end + end + + def stderr? + @error_stream == $stderr + end + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/reporter.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/reporter.rb new file mode 100644 index 00000000..0fae7d13 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/runner/reporter.rb @@ -0,0 +1,171 @@ +module Spec + module Runner + class Reporter + attr_reader :options + + def initialize(options) + @options = options + @options.reporter = self + @failures = [] + @pending_count = 0 + @example_count = 0 + @start_time = nil + @end_time = nil + end + + def example_group_started(example_group) + @example_group = example_group + formatters.each do |f| + f.example_group_started(example_group) + end + end + + def example_started(example) + formatters.each{|f| f.example_started(example)} + end + + def example_finished(example, error=nil) + @example_count += 1 + + if error.nil? + example_passed(example) + elsif Spec::Example::ExamplePendingError === error + example_pending(example, example.location, error.message) + else + example_failed(example, error) + end + end + + def example_failed(example, error) + backtrace_tweaker.tweak_backtrace(error) + failure = Failure.new(@example_group.description, example.description, error) + @failures << failure + formatters.each do |f| + f.example_failed(example, @failures.length, failure) + end + end + + def start(number_of_examples) + @start_time = Time.new + formatters.each{|f| f.start(number_of_examples)} + end + + def end + @end_time = Time.new + end + + # Dumps the summary and returns the total number of failures + def dump + formatters.each{|f| f.start_dump} + dump_pending + dump_failures + formatters.each do |f| + f.dump_summary(duration, @example_count, @failures.length, @pending_count) + f.close + end + @failures.length + end + + class Failure + def initialize(group_description, example_description, exception) # :nodoc: + @example_name = "#{group_description} #{example_description}" + @exception = exception + end + + # The Exception object raised + attr_reader :exception + + # Header messsage for reporting this failure, including the name of the + # example and an indicator of the type of failure. FAILED indicates a + # failed expectation. FIXED indicates a pending example that passes, and + # no longer needs to be pending. RuntimeError indicates that a + # RuntimeError occured. + # + # == Examples + # + # 'A new account should have a zero balance' FAILED + # 'A new account should have a zero balance' FIXED + # RuntimeError in 'A new account should have a zero balance' + def header + if expectation_not_met? + "'#{@example_name}' FAILED" + elsif pending_fixed? + "'#{@example_name}' FIXED" + else + "#{@exception.class.name} in '#{@example_name}'" + end + end + + def pending_fixed? # :nodoc: + @exception.is_a?(Spec::Example::PendingExampleFixedError) + end + + def expectation_not_met? # :nodoc: + @exception.is_a?(Spec::Expectations::ExpectationNotMetError) + end + end + + private + + def formatters + @options.formatters + end + + def backtrace_tweaker + @options.backtrace_tweaker + end + + def dump_failures + return if @failures.empty? + @failures.inject(1) do |index, failure| + formatters.each{|f| f.dump_failure(index, failure)} + index + 1 + end + end + + def dump_pending + formatters.each{|f| f.dump_pending} + end + + def duration + return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?) + return "0.0" + end + + def example_passed(example) + formatters.each{|f| f.example_passed(example)} + end + + EXAMPLE_PENDING_DEPRECATION_WARNING = <<-WARNING + +********************************************************************* +DEPRECATION WARNING: RSpec's formatters have changed example_pending +to accept two arguments instead of three. Please see the rdoc +for Spec::Runner::Formatter::BaseFormatter#example_pending +for more information. + +Please update any custom formatters to accept only two arguments +to example_pending. Support for example_pending with two arguments +and this warning message will be removed after the RSpec 2.0 release. +********************************************************************* +WARNING + + def example_pending(example, ignore, message="Not Yet Implemented") + @pending_count += 1 + formatters.each do |formatter| + if formatter_uses_deprecated_example_pending_method?(formatter) + Spec.warn EXAMPLE_PENDING_DEPRECATION_WARNING + formatter.example_pending(example, message, example.location) + else + formatter.example_pending(example, message) + end + end + end + + def formatter_uses_deprecated_example_pending_method?(formatter) + formatter.method(:example_pending).arity == 3 + end + + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/test/unit.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/test/unit.rb new file mode 100644 index 00000000..fb4eb493 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/test/unit.rb @@ -0,0 +1,10 @@ +require 'spec/interop/test' + +# Hack to stop active_support/dependencies from complaining about +# 'spec/test/unit' not defining Spec::Test::Unit +module Spec + module Test + module Unit + end + end +end diff --git a/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/version.rb b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/version.rb new file mode 100644 index 00000000..d4dc926b --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/RSpec/libs/rspec-1.2.7/lib/spec/version.rb @@ -0,0 +1,14 @@ +module Spec # :nodoc: + module VERSION # :nodoc: + unless defined? MAJOR + MAJOR = 1 + MINOR = 2 + TINY = 7 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') + + SUMMARY = "rspec #{STRING}" + end + end +end \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v3.1/Gallio.ReSharperRunner31.dll b/lib/Gallio_3.1.397.0/bin/ReSharper/v3.1/Gallio.ReSharperRunner31.dll new file mode 100644 index 00000000..aed4b896 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/ReSharper/v3.1/Gallio.ReSharperRunner31.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v3.1/Gallio.ReSharperRunner31.plugin b/lib/Gallio_3.1.397.0/bin/ReSharper/v3.1/Gallio.ReSharperRunner31.plugin new file mode 100644 index 00000000..1b9ef461 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/ReSharper/v3.1/Gallio.ReSharperRunner31.plugin @@ -0,0 +1,19 @@ + + + + ReSharper v3.1 Runner + 3.1.0.0 + Enables ReSharper v3.1 to run tests using Gallio. + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v4.0/Gallio.ReSharperRunner40.dll b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.0/Gallio.ReSharperRunner40.dll new file mode 100644 index 00000000..6c8211e9 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.0/Gallio.ReSharperRunner40.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v4.0/Gallio.ReSharperRunner40.plugin b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.0/Gallio.ReSharperRunner40.plugin new file mode 100644 index 00000000..84950981 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.0/Gallio.ReSharperRunner40.plugin @@ -0,0 +1,19 @@ + + + + ReSharper v4.0 Runner + 3.1.0.0 + Enables ReSharper v4.0 to run tests using Gallio. + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v4.1/Gallio.ReSharperRunner41.dll b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.1/Gallio.ReSharperRunner41.dll new file mode 100644 index 00000000..d869568a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.1/Gallio.ReSharperRunner41.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v4.1/Gallio.ReSharperRunner41.plugin b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.1/Gallio.ReSharperRunner41.plugin new file mode 100644 index 00000000..8b211a9a --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.1/Gallio.ReSharperRunner41.plugin @@ -0,0 +1,19 @@ + + + + ReSharper v4.1 Runner + 3.1.0.0 + Enables ReSharper v4.1 to run tests using Gallio. + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v4.5/Gallio.ReSharperRunner45.dll b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.5/Gallio.ReSharperRunner45.dll new file mode 100644 index 00000000..3645ad7a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.5/Gallio.ReSharperRunner45.dll differ diff --git a/lib/Gallio_3.1.397.0/bin/ReSharper/v4.5/Gallio.ReSharperRunner45.plugin b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.5/Gallio.ReSharperRunner45.plugin new file mode 100644 index 00000000..cd8c6530 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/ReSharper/v4.5/Gallio.ReSharperRunner45.plugin @@ -0,0 +1,19 @@ + + + + ReSharper v4.5 Runner + 3.1.0.0 + Enables ReSharper v4.5 to run tests using Gallio. + + + + + + + + + + + \ No newline at end of file diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Assembly.ico b/lib/Gallio_3.1.397.0/bin/Resources/Assembly.ico new file mode 100644 index 00000000..c448dd42 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Assembly.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Container.ico b/lib/Gallio_3.1.397.0/bin/Resources/Container.ico new file mode 100644 index 00000000..3aa2dadc Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Container.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Fixture.ico b/lib/Gallio_3.1.397.0/bin/Resources/Fixture.ico new file mode 100644 index 00000000..85936b34 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Fixture.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Gallio.ControlPanel.ico b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.ControlPanel.ico new file mode 100644 index 00000000..4ed5608a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.ControlPanel.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Copy.ico b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Copy.ico new file mode 100644 index 00000000..4ed5608a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Copy.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Echo.ico b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Echo.ico new file mode 100644 index 00000000..eb3edb9c Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Echo.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Icarus.ico b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Icarus.ico new file mode 100644 index 00000000..4ed5608a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Icarus.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Utility.ico b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Utility.ico new file mode 100644 index 00000000..eb3edb9c Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.Utility.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Gallio.ico b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.ico new file mode 100644 index 00000000..4ed5608a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Gallio.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/MbUnit.ico b/lib/Gallio_3.1.397.0/bin/Resources/MbUnit.ico new file mode 100644 index 00000000..71926959 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/MbUnit.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Test.ico b/lib/Gallio_3.1.397.0/bin/Resources/Test.ico new file mode 100644 index 00000000..2f2a792b Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Test.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/Unsupported.ico b/lib/Gallio_3.1.397.0/bin/Resources/Unsupported.ico new file mode 100644 index 00000000..224dfba0 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/Unsupported.ico differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/css/Gallio-Report.css b/lib/Gallio_3.1.397.0/bin/Resources/css/Gallio-Report.css new file mode 100644 index 00000000..5769d36f --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Resources/css/Gallio-Report.css @@ -0,0 +1,527 @@ +/* Common inherited text options */ +.gallio-report +{ + font-family: Verdana, Arial, Helvetica, Helv, sans-serif; + font-size: 10pt; + word-wrap: break-word; /* IE and CSS3, we use for other browsers */ +} + +/* Containers */ +div.gallio-report, body.gallio-report +{ + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + overflow: hidden; + width: 100%; +} + +.gallio-report div.header +{ + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + background-color: #95b0be; + background-image: url(../img/header-background.gif); + background-repeat: repeat-y; + width: 100%; + height: 59px; + border-bottom: solid 1px black; +} + +.gallio-report div.header-image +{ + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + width: 100%; + height: 60px; + background-image: url(../img/GallioTestReportHeader.png); + background-repeat: no-repeat; + background-position: 0 0; +} + +.gallio-report div.content +{ + width: 100%; +} + +/* Navigation bar */ +.gallio-report div.navigator +{ + position: fixed; + right: 0px; + bottom: 0px; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + width: 17px; + background-color: #d0d4d8; + overflow: hidden; +} + +.gallio-report div.navigator a.navigator-box +{ + display: block; + cursor: pointer; + width: 9px; + height: 9px; + position: absolute; + top: 3px; + left: 3px; + border: solid 1px black; +} + +.gallio-report div.navigator div.navigator-stripes +{ + position: absolute; + top: 17px; + bottom: 0px; + width: 17px; +} + +.gallio-report div.navigator div.navigator-stripes a +{ + display: block; + cursor: pointer; + width: 11px; + height: 2px; + position: absolute; + left: 3px; +} + +/* Generate a fixed layout when the report is the whole document */ +body.gallio-report div.header +{ + position: fixed; + top: 0px; + left: 0px; +} + +body.gallio-report div.content +{ + position: fixed; + top: 60px; + left: 0px; + right: 17px; + bottom: 0px; + overflow: auto; + width: auto; +} + +body.gallio-report div.navigator +{ + top: 60px; +} + +/* Generate an embedded layout when the report is only a fragment */ +div.gallio-report div.header +{ + border: solid 1px black; +} + +div.gallio-report div.navigator +{ + top: 0px; +} + +/* Section headings */ +.gallio-report h2 +{ + font-size: 13pt; + letter-spacing: 0.15em; + color: #1f1f1f; + padding: 0; + margin: 0 0 3px 0; + text-indent: 8px; +} + + +/* Toggle regions */ +.gallio-report ul +{ + list-style-type: none; + padding-left: 0px; + margin: 0px 0px 0px 0px; +} + +.gallio-report div.panel +{ + margin: 0px 0px 0px 24px; +} + +.gallio-report img.toggle +{ + cursor: pointer; + margin-right: 6px; +} + + +/* Status colors */ +.gallio-report .status-passed +{ + background-color: #008000; +} + +.gallio-report .status-failed +{ + background-color: #ff0000; +} + +.gallio-report .status-inconclusive +{ + background-color: #ffff00; +} + +.gallio-report .status-skipped +{ + background-color: #999999; +} + + +/* Outcome bar */ +.gallio-report table.outcome-bar +{ + display: inline; + vertical-align: middle; + margin-left: 8px; +} + +.gallio-report div.outcome-bar +{ + overflow: hidden; + + border: solid 1px #000000; + padding: 0px 0px 0px 0px; + margin: 0px 0px 0px 0px; + + height: 8px; + width: 72px; +} + +.gallio-report div.outcome-bar.condensed +{ + height: 6px; + width: 20px; +} + + +/* Outcome statistics */ +.gallio-report span.outcome-icons +{ + font-size: 11pt; +} + + +/* Test Kind Icons (Note: Additional kinds in separate automatically generated css file.) */ + +.gallio-report .testKind +{ + display: inline-block; + margin: 0px 6px 0px 0px; + padding: 0px 0px 0px 0px; + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: center center; + background-image: url(../img/UnknownTestKind.png); +} + +/* Test runs */ +.gallio-report .testStepRun +{ + margin-top: 12pt; + font-size: 10pt; +} + +.gallio-report .testStepRunHeading +{ + font-weight: bold; + font-size: 10pt; +} + +.gallio-report .testStepRunHeading-Level1 +{ + font-size: 12pt; +} + +.gallio-report .testStepRunHeading-Level2 +{ + font-size: 11pt; +} + +.gallio-report .testStepRunHeading-Level3 +{ + font-size: 10pt; +} + + +/* Metadata entries */ +.gallio-report .metadata +{ + margin: 5px 5px 5px 0px; + padding: 5px 5px 5px 5px; + + background: #f4f4ff; + font-size: 9pt; +} + +/* Test logs */ +.gallio-report .log +{ + margin: 5px 0px 5px 0px; +} + +.gallio-report .logAttachmentList +{ + font-size: 10pt; + font-style: italic; +} + +.gallio-report .logStream +{ + background-color: #f0f0f0; + border-bottom: solid 1px #c6c6c6; + border-right: solid 1px #c6c6c6; + margin: 5px 5px 5px 0px; + padding: 5px 5px 5px 5px; +} + +.gallio-report .logStreamHeading +{ + font-weight:bold; + font-size: 10pt; + text-decoration: underline; +} + +.gallio-report .logStreamBody +{ + font-size: 9pt; + border-style: none; +} + +.gallio-report .logStreamSection +{ + margin-top: 12pt; + margin-bottom: 12pt; + padding-left: 6px; + border-left: solid 3px black; +} + +.gallio-report .logStreamSectionHeading +{ + font-weight: bold; + text-decoration: underline; +} + +.gallio-report .logStreamEmbed +{ + font-style: italic; + padding: 5px 10px 5px 10px; +} + +.gallio-report .logHiddenData +{ + display: none; +} + +/* Test log streams */ +.gallio-report .logStream-Failures +{ + background-color: #ffd8d8; + border: dotted 1px #905050; +} + +.gallio-report .logStream-Warnings +{ + background-color: #ffffc8; + border: dotted 1px #909050; +} + +/* Test log stream markers */ +.gallio-report .logStreamMarker-AssertionFailure +{ +} + +.gallio-report .logStreamMarker-Label +{ + font-weight: bold; +} + +.gallio-report .logStreamMarker-Exception +{ + font-style: italic; +} + +.gallio-report .logStreamMarker-StackTrace +{ + font-style: italic; +} + +.gallio-report .logStreamMarker-Monospace +{ + font-family: Consolas, Courier New, Courier; +} + +.gallio-report .logStreamMarker-Highlight +{ + background-color: Yellow; +} + +.gallio-report .logStreamMarker-DiffAddition +{ + background-color: #b0ffb0; +} + +.gallio-report .logStreamMarker-DiffDeletion +{ + background-color: #ffb0b0; + text-decoration: line-through; +} + +.gallio-report .logStreamMarker-DiffChange +{ + background-color: #b0b0ff; +} + +.gallio-report .logStreamMarker-Ellipsis +{ + text-decoration: underline; +} + +.gallio-report .embeddedImage +{ + max-width: 800px; +} + +.gallio-report .attachmentLink +{ +} + +/* Sections */ +.gallio-report div.section +{ + background-color: #ebeaea; + margin: 5px; + padding: 10px; + border-bottom: solid 1px #dcdcdc; + border-right: solid 1px #dcdcdc; + overflow: hidden; +} + +.gallio-report div.section-content +{ + background-color: #fbfbfb; + padding: 10px 10px 10px 10px; + overflow: hidden; +} + +.gallio-report table.statistics-table +{ + border-collapse: collapse; +} + +.gallio-report table.statistics-table td +{ + width: 100%; +} + +.gallio-report table.statistics-table td.statistics-label-cell +{ + font-weight: bolder; + color: #646464; + padding: 0px 10px 0px 10px; + width: auto; +} + +.gallio-report table.statistics-table tr.alternate-row td +{ + background-color: #f2f2f2; +} + + +/* Annotations */ +.gallio-report div.annotation +{ +} + +.gallio-report div.annotation-message +{ + margin-left: 2em; + text-indent: -2em; +} + +.gallio-report div.annotation-location, div.annotation-reference, div.annotation-details +{ + margin-left: 4em; + text-indent: -2em; + font-style: italic; +} + +.gallio-report .annotation-type-error +{ + color: #990000; +} + +.gallio-report .annotation-type-warning +{ + color: #999900; +} + +.gallio-report .annotation-type-info +{ + color: #999999; +} + +/* Log Entries */ +.gallio-report div.logEntry +{ +} + +.gallio-report div.logEntry-text +{ + margin-left: 2em; + text-indent: -2em; +} + +.gallio-report div.logEntry-details +{ + margin-left: 4em; + text-indent: -2em; + font-style: italic; +} + +.gallio-report .logEntry-severity-error +{ + color: #990000; +} + +.gallio-report .logEntry-severity-warning +{ + color: #999900; +} + +.gallio-report .logEntry-severity-important +{ + color: #000000; +} + +.gallio-report .logEntry-severity-info +{ + color: #999999; +} + +.gallio-report .logEntry-severity-debug +{ + color: #aaaaaa; +} + +/* Cross-References */ + +.gallio-report a:hover.crossref +{ + background-color: #eeee99; +} + +.gallio-report a.crossref +{ + color: #000000; + text-decoration: none; + border-bottom: dotted 1px #aa00dd; +} diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/Failed.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/Failed.gif new file mode 100644 index 00000000..bcf4c078 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/Failed.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/FullStop.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/FullStop.gif new file mode 100644 index 00000000..dda8c62b Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/FullStop.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/GallioTestReportHeader.png b/lib/Gallio_3.1.397.0/bin/Resources/img/GallioTestReportHeader.png new file mode 100644 index 00000000..111cca6f Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/GallioTestReportHeader.png differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/Ignored.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/Ignored.gif new file mode 100644 index 00000000..dd90f466 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/Ignored.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/Minus.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/Minus.gif new file mode 100644 index 00000000..46acbcc7 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/Minus.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/Passed.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/Passed.gif new file mode 100644 index 00000000..1dee9cd8 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/Passed.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/Plus.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/Plus.gif new file mode 100644 index 00000000..0ce509a8 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/Plus.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/UnknownTestKind.png b/lib/Gallio_3.1.397.0/bin/Resources/img/UnknownTestKind.png new file mode 100644 index 00000000..9f91b64a Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/UnknownTestKind.png differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/img/header-background.gif b/lib/Gallio_3.1.397.0/bin/Resources/img/header-background.gif new file mode 100644 index 00000000..0e01c4c0 Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/img/header-background.gif differ diff --git a/lib/Gallio_3.1.397.0/bin/Resources/js/Gallio-Report.js b/lib/Gallio_3.1.397.0/bin/Resources/js/Gallio-Report.js new file mode 100644 index 00000000..5ed30971 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Resources/js/Gallio-Report.js @@ -0,0 +1,244 @@ +function reportLoaded() +{ + fixAttachmentLinksOnIE(); +} + +function fixAttachmentLinksOnIE() +{ + if (needFixupForIE()) + { + // On IE, pages in the local filesystem that possess the Mark of the Web + // are forbidden from navigating to other local files. This breaks links + // to attachments on the local filesystem unless we make some changes. + var count = document.links.length; + for (var i = 0; i < count; i++) + { + var link = document.links[i]; + var href = link.href; + if (link.className == "attachmentLink" && isLocalFileUri(href)) + { + link.href = toGallioAttachmentUri(href); + } + } + } +} + +function toGallioAttachmentUri(uri) +{ + var path = uri.substring(8).replace(/\//g, "\\"); + return "gallio:openAttachment?path=" + path; +} + +var needFixupForIECache = undefined; +function needFixupForIE() +{ + if (needFixupForIECache == undefined) + needFixupForIECache = isIE() && (isLocalFileUri(window.location.href) || isInMemoryUri(window.location.href)); + + return needFixupForIECache; +} + +function isIE() +{ + return navigator.appName == "Microsoft Internet Explorer"; +} + +function isLocalFileUri(uri) +{ + return uri.search(/^file:\/\/\//) == 0; +} + +function isInMemoryUri(uri) +{ + return uri == "about:blank"; +} + +function toggle(id) +{ + var icon = document.getElementById('toggle-' + id); + if (icon != null) + { + var childElement = document.getElementById(id); + if (icon.src.indexOf('Plus.gif') != -1) + { + icon.src = icon.src.replace('Plus.gif', 'Minus.gif'); + if (childElement != null) + childElement.style.display = "block"; + } + else + { + icon.src = icon.src.replace('Minus.gif', 'Plus.gif'); + if (childElement != null) + childElement.style.display = "none"; + } + } +} + +function expand(ids) +{ + for (var i = 0; i < ids.length; i++) + { + var id = ids[i]; + var icon = document.getElementById('toggle-' + id); + if (icon != null) + { + if (icon.src.indexOf('Plus.gif') != -1) + { + icon.src = icon.src.replace('Plus.gif', 'Minus.gif'); + + var childElement = document.getElementById(id); + if (childElement != null) + childElement.style.display = "block"; + } + } + } +} + +function navigateTo(path, line, column) +{ + var navigator = new ActiveXObject("Gallio.Navigator.GallioNavigator"); + if (navigator) + navigator.NavigateTo(path, line, column); +} + +function setInnerHTMLFromUri(id, uri) +{ + _asyncLoadContentFromUri(uri, function(loadedDocument) + { + // workaround for IE failure to auto-detect HTML content + var children = isIE() ? loadedDocument.body.children : null; + if (children && children.length == 1 && children[0].tagName == "PRE") + { + var text = getTextContent(loadedDocument.body); + setInnerHTMLFromContent(id, text); + } + else + { + var html = loadedDocument.body.innerHTML; + setInnerHTMLFromContent(id, html); + } + }); +} + +function setPreformattedTextFromUri(id, uri) +{ + _asyncLoadContentFromUri(uri, function(loadedDocument) { setPreformattedTextFromContent(id, getTextContent(loadedDocument.body)); }); +} + +function setInnerHTMLFromHiddenData(id) +{ + var element = document.getElementById(id + '-hidden'); + if (element) + setInnerHTMLFromContent(id, getTextContent(element)); +} + +function setPreformattedTextFromHiddenData(id) +{ + var element = document.getElementById(id + '-hidden'); + if (element) + setPreformattedTextFromContent(id, getTextContent(element)); +} + +function setInnerHTMLFromContent(id, content) +{ + if (content != undefined) + { + var element = document.getElementById(id); + if (element) + element.innerHTML = content; + } +} + +function setPreformattedTextFromContent(id, content) +{ + if (content != undefined) + { + var element = document.getElementById(id); + if (element) + { + element.innerHTML = "
    ";
    +            setTextContent(element.children[0], content);
    +        }
    +    }
    +}
    +
    +function getTextContent(element)
    +{
    +    return element.textContent != undefined ? element.textContent : element.innerText;
    +}
    +
    +function setTextContent(element, content)
    +{
    +    if (element.textContent != undefined)
    +        element.textContent = content;
    +    else
    +        element.innerText = content;
    +}
    +
    +function setFrameLocation(frame, uri)
    +{
    +    if (frame.contentWindow)
    +        frame.contentWindow.location.replace(uri);
    +}
    +
    +function _asyncLoadContentFromUri(uri, callback)
    +{
    +    var asyncLoadFrame = document.getElementById('_asyncLoadFrame');
    +
    +    if (!asyncLoadFrame.pendingRequests)
    +        asyncLoadFrame.pendingRequests = [];
    +
    +    asyncLoadFrame.pendingRequests.push({ uri: uri, callback: callback });
    +
    +    _asyncLoadFrameNext(asyncLoadFrame);
    +}
    +
    +function _asyncLoadFrameOnLoad()
    +{
    +    var asyncLoadFrame = document.getElementById('_asyncLoadFrame');
    +    if (asyncLoadFrame)
    +    {
    +        var request = asyncLoadFrame.currentRequest;
    +        if (request)
    +        {
    +            asyncLoadFrame.currentRequest = undefined;
    +
    +            try
    +            {
    +                var loadedWindow = asyncLoadFrame.contentWindow;
    +                if (loadedWindow && loadedWindow.location.href != "about:blank")
    +                {
    +                    var loadedDocument = loadedWindow.document;
    +                    if (loadedDocument)
    +                    {
    +                        request.callback(loadedDocument);
    +                    }
    +                }
    +            }
    +            catch (ex)
    +            {
    +                //alert(ex.message);
    +            }
    +        }
    +
    +        _asyncLoadFrameNext(asyncLoadFrame);
    +    }
    +}
    +
    +function _asyncLoadFrameNext(asyncLoadFrame)
    +{
    +    while (!asyncLoadFrame.currentRequest && asyncLoadFrame.pendingRequests && asyncLoadFrame.pendingRequests.length > 0)
    +    {
    +        var request = asyncLoadFrame.pendingRequests.shift();
    +        asyncLoadFrame.currentRequest = request;
    +
    +        try
    +        {
    +            setFrameLocation(asyncLoadFrame, request.uri);
    +        }
    +        catch (ex)
    +        {
    +            //alert(ex.message);
    +        }
    +    }
    +}
    diff --git a/lib/Gallio_3.1.397.0/bin/Resources/js/expressInstall.swf b/lib/Gallio_3.1.397.0/bin/Resources/js/expressInstall.swf
    new file mode 100644
    index 00000000..0fbf8fca
    Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/js/expressInstall.swf differ
    diff --git a/lib/Gallio_3.1.397.0/bin/Resources/js/player.swf b/lib/Gallio_3.1.397.0/bin/Resources/js/player.swf
    new file mode 100644
    index 00000000..ec848da1
    Binary files /dev/null and b/lib/Gallio_3.1.397.0/bin/Resources/js/player.swf differ
    diff --git a/lib/Gallio_3.1.397.0/bin/Resources/js/swfobject.js b/lib/Gallio_3.1.397.0/bin/Resources/js/swfobject.js
    new file mode 100644
    index 00000000..8eafe9dd
    --- /dev/null
    +++ b/lib/Gallio_3.1.397.0/bin/Resources/js/swfobject.js
    @@ -0,0 +1,4 @@
    +/*	SWFObject v2.2  
    +	is released under the MIT License  
    +*/
    +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab
    +
    +  
    +  
    +
    +  /gallio/css/
    +  /gallio/js/
    +  /gallio/img/
    +  GallioAttachment.aspx?
    +  
    +
    +  
    +    
    +  
    +  
    +  
    +    
    +
    diff --git a/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.ccnet-details.xsl b/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.ccnet-details.xsl
    new file mode 100644
    index 00000000..0a6baf36
    --- /dev/null
    +++ b/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.ccnet-details.xsl
    @@ -0,0 +1,20 @@
    +
    +
    +  
    +  
    +
    +  /gallio/css/
    +  /gallio/js/
    +  /gallio/img/
    +  GallioAttachment.aspx?
    +  
    +
    +  
    +    
    +  
    +  
    +  
    +    
    +
    diff --git a/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.common.xsl b/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.common.xsl
    new file mode 100644
    index 00000000..49c9f537
    --- /dev/null
    +++ b/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.common.xsl
    @@ -0,0 +1,356 @@
    +
    +
    +  
    +  
    +  
    +  
    +    
    +       
    +		    
    +     run, 
    +    
    +    
    +     passed
    +    
    +      
    +      passed
    +    
    +    , 
    +    
    +    
    +     failed
    +    
    +      
    +      failed
    +    
    +    , 
    +
    +    
    +     inconclusive
    +    
    +      
    +      inconclusive
    +    
    +    , 
    +    
    +    
    +     skipped
    +    
    +      
    +      skipped
    +    
    +  
    +  
    +  
    +    
    +    
    +    
    +    
    +    
    +    
    +       (
    +        
    +          
    +          
    +          , 
    +          
    +           
    +          
    +        
    +      )
    +    
    +  
    +  
    +  
    +  
    +    
    +    
    +    
    +      
    +        
    +        
    +          (
    +          
    +          
    +            ,
    +            
    +          
    +          )
    +        
    +      
    +      
    +        (unknown)
    +      
    +    
    +  
    +
    +  
    +  
    +    
    +    
    +    
    +      Parameter 
    +      
    +       of 
    +    
    +    
    +    
    +      
    +        
    +        
    +          .
    +          
    +        
    +      
    +      
    +        
    +      
    +    
    +    
    +    
    +      
    +        , 
    +      
    +      
    +    
    +  
    +  
    +  
    +  
    +    
    +
    +    
    +    
    +    
    +    
    +    
    +    
    +    
    +    
    +    
    +    
    +    
    +    
    +
    +    
    +      
    +      
    +      
    +      
    +      
    +      
    +      
    +      
    +      
    +      
    +      
    +        
    +          skipped
    +          
    +        
    +        
    +          passed
    +          
    +        
    +        
    +          inconclusive
    +          
    +        
    +        
    +          failed
    +          
    +        
    +      
    +    
    +  
    +  
    +  
    +  
    +    
    +    
    +    
    +    
    +      
    +      
    +        
    +      
    +    
    +  
    +  
    +  
    +  
    +    
    +    
    +    
    +    
    +
    +    
    +      
    +        
    +        
    +        
    +        
    +      
    +    
    +  
    +
    +  
    +    
    +    
    +    
    +    
    +
    +    
    +      
    +        
    +        
    +        
    
    +        
    +          
    +          
    +          
    +          
    +        
    +      
    +      
    +      
    +        
    +        
    +        
    +          
    
    +        
    +      
    +    
    +  
    +
    +  
    +  
    +    
    +    
    +    
    +    
    +      
    +      
    +      
    +        
    +        
    +          
    +           
    +          
    +          
    +            
    +            
    +          
    +        
    +
    +        
    +        
    +          
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + / + %20 + %25 + + + + + + + +
    diff --git a/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.html+xhtml.xsl b/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.html+xhtml.xsl new file mode 100644 index 00000000..d15c7fa6 --- /dev/null +++ b/lib/Gallio_3.1.397.0/bin/Resources/xsl/Gallio-Report.html+xhtml.xsl @@ -0,0 +1,1060 @@ + + + + + + + + saved from url=(0014)about:internet + + + Gallio Test Report + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + +
    +